概述
新建一个xml文件,配置书籍实体的映射 ,Book.hbm.xml–》匹配实体类
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.entity.Book" table="t_hibernate_book">
<id name="book_id" type="java.lang.Integer" column="book_id">
<generator class="increment"></generator>
</id>
<property name="book_name" type="java.lang.String" column="book_name"></property>
<property name="price" type="java.lang.Float" column="price"></property>
<!-- 以上为实体中的基本属性 -->
<!--
set标签对应实体中的set集合,若实体中使用的是List集合,这里则使用list标签
name: 指的是当前映射实体
table: 对应的是中间表的表名
-->
<set name="categorys" table="t_hibernate_book_category">
<!-- 中间表字段(与当前映射实体对应的表的主键相关联的那个字段) -->
<key column="bid"></key>
<!--
class: ‘多’方的全限定名,这个多方也可以叫对方,也就是类别
column: 中间表字段(与‘多’方主键相关联的字段)
-->
<many-to-many class="com.hibernate.entity.Category" column="cid"></many-to-many>
</set>
</class>
</hibernate-mapping>
新建一个xml文件,配置类别实体的映射,Category.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.entity.Category" table="t_hibernate_category">
<id name="category_id" type="java.lang.Integer" column="category_id">
<generator class="increment"></generator>
</id>
<property name="category_name" type="java.lang.String" column="category_name"></property>
<!--
set标签对应实体中的set集合,若实体中使用的是List集合,这里则使用list标签
name: 指的是当前映射实体
table: 对应的是中间表的表名 ,
关联关系交与对方管理(中间表的数据是否交给对方维护)
cascade
inverse
-->
<set name="books" table="t_hibernate_book_category" cascade="save-update" inverse="true">
<!-- 中间表字段(与当前映射实体对应的表的主键相关联的那个字段) -->
<key column="cid"></key>
<!--
class: ‘多’方的全限定名,这个多方也可以叫对方,也就是类别
column: 中间表字段(与‘多’方主键相关联的字段)
-->
<many-to-many class="com.hibernate.entity.Book" column="bid"></many-to-many>
</set>
</class>
</hibernate-mapping>
将书籍与类别的实体映射文件配置到hibernate的核心配置文件中:
(核心配置文件也是新建的xml文件)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置数据源信息 -->
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 配置sql语句生成的规则,配置数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置本地事务 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 配置开发调试所用的配置show_sql,format_sql -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 配置映射文件 -->
<mapping resource="com/hibernate/entity/Book.hbm.xml"/>
<mapping resource="com/hibernate/entity/Category.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试代码:
hibernate中一对多双向关联的记录
1.查询
//需求:通过ID查询书籍的信息,同时查询书籍对应的类别的信息。
@Test
public void testGet() {
//1.获得session会话
Session session = HibernateUtils.getSession();
//2.开启事务
Transaction beginTransaction = session.beginTransaction();
//3.数据库操作
Book b=new Book();
b.setBook_id(1);
Book book = session.get(Book.class,b.getBook_id());
System.out.println(book);
book.getCategorys().stream().forEach(System.out::println);
//4.关闭事务
beginTransaction.commit();
//5.关闭会话
session.close();
}
2.新增
由于我们之前在类别的映射文件Category.hbm.xml中设置了 cascade=“save-update” inverse=“true” ,设置这几个属性则表示新增与修改时,中间表的数据是否由对方维护,如果inverse设置为true,则表示由对方维护(即由书籍维护中间表数据)。所以我们这里的中间表数据就由书籍来维护。
//需求:通过新增书籍,同时在中间表中新增该书籍与其对应的类别。
@Test
public void testSave() {
Session session = HibernateUtils.getSession();
Transaction beginTransaction = session.beginTransaction();
//实例化一个Book对象
Book b=new Book();
//初始化book对象
b.setBook_name("斗破苍穹");
b.setPrice(10f);
//为Book对象设置它的书籍类别
Category c=new Category();
c.setCategory_id(1);
Category c2=new Category();
c2.setCategory_id(2);
b.getCategorys().add(c);
b.getCategorys().add(c2);
//执行新增操作
Integer save = (Integer) session.save(b);
beginTransaction.commit();
session.close();
}
由于我们设置了中间表数据由书籍维护,在数据库中刷新一下数据会发现,书籍表中斗破苍穹添加成功了,中间表也将对应的书籍id以及类型id添加了进去,所以增加是成功的;不过这里还要举一个反面的例子:添加类别,且为类别中的Set集合加入书籍
需求:通过新增类别,同时在中间表中新增该类别与其对应的书籍。
@Test
public void testSaveC() {
Session session = HibernateUtils.getSession();
Transaction beginTransaction = session.beginTransaction()
//实例化一个类型对象
Category c=new Category();
//初始化类型对象
c.setCategory_name("修仙");
//为Category对象设置它的书籍
Book book=new Book();
book.setBook_id(6);
book.setBook_name("魔道");
book.setPrice(30f);
c.getBooks().add(book);
Integer save = (Integer) session.save(c);
beginTransaction.commit();
session.close();
}
注:由于中间表的数据是由书籍来维护的,所以新增类型时, 如果指定了书籍 ,中间表不仅不会添加数据,反而还会删除掉中间表中的数据。 故增加类别时,只做单纯的增加类别就行了,别指定书籍。
3.删除
//需求:根据书籍id删除书籍,同时删除中间表中该书籍所对应的数据
@Test
public void testDelete() {
Session session = HibernateUtils.getSession();
Transaction beginTransaction = session.beginTransaction();
//执行删除操作
Book book=new Book();
book.setBook_id(5);
session.delete(book);
beginTransaction.commit();
session.close();
}
删除与新增有相同,由于之前在类别的实体映射文件中配置了,中间表的数据由书籍去维护。
So,对Book进行删除时,中间表中该书籍对应的数据也会被删除掉,需求能够达成!
对类别进行删除,中间表有该类别删除不了(由于中间表关联了主外键),所以删除被控方(类别)建议不使用
注:删除被控方数据时,如果中间表中关联了要删除的那条数据,则中间表中关联的数据也会被一同删除。
@Test
public void testDeleteC() {
Session session = HibernateUtils.getSession();
Transaction beginTransaction = session.beginTransaction();
//要删除的类别id
Category c=new Category();
c.setCategory_id(4);
/**
* 被控方的删除:
* 1、先要获取到被控方的数据
* 2、利用被控方获取到主控方来解除关联关系
* 3、最后将被控方删除
*/
Category category = session.get(Category.class, c.getCategory_id());
for (Book b : category.getBooks()) {
b.getCategorys().remove(category);
}
session.delete(category);
beginTransaction.commit();
session.close();
}
最后
以上就是调皮曲奇为你收集整理的hibernate级联 新增及删除的全部内容,希望文章能够帮你解决hibernate级联 新增及删除所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复