1、项目结构:
1.1、场景说明: 一个订单,包含多个产品
1.2、类文件:
Order.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package
com.rhythmk.model;
import java.util.Date;
public class Order {
public
int getOrderID() {
return
orderID;
}
public
void setOrderID( int
orderID) {
this .orderID = orderID;
}
public
String getName() {
return
Name;
}
public
void setName(String name) {
Name = name;
}
public
double getSumMoney() {
return
SumMoney;
}
public
void setSumMoney( double
sumMoney) {
SumMoney = sumMoney;
}
public
Date getCreateDate() {
return
createDate;
}
public
void setCreateDate(Date createDate) {
this .createDate = createDate;
}
private
int orderID;
private
String Name;
private
double SumMoney;
@Override
public
String toString() {
return
"Order [orderID=" + orderID + ", Name="
+ Name + ", SumMoney="
+ SumMoney + ", createDate="
+ createDate + "]" ;
}
private
Date createDate;
} |
order.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.rhythmk.model.Order" table="t_order"> <id name="orderID" type="int"> <column name="orderID" /> <generator class="native" /> </id> <property name="Name" type="string"> <column name="Name" not-null="true" /> </property> <property name="SumMoney" type="double"></property> <property name="createDate" type="timestamp"> <column name="createDate" not-null="true" /> </property> </class> </hibernate-mapping>
Product.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package
com.rhythmk.model;
public class Product {
public
int getProductID() {
return
productID;
}
public
void setProductID( int
productID) {
this .productID = productID;
}
public
String getProductName() {
return
productName;
}
public
void setProductName(String productName) {
this .productName = productName;
}
private
int productID;
private
String productName;
public
Order getOrder() {
return
order;
}
public
void setOrder(Order order) {
this .order = order;
}
private
Order order ;
@Override
public
String toString() {
return
"Product [productID=" + productID + ", productName="
+ productName + ", order="
+ order + "]" ;
}
} |
product.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.rhythmk.model.Product" table="t_product"> <id name="productID" type="int"> <column name="productID" /> <generator class="native" /> </id> <property name="productName" type="string"> <column name="productName" /> </property> <many-to-one name="order" column="orderID"></many-to-one> </class> </hibernate-mapping>
hibernate.cfg.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"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_demo</property> <property name="connection.username">root</property> <property name="connection.password">wangkun</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property> <!--是否在后台显示Hibernate用到的SQL语句,开发时设置为true,便于差错,程序运行时可以在Eclipse的控制台显示Hibernate的执行Sql语句。项目部署后可以设置为false,提高运行效率 --> <property name="hibernate.show_sql">true </property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="com/rhythmk/model/user.hbm.xml" /> <mapping resource="com/rhythmk/model/product.hbm.xml" /> <mapping resource="com/rhythmk/model/order.hbm.xml" /> </session-factory> </hibernate-configuration>
1.3 、结论:
在Many方 定义XML配置 :
<many-to-one name="order" column="orderID"></many-to-one>
写入数据调用session.save方法跟单表保存基本一致。
读取数据:获取Many对象,默认 One对象都是以延迟加载模式进行加载。
不论是删除 Many ,还是删除 One 对象 都只删除本身数据 ,并非删除全部主从数据,如果删除One对象,一旦Many还有关联One的对象的存在,则将抛出异常。见(test04_del)
1.4 、测试验证:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@Test public
void test02_add() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Order order = new
Order();
order.setCreateDate( new
Date());
order.setName( "订单一" );
order.setSumMoney( 12 );
session.save(order);
Product p1 = new
Product();
p1.setOrder(order);
p1.setProductName( "产品1" );
session.save(p1);
Product p2 = new
Product();
p2.setOrder(order);
p2.setProductName( "产品2" );
session.save(p2);
session.getTransaction().commit();
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
}
|
输出:
Hibernate: insert into t_order (Name, SumMoney, createDate) values (?, ?,
?)
Hibernate: insert into t_product (productName, orderID) values (?,
?)
Hibernate: insert into t_product (productName, orderID) values (?, ?)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Test public void test03_load() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
Order order = (Order) session.load(Order. class , 1 );
System.out.println(order);
System.out.println( "-----------Read Product-----------" );
Product product = (Product) session.load(Product. class , 1 );
System.out.println( "-----------Print Product-----------" );
System.out.println(product);
System.out.println( "-----------Read Order-----------" );
System.out.println(product.getOrder().getName());
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
} |
输出:
Hibernate: select order0_.orderID as orderID1_0_0_, order0_.Name as
Name2_0_0_, order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as
createDa4_0_0_ from t_order order0_ where order0_.orderID=?
Order [orderID=1,
Name=订单一, SumMoney=12.0, createDate=2014-05-02 15:24:02.0]
-----------Read
Product-----------
-----------Print Product-----------
Hibernate: select
product0_.productID as productI1_1_0_, product0_.productName as productN2_1_0_,
product0_.orderID as orderID3_1_0_ from t_product product0_ where
product0_.productID=?
Product [productID=1, productName=产品1, order=Order
[orderID=1, Name=订单一, SumMoney=12.0, createDate=2014-05-02
15:24:02.0]]
-----------Read Order-----------
订单一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Test public void test04_Get() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
System.out.println( "-----------Read Product-----------" );
Product product = (Product) session.get(Product. class , 1 );
System.out.println( "-----------Print Product-----------" );
System.out.println(product);
System.out.println( "-----------Read Order-----------" );
System.out.println(product.getOrder().getName());
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
} |
输出:
-----------Read Product-----------
Hibernate: select product0_.productID
as productI1_1_0_, product0_.productName as productN2_1_0_, product0_.orderID as
orderID3_1_0_ from t_product product0_ where
product0_.productID=?
-----------Print Product-----------
Hibernate:
select order0_.orderID as orderID1_0_0_, order0_.Name as Name2_0_0_,
order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as createDa4_0_0_ from
t_order order0_ where order0_.orderID=?
Product [productID=1,
productName=产品1, order=Order [orderID=1, Name=订单一, SumMoney=12.0,
createDate=2014-05-02 15:24:02.0]]
-----------Read
Order-----------
订单一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@Test public void test04_Del() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
/*
Product product = (Product) session.get(Product.class, 1);
session.delete(product);
输出:
Hibernate: select product0_.productID as productI1_1_0_, product0_.productName as productN2_1_0_, product0_.orderID as orderID3_1_0_ from t_product product0_ where product0_.productID=?
Hibernate: delete from t_product where productID=?
*/ Order order = (Order) session.get(Order. class , 3 );
session.delete(order);
session.getTransaction().commit();
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
} |
输出:
Hibernate: select order0_.orderID as orderID1_0_0_, order0_.Name as
Name2_0_0_, order0_.SumMoney as SumMoney3_0_0_, order0_.createDate as
createDa4_0_0_ from t_order order0_ where order0_.orderID=?
Hibernate: delete
from t_order where orderID=?
org.hibernate.exception.ConstraintViolationException:
could not execute statement
at
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
at
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
-------------------------------------------------OneToMany----------------------------------------------------------------------------
>>> OneToMany 单相关联
2.1
需求背景:
每个人都有很多标签:
在User 类中添加:
1
2
3
4
5
6
7
|
public Set<Tag> getTags() {
return
tags;
} public void setTags(Set<Tag> tags) {
this .tags = tags;
} private
Set<Tag> tags;
|
同时 添加 Tag类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package
com.rhythmk.model;
public class Tag {
public
Integer getTagId() {
return
tagId;
}
public
void setTagId(Integer tagId) {
this .tagId = tagId;
}
public
String getTagTitle() {
return
tagTitle;
}
public
void setTagTitle(String tagTitle) {
this .tagTitle = tagTitle;
}
public
Integer getUserID() {
return
userID;
}
@Override
public
String toString() {
return
"Tag [tagId=" + tagId + ", tagTitle="
+ tagTitle + ", userID="
+ userID + "]" ;
}
public
void setUserID(Integer userID) {
this .userID = userID;
}
private
Integer tagId;
private
String tagTitle;
private
Integer userID;
} |
添加User对应XML配置:
<set name="tags"> <key column="userID"></key> <!-- 此处需要配置完成的类别--> <one-to-many class="com.rhythmk.model.Tag" /> </set>
注意:此处 one-to-many 对应的 class 需要填写类的全路径名称
2.2 验证:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@Test public
void test01_add() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Tag t1 = new
Tag();
t1.setTagTitle( "tag1" );
Tag t2 = new
Tag();
t2.setTagTitle( "tag2" );
Set<Tag> tags = new
HashSet<Tag>();
tags.add(t1);
tags.add(t2);
User entity = new
User();
entity.setUserName( "张飞2222" );
entity.setCreateTime( new
Date());
entity.setTags(tags);
session.save(t1);
session.save(t2);
session.save(entity);
session.getTransaction().commit();
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
}
|
输出:
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into
t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName,
createTime) values (?, ?)
Hibernate: update t_tag set userID=? where
tagId=?
Hibernate: update t_tag set userID=? where tagId=?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@Test public
void test02_get() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
System.err.println( "------01 -----------" );
User entity = (User) session.get(User. class , 6 );
System.err.println( "------02 -----------" );
for
(Tag t : entity.getTags()) {
System.out.println(t);
}
session.getTransaction().commit();
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
}
|
输出:
------01 -----------
Hibernate: select user0_.userID as userID1_3_0_,
user0_.userName as userName2_3_0_, user0_.createTime as createTi3_3_0_ from
t_user user0_ where user0_.userID=?
------02 -----------
Hibernate: select
tags0_.userID as userID3_3_0_, tags0_.tagId as tagId1_2_0_, tags0_.tagId as
tagId1_2_1_, tags0_.tagTitle as tagTitle2_2_1_ from t_tag tags0_ where
tags0_.userID=?
Tag [tagId=2, tagTitle=tag1, userID=null]
Tag [tagId=3,
tagTitle=tag2, userID=null]
>>> OneToMany 双相关联
背景:一个标签下有多少人
调整原标签代码:
<set name="users"> <key column="tagId"></key> <!-- 此处需已在hibernate-mapping 上配置了 类包名--> <one-to-many class="User" /> </set>
one-to-many class仅填写类名 现将包名调整到 hibernate-mapping属性上 如:
<hibernate-mapping package="com.rhythmk.model">
调整 Tag.java,添加:
1
2
3
4
5
6
7
8
9
|
public Set<User> getUsers() {
return
users;
} public void setUsers(Set<User> users) {
this .users = users;
} private
Set<User> users;
|
测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@Test public
void test01_add() {
Session session = null ;
try
{
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Tag t1 = new
Tag();
t1.setTagTitle( "tag1" );
Tag t2 = new
Tag();
t2.setTagTitle( "tag2" );
Set<Tag> tags = new
HashSet<Tag>();
tags.add(t1);
tags.add(t2);
User u1 = new
User();
u1.setUserName( "张飞2222" );
u1.setCreateTime( new
Date());
u1.setTags(tags);
User u2 = new
User();
u2.setUserName( "张飞2333332" );
u2.setCreateTime( new
Date());
u2.setTags(tags);
Set<User> users = new
HashSet<User>();
users.add(u1);
users.add(u2);
t1.setUsers(users);
t2.setUsers(users);
session.save(t1);
session.save(t2);
session.save(u1);
session.save(u2);
session.getTransaction().commit();
} catch
(Exception e) {
e.printStackTrace();
} finally
{
if
(session != null )
session.close();
}
}
|
输出:
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into
t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName,
createTime) values (?, ?)
Hibernate: insert into t_user (userName,
createTime) values (?, ?)
Hibernate: update t_user set tagId=? where
userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate:
update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=?
where userID=?
Hibernate: update t_tag set userID=? where
tagId=?
Hibernate: update t_tag set userID=? where tagId=?
Hibernate:
update t_tag set userID=? where tagId=?
Hibernate: update t_tag set userID=?
where tagId=?
注意:此处因为在提交事务过程中 Tag 以及User都相互影响变化,故出现12条SQL。
在实际项目中 我们并非需要 One 跟 Many都同时去维护数据,故引入 inverse,当inverse="true" 则不去维护对应关系,现修改User.hbm.xml 如下:
<set name="tags" lazy="extra" inverse="true"> <key column="userID"></key> <!-- 此处需要配置完成的类别--> <one-to-many class="com.rhythmk.model.Tag" /> </set>
执行测试输出:
Hibernate: insert into t_tag (tagTitle) values (?)
Hibernate: insert into
t_tag (tagTitle) values (?)
Hibernate: insert into t_user (userName,
createTime) values (?, ?)
Hibernate: insert into t_user (userName,
createTime) values (?, ?)
Hibernate: update t_user set tagId=? where
userID=?
Hibernate: update t_user set tagId=? where userID=?
Hibernate:
update t_user set tagId=? where userID=?
Hibernate: update t_user set tagId=?
where userID=?
Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany],布布扣,bubuko.com
Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]