Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]

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]

时间: 2024-12-21 20:53:58

Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [ManyToOne,OneToMany]的相关文章

Rhythmk 学习 Hibernate 05 - Hibernate 表间关系 [One To One]

1.One To One 单相 背景: 古代一个老婆  只能关联一个老公 husband.java ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.rhythmk.model; public class husband {          public Integer getHusbandId() {         return husbandId;     }     public void setHusba

Hibernate之表间关系

ManyToOne 多对一,是最常见的表间关系,对应关系数据库中的外键关系.通常用于建立子实体和其父实体的关联关系 @Entity(name = "Person") public static class Person { @Id @GeneratedValue private Long id; //Getters and setters are omitted for brevity } @Entity(name = "Phone") public static

hibernate中多表映射关系配置

1.one-to-many一对多关系的映射配置(在一的一方实体映射文件中配置) <!-- cascade属性:级联操作属性 save-update: 级联保存,保存客户时,级联保存客户关联的联系人 delete:级联删除,删除客户时,级联删除客户关联的联系人 all:级联保存+级联删除 --> <!-- inverse属性:设置是否不维护关联关系 true:不维护关联 false(默认值):维护关联 --> <!-- 一对多 --> <set name="

Node.js ORM框架Sequlize之表间关系

Sequelize模型之间存在关联关系,这些关系代表了数据库中对应表之间的主/外键关系.基于模型关系可以实现关联表之间的连接查询.更新.删除等操作.本文将通过一个示例,介绍模型的定义,创建模型关联关系,模型与关联关系同步数据库,及关系模型的增.删.改.查操作. 数据库中的表之间存在一定的关联关系,表之间的关系基于主/外键进行关联.创建约束等.关系表中的数据分为1对1(1:1).1对多(1:M).多对多(N:M)三种关联关系. 在Sequelize中建立关联关系,通过调用模型(源模型)的belon

sql语句之表间字段值复制遇到的一些问题--基于mysql

好久没来园子了,转眼2017已经到3月份了,前段时间一直忙没时间写博客(其实是自己懒),感觉内心好惭愧.昨天临下班前,技术老大突然对我说要改下表结构,问我能不能实现将一个表的字段值复制到另外一个表的某个字段中去,感觉这好拗口,其实就是表间字段值复制.于是,昨晚加了会儿班百度了下然后自己在本地测试了下,还真弄出来了,下面就把这个sql语句记下来,以备忘. 1,背景和需求 两张表a_user和b_user结构如下: a_user +--------+-------------+------+----

Rhythmk 学习 Hibernate 07 - Hibernate annotation 实体注解

参考: http://docs.jboss.org/hibernate/annotations/3.4/reference/zh_cn/html_single/ 1.系统配置: 可以通过使用  mapping的 resource,于class 属性混合配置 <mapping resource="com/rhythmk/model/product.hbm.xml" /> <mapping class="com.rhythmk.model.User"&

Rhythmk 学习 Hibernate 03 - Hibernate 之 延时加载 以及 ID 生成策略

Hibernate 加载数据 有get,跟Load 1.懒加载: 使用session.load(type,id)获取对象,并不读取数据库,只有在使用返回对象值才正真去查询数据库. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test    public void  test1()    {        Session session = null;         try {             session = Hiber

Rhythmk 学习 Hibernate 02 - Hibernate 之 瞬时状态 离线状态 持久化状态 三状态

by:rhythmk.cnblogs.com 1.Hibernate 三种状态: 1.1.三种定义(个人理解,不一定准确):  瞬时状态(transient):    不被session接管,且不存在数据库中的对象的状态,类似于新New一个对象  离线状态 (detached):    数据库中存在而不被session接管  持久化状态(persistent): 对象被session管理且数据库中存在此对象 1.2. 状态之间转换关系图 2 .状态转换以及Hibernate数据库执行过程详解:

Rhythmk 学习 Hibernate 09 - Hibernate HQL

1.初始数据 ? 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 @Test     public void test01() {         Session session = null;         try {             session = HibernateUtil.getSessionFactory().openSession();             session.begin