Hibernate 一对多双向关联(XML方式配置)

引言:

  1. 单向“一对多”和“多对一”
    • 一对多:将一的主键加入到多的一方表中作为外键,在一的一方需要加入多的set集合
      •  可以通过“一”操作“多”,反之,不可以,比如,添加category目录,那么其属性中所有对应的book会自动添加进去
    • 多对一:将多一方的主键加入到一的表中作为主键,在多的一方需要定义一的对象
      •  可以通过“多”操作“一”,反之,不可以,比如,添加book,那么其所属的category会自动添加进来,不需要在去找,然后添加
  2. 双向多对一:双方相互添加彼此

要建两张表:book和category

Book类:

 1 public class Book {
 2     private Integer bookId;
 3     private String bookName;
 4     private String author;
 5     private double price;
 6 
 7     private Category category;
 8     
 9     /*省略set和get方法*/
10 
11 }

book.hbm.xm

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6 
 7     <!--多对一双向关联-->
 8     <!--“多”-->
 9     <class name="com.ajax.model.Book" table="BOOK" schema="TEST">
10         <id name="bookId" column="BOOKID"/>
11         <property name="bookName" column="BOOKNAME"/>
12         <property name="author" column="AUTHOR"/>
13         <property name="price" column="PRICE" type="java.lang.Double"/>
14 
15         <!--建立多对一关联映射
16         book(多)映射关键点:
17             1.book的哪个属性映射?name:categoty
18             2.通过什么外键字段映射:categoty_id
19             3.映射到哪个实体类?class:com.ajax.model.category
20         -->
21         <!--name 对应 的是book中的对应的多字段-->
22         <many-to-one name="category" column="CATEGORYID" class="com.ajax.model.Category"/>
23     </class>
24 </hibernate-mapping>

 

category

1 public class Category {
2 
3     private Integer categoryId;
4     private String categoryName;
5     private Set<Book> books;
6 
7     //省去set和get方法
8 }

category.hbm.xml

 1 <?xml version='1.0' encoding='utf-8'?>
 2         <!DOCTYPE hibernate-mapping PUBLIC
 3                 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4                 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6 
 7 <class name="com.ajax.model.Category" table="CATEGORY" schema="TEST">
 8     <id name="categoryId" column="CATEGORYID"/>
 9     <property name="categoryName" column="NAME"/>
10 
11     <!--一对多关联隐射配置
12     “一”:
13         1.指定映射的集合属性:books
14         2.集合属性对应的集合表:BOOK
15         3.集合表的外键字段t_book.category_id
16         4.集合元素的类型
17     -->
18 
19     <set name="books" table="BOOK" inverse="true">
20         <!--column的值category_id与多对一关系中的外键值一致
21         双向关联用inverse,单向关联用cascade表示两张表的级联,inverse默认为false,
22         表示由当前对象负责维护两张表之间的级联关系-->
23         <key column="CATEGORYID"></key>
24         <one-to-many class="com.ajax.model.Book"/>
25     </set>
26 </class>
27 </hibernate-mapping>

hibernate.cfg.xml文件

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
 8         <property name="connection.username">test</property>
 9         <property name="connection.password">123456</property>
10 
11         <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
12 
13         <!--显示生成sql语句-->
14         <property name="show_sql">true</property>
15         <!--格式化sql语句-->
16         <property name="hibernate.format_sql">true</property>
17         <!--如果表不存在,将自动创建-->
18         <!--<property name="hibernate.hbm2ddl.auto">update</property>-->
19 
20         <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
21 
22         <mapping resource="com/ajax/model/Book.hbm.xml"/>
23         <mapping resource="com/ajax/model/Category.hbm.xml"/>
24         <!--<mapping resource="com/ajax/model/Book.hbm.xml"/>-->
25 
26         <!--以注解方式配置-->
27         <!--<mapping class="com.model.Book"/>-->
28         <!--<mapping class="com.automapping.Book"/>-->
29 
30         <!--<mapping resource="com/model/Book.hbm.xml"/>-->
31     </session-factory>
32 </hibernate-configuration>

注:这玩意hibernate.cfg.xml文件的头部分也有坑:

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

idea自动生成的会提示找不到配置文件:

        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"

根据实体隐射关系自动生成表:

  • SchemaExport()
  • 配置文件:
    <property name="hibernate.hbm2ddl.auto">true</property>
     1     /*
     2      *测试使用SchemaExport根据实体类及映射关系生成表
     3      */
     4     @Test
     5     public void TestSchemaExport(){
     6         Configuration cfg = new Configuration().configure();//读取配置文件
     7         //SessionFactory sessionFactory = cfg.buildSessionFactory();//根据配置文件创建session工厂
     8         SchemaExport export = new SchemaExport(cfg);//创建SchemaExport
     9         //执行生成表。参数1:是否显示sql语句,参数2:是否到数据库中执行
    10         export.create(true,true);
    11     }
    12     /*

    输出结果:(生成了两个外键,原因是 在配置文件中拼错了)

测试:

HibernateUtil.java

public class HibernateUtil {
    private static SessionFactory sessionFactory;

    private HibernateUtil(){}

    static{
        Configuration configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    }

    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }

    public static Session getSession(){
        return sessionFactory.openSession();
    }

    public static void closeSession(Session session){
        if (null !=session){
            session.close();
        }

    }
}

测试方法:

 1     /*
 2      *往数据库中写点数据
 3      */
 4     @Test
 5     public void addData(){
 6         Session session = null;
 7         try {
 8             session = HibernateUtil.getSession();
 9 
10             session.beginTransaction();
11             Category category = new Category();
12             category.setCategoryId(1);
13             category.setCategoryName("古典小说");
14 
15             Category category1 = new Category();
16             category1.setCategoryId(2);
17             category1.setCategoryName("都市言情");
18 
19             Book b1 = new Book();
20             b1.setBookId(1);
21             b1.setBookName("西游记");
22             b1.setAuthor("吴承恩");
23             b1.setPrice(10);
24 
25             Book b2 = new Book();
26             b2.setBookId(2);
27             b2.setBookName("天堂向左,深圳往右");
28             b2.setAuthor("慕容雪村");
29             b2.setPrice(20);
30 
31             Book b3 = new Book();
32             b3.setBookId(3);
33             b3.setBookName("封神演义");
34             b3.setAuthor("xxx");
35             b3.setPrice(20);
36 
37             //保存各自的单表信息
38             session.persist(b1);
39             session.persist(b2);
40             session.persist(b3);
41 
42             session.persist(category);
43             session.persist(category1);
44 
45 
46             //创建表的关联关系,保存在多的一方
47             b1.setCategory(category);
48             b2.setCategory(category1);
49             b3.setCategory(category);
50 
51 //            category.getBooks().add(b1);
52 //            category1.getBooks().add(b2);
53 //            category.getBooks().add(b3);
54 
55             session.save(b1);
56             session.save(b2);
57             session.save(b3);
58             session.getTransaction().commit();
59         }catch (Exception e){
60             e.printStackTrace();
61             session.getTransaction().rollback();
62 
63         }finally {
64             HibernateUtil.closeSession(session);
65             System.out.println("成功关闭session!");
66         }
67 
68     }
69 
70     @Test
71     public void TestFindBooks(){
72         Session session = null;
73         session = HibernateUtil.getSession();
74         session.getTransaction().begin();
75 
76         Category category = (Category) session.get(Category.class,1);
77         System.out.println("目录id:"+category.getCategoryId());
78         System.out.println("目录name:"+category.getCategoryName());
79 
80         //遍历该目录下的所有书籍
81         Set<Book> books = category.getBooks();
82         System.out.println("属于'"+category.getCategoryName()+"'的书有");
83 
84         for (Iterator<Book> it =books.iterator();it.hasNext();){
85             Book book = (Book) it.next();
86             System.out.println("书id:"+book.getBookId());
87             System.out.println("书名:"+book.getBookName());
88             System.out.println("作者:"+book.getAuthor());
89             System.out.println("价格:"+book.getPrice());
90             System.out.println("----------------------------------");
91         }
92     }

 尝试在“一”的一方保存关联关系,把添加数据部分代码改了:

 1             //创建表的关联关系,保存在多的一方
 2 //            b1.setCategory(category);
 3 //            b2.setCategory(category1);
 4 //            b3.setCategory(category);
 5 
 6             category.getBooks().add(b1);
 7             category1.getBooks().add(b2);
 8             category.getBooks().add(b3);
 9 
10             session.save(category);
11             session.save(category1);
12 
13 //            session.save(b1);
14 //            session.save(b2);
15 //            session.save(b3);

运行会报错,因为在配置文件中,已经约定了inverse 属性,尝试改变 会报错的哦!

 

转载于:https://www.cnblogs.com/ditto/p/9266725.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值