注意事项:
1.单向一对多
只需在“一”放进行配置
2.双向一对多
需要在关联双方都加以配置,而且需要在一的一方设置inverse=true
首先是实体类:
TAddress.java(多的一方)
public
class
TAddress
implements
Serializable {
private
static
final
long
serialVersionUID = 1121137857691229229L;
private
Integer id;
private
String address;
private
String zipcode;
private
String tel;
private
String type;
private
TUser user;
//必须有
............
}
|
TUser.java(一的一方)
public
class
TUser
implements
Serializable {
private
static
final
long
serialVersionUID = 1224691192698621789L;
private
Integer id;
private
Integer age;
private
String name;
@SuppressWarnings
(
"rawtypes"
)
private
Set address =
new
HashSet();
//多的一方放在集合中
|
....................
}
|
然后是各个实体类的配置文件
TAddress.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <!-- 一对多 --> <hibernate-mapping> <class name="com.model.TAddress" table="t_address" dynamic-update="false" dynamic-insert="false"> <id name="id" type="java.lang.Integer" column="id" unsaved-value="0"> <generator class="native" /> </id> <property name="address" column="address" type="string" /> <property name="tel" column="tel" type="string" /> <property name="zipcode" column="zipcode" type="string" /> <property name="type" column="type" type="string" /> <!-- 必须有many-to-one 否则关联字段(user_id)为null --> <many-to-one name="user" class="com.model.TUser" cascade="none" outer-join="auto" update="true" insert="true" access="property" column="user_id" not-null="true"> </many-to-one> </class> </hibernate-mapping>
TUser.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <!-- 一对多 外键关联 --> <!-- Select from TUser where id=1 Select from TUser where id=1 to Select from TUser where id=1 or id=2 --> <!-- batch-size 批量加载机制 可以自定义每次批量加载的数量 --> <hibernate-mapping> <class name="com.model.TUser" table="t_user" dynamic-update="true" > <id name="id" type="java.lang.Integer" column="id" unsaved-value="0"> <generator class="native" /> </id> <property name="name" column="name" /> <property name="age" column="age" /> <set name="address" table="t_address" cascade="all" order-by="zipcode asc" lazy="true" inverse="true"> <key column="user_id" /><!-- 确定关联的外键列 --> <one-to-many class="com.model.TAddress" /> </set> </class> </hibernate-mapping>
其次是hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> <hibernate-configuration> <session-factory> <!-- properties --> <!-- 数据库URL --> <property name="hibernate.connection.url">jdbc:mysql://localhost/onetomany</property> <!-- 数据库JDBC驱动 --> <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property> <!-- 数据库用户名 --> <property name="hibernate.connection.username">root</property> <!-- 数据库密码 --> <property name="hibernate.connection.password">hello</property> <!-- 数据库方言 --> <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property> <!-- 是否日志调试 --> <property name="show_sql">true</property> <!-- 是否使用数据库外连接 --> <property name="use_outer_join">true</property> <!-- 事务管理 使用JDBC Transaction(使用JTA会报错) --> <property name="transaction.factory_class"> net.sf.hibernate.transaction.JDBCTransactionFactory </property> <!-- 指定hibernate每次提交的SQL数量 对批量操作的性能提升帮助很大!!!!!!!!!!!!! --> <property name="hibernate.jdbc.batch_size">25</property> <!-- 映射文件配置,配置文件名必须包含其相对于根的全路径 --> <mapping resource="com/model/TUser.hbm.xml" /> <mapping resource="com/model/TAddress.hbm.xml" /> </session-factory> </hibernate-configuration>
测试代码(部分)
增加
public
void
testSave(){
try
{
Transaction tx=session.beginTransaction();
// TUser user=(TUser) session.load(TUser.class, 1);
TUser user=
new
TUser();
user.setName(
"zhangsan"
);
user.setAge(
20
);
TAddress address=
new
TAddress();
address.setAddress(
"jingsan"
);
address.setTel(
"1361380"
);
address.setZipcode(
"45000"
);
address.setType(
"java"
);
address.setUser(user);
//设置关联的TUser对象
user.getAddress().add(address);
session.save(user);
//级联更新
tx.commit();
}
catch
(HibernateException e) {
e.printStackTrace();
}
}
|
查询
public
void
testLoad(){
try
{
Transaction tx=session.beginTransaction();
String hql=
"from TUser where name='zhangsan'"
;
List list=session.createQuery(hql).list();
System.out.println(
"-------------1------------"
);
Iterator iter=list.iterator();
while
(iter.hasNext()){
TUser user=(TUser) iter.next();
System.out.println(
"--------------2------------"
);
System.out.println(
"user.name="
+user.getName());
System.out.println(
"--------------3------------"
);
System.out.println(
"user.address="
+user.getAddress().size());
System.out.println(
"--------------4------------"
);
}
}
catch
(HibernateException e) {
e.printStackTrace();
}
}
|
批量插入(可以提高性能)
实现机制:如果使用了批量加载机制,hibernate在进行数据查询操作前,会自动在当前session中寻找是否还存在
其他同类型待加载的数据,如果有,则将其查询条件合并在当前的select语句中一并提交,这样,通过
一次数据库操作即完成了多个读取任务。
//批量插入操作性能优化 通过配置<property name="hibernate.jdbc.batch_size">25</property>
public
void
testBatchInsert(){
long
start=System.currentTimeMillis();
this
.importUserList();
long
end=System.currentTimeMillis();
System.out.println(
"批量插入花费时间是"
+(end-start));
}
public
void
importUserList(){
try
{
Transaction tx=session.beginTransaction();
for
(
int
i=
0
;i<
10000
;i++){
TUser user=
new
TUser();
user.setName(
"user"
+i);
session.save(user);
if
(i%
25
==
0
){
//以每25个数据作为一个处理单元
session.flush();
session.clear();
}
}
tx.commit();
}
catch
(HibernateException e) {
e.printStackTrace();
}
}
原文出处:http://www.cnblogs.com/wangchenyang/archive/2011/08/23/2150323.html
|