此方法在快速建立项目原型上有很大帮助(这最关键的就是速度,用的好原型很快就能建立起来)
先确定下“快速原型”环境定义:
使用:ant+hibernate_xdoclet+hibernate_create_table
过程:定义bean(xdoclet) -> hbm映射文件 -> hibernate.hbm2ddl.auto create -> 逻辑
注意:如有使用泛型,请使用 > xjavadoc-1.1.jar
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<property file="build-dist.properties" />
<path id="class.path">
<fileset dir="${ant.lib.dir}">
<include name="*.jar" />
</fileset>
<fileset dir="${project.lib.dir}">
<include name="*.jar" />
</fileset>
</path>
<!-- =================================================================== -->
<!-- Initialise -->
<!-- =================================================================== -->
<target name="init">
<taskdef name="hibernatedoclet" classname="xdoclet.modules.hibernate.HibernateDocletTask" classpathref="class.path" />
</target>
<!-- =================================================================== -->
<!-- Invoke XDoclet's hibernate -->
<!-- =================================================================== -->
<target name="hibernate" depends="init">
<echo>+---------------------------------------------------+</echo>
<echo>| |</echo>
<echo>| R U N N I N G H I B E R N A T E D O C L E T |</echo>
<echo>| |</echo>
<echo>+---------------------------------------------------+</echo>
<hibernatedoclet destdir="${config.dir}" mergedir="${config.dir}" excludedtags="@version,@author,@todo,@see" addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author XDoclet,@version ${version}" force="${samples.xdoclet.force}" verbose="false">
<fileset dir="${src.dir}">
<include name="bean/**/*.java" />
</fileset>
<hibernate version="3.0" />
</hibernatedoclet>
</target>
</project>
ant配置文件
# 当然根据你自己的项目路径
ant.lib.dir = C:\\src\\test\\hbmTest\\action\\lib
project.lib.dir= C:\\src\\test\\hbmTest\\lib
src.dir = C:\\src\\test\\hbmTest\\src
config.dir = C:\\src\\test\\hbmTest\\config
hibernate.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.url">
<![CDATA[
jdbc:mysql://localhost:3306/hbm?characterEncoding=utf8&connectionCollation=gbk_chinese_ci
]]>
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.password">******</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.show_sql">true</property>
<!-- 映射添加 -->
<mapping resource="bean\unidirectional\m2o\Person.hbm.xml"/>
<mapping resource="bean\unidirectional\m2o\Address.hbm.xml"/>
</session-factory>
</hibernate-configuration>
下面就详细介绍了第一个
单项一对多
1.先定义bean
package bean.unidirectional.m2o;
/**
* @hibernate.class
*/
public class Person {
private int id;
private Address address;
/**
* @hibernate.id generator-class = "native"
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/**
* @hibernate.many-to-one column = "addressId" not-null = "true"
*/
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
package bean.unidirectional.m2o;
/**
* @hibernate.class
*/
public class Address {
private int id;
/**
* @hibernate.id generator-class = "native"
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
2.运行 ant hibernate 得到 hbm 映射文件
3.Main 运行测试
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateUtil;
import bean.unidirectional.m2o.Address;
import bean.unidirectional.m2o.Person;
public class Main {
public static void main(String[] args) {
Session session1 = HibernateUtil.currentSession();
Transaction t1 = session1.beginTransaction();
//insert
Address address1 = new Address();
Address address2 = new Address();
Person person1 = new Person();
Person person2 = new Person();
person1.setAddress(address1);
person2.setAddress(address1);
Person person3 = new Person();
person3.setAddress(address2);
session1.save(address1);
session1.save(address2);
session1.save(person1);
session1.save(person2);
session1.save(person3);
t1.commit();
//查询有重复的 address
Session session2 = HibernateUtil.currentSession();
Query query = session2.createQuery(
" select ta from "+
Address.class.getName()+" ta , "+
Person.class.getName()+" tp "+
" where ta.id=tp.address "+
" group by ta.id having count(ta.id)>1 "
);
List<Address> list = query.list();
for(Address atmp : list ){
System.out.println( atmp.getId() );
}
}
}
数据库:
mysql> show tables ;
+-----------------------+
| Tables_in_hbm |
+-----------------------+
| address |
| person |
+-----------------------+
结果:
Hibernate: insert into Address values ( )
Hibernate: insert into Address values ( )
Hibernate: insert into Person (addressId) values (?)
Hibernate: insert into Person (addressId) values (?)
Hibernate: insert into Person (addressId) values (?)
Hibernate: select address0_.id as id from Address address0_, Person person1_ where address0_.id=person1_.addressId group by address0_.id having count(address0_.id)>1
1
当然我这文章主要是映射关系,下面我们就进主题,大家想尝试下可以使用上面的原型快速测试:
参考(在此我对参考加入了自己的注解,希望能给大家帮助。对于在实际开发中不常见或难以实现的我们就不介绍了)
单向一对一(one to one)
#通过外键关联
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
#通过主键关联(请注意,例子中掉换了关联的方向)
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
单向一对多(one to many)
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses">
<key column="personId" not-null="true"/>
<one-to-many class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null
# 这里 当 ddl主键对象 会多出 n条 被外键对象的 update
# 解决办法修改映射为双向,并且set-inverse= "false"并且 在代码中‘孩子.set父亲()’和 ‘父亲.add孩子()’一定要写明
# 如果不希望硬代码 就 set-inverse="true" ‘父亲.add孩子()’在生成sql 中就会有多余的update
# 当然根据逻辑情况来选择
/**
* @hibernate.class
*
*/
public class Person {
private int id;
private Set<Address> addresss;
/**
* @hibernate.id
* generator-class = "native"
* @return
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/**
* @hibernate.set inverse = "false"
* @hibernate.collection-key column ="personId"
* @hibernate.collection-one-to-many class = "bean.unidirectional.m2o.Address"
*/
public Set<Address> getAddresss() {
return addresss;
}
public void setAddresss(Set<Address> addresss) {
this.addresss = addresss;
}
}
/**
* @hibernate.class
* @author root
*
*/
public class Address {
private int id;
private Person person ;
/**
* @hibernate.id generator-class = "native"
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/**
* @hibernate.many-to-one
* column = "personId"
* @return
*/
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
public static void main(String[] args) {
Session session1 = HibernateUtil.currentSession();
Transaction t1 = session1.beginTransaction();
//insert
Address address1 = new Address();
Address address2 = new Address();
Set<Address> addresss = new HashSet<Address>();
addresss.add(address1);
addresss.add(address2);
Person person1 = new Person();
person1.setAddresss(addresss);
address1.setPerson(person1);
address2.setPerson(person1);
session1.save(person1);
session1.save(address1);
session1.save(address2);
t1.commit();
//查询有重复的 address
Session session2 = HibernateUtil.currentSession();
Query query = session2.createQuery(
" from "+Person.class.getName()+" tp "
);
List<Person> list = query.list();
for(Person ptmp : list ){
for( Address atmp : ptmp.getAddresss() ){
System.out.println(atmp.getId());
}
}
结果:
干净的 insert
Hibernate: insert into Person values ( )
Hibernate: insert into Address values ( )
Hibernate: insert into Address values ( )
Hibernate: select person0_.id as id from Person person0_
1
2
mysql :
mysql> select * from address ;
+----+----------+
| id | personId |
+----+----------+
| 1 | 1 |
| 2 | 1 |
+----+----------+
2 rows in set (0.00 sec)
整理 www.blogjava.net/Good-Game