多对多映射配置
- 以用户和角色为例演示:
- 第一步:创建实体类:用户和角色
- 第二步:让两个实体类之间相互表示
(1) 一个用户里面表示所有角色:使用set集合
(2) 一个角色有多个用户:使用set集合 - 第三步:配置映射关系
(1) 基本配置
(2) 配置多对多关系 - 第四步:在核心配置文件中加载映射配置文件
- 第五步:测试
第一步:创建实体类:用户和角色
- 用户实体
public class User {
private Integer id;
private String name;
private String password;
}
- 角色实体
public class Role {
private Integer id; // 角色id
private String name;// 角色名称
private String memo; // 角色描述
}
第二步:让两个实体相互关联
- 用户与角色关系的实体类
public class User {
private Integer id; // 用户id
private String name; // 用户名称
private String password; // 用户密码
// 用户与角色之间的关系: 一个用户可以有多个角色: 一对多
private Set<Role> roles = new HashSet<>();
}
- 角色与用户关系的实体类
public class Role {
private Integer id; // 角色id
private String name;// 角色名称
private String memo; // 角色描述
// 角色与用户之间的关系:一个角色里面可以有多个用户:一对多
private Set<User> users = new HashSet<>();
}
第三步:配置映射关系
- 用户的基本映射配置
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.User" table="t_user">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="password" column="password"></property>
</class>
</hibernate-mapping>
- 角色的基本映射配置
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.Role" table="t_role">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="memo" column="memo"></property>
</class>
</hibernate-mapping>
- 用户与角色关系的映射配置
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.User" table="t_user">
<!-- 用户的基本映射配置 -->
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="password" column="password"></property>
<!-- 用户与角色关系的映射配置: table是第三张表名称 -->
<set name="roles" table="t_user_role">
<!-- key里面配置的是外外键: 用户表在第三张表中的外键 -->
<key column="userid"></key>
<!-- 用户关联的角色的配置
class属性: 角色实体类的全限定类名
column属性:角色表在第三张表中的外键
-->
<many-to-many class="com.ycom1024.hibernate.po.Role" column="roleid"/>
</set>
</class>
</hibernate-mapping>
- 角色与用户之间关系的映射配置
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.Role" table="t_role">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="memo" column="memo"></property>
<set name="users" table="t_user_role">
<key column="roleid"></key>
<many-to-many class="com.ycom1024.hibernate.po.User" column="userid"/>
</set>
</class>
</hibernate-mapping>
第四步:在核心配置文件中加载映射配置文件
<?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 访问数据库服务器的url -->
<property name="hibernate.connection.url">jdbc:mysql:///hibernate07</property>
<!-- 访问数据库服务器的用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 访问数据库服务器的密码 -->
<property name="hibernate.connection.password">root</property>
<!-- 第二部分:Hibernate自身的配置 -->
<!-- 让Hibernate输出SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 让Hibenate输出的SQL语句是格式化的SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!-- 让Hibernate帮助我们创建数据表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置MySQL数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 获取本地线程Session的配置 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 第三部分:加载映射配置文件 -->
<mapping resource="com/ycom1024/hibernate/po/Role.hbm.xml"/>
<mapping resource="com/ycom1024/hibernate/po/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
第五步:测试
public class HibernateUtils {
private static final SessionFactory sessionFactofy;
static {
Configuration cfg = new Configuration();
cfg.configure();
sessionFactofy = cfg.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactofy;
}
public static void main(String[] args) {
System.out.println("00000");
}
}
- 在指定的数据库中就生成了三张表
多对多级联保存
- 根据用户保存角色:
(1) 第一步:在用户映射配置文件中的set标签进行配置cascade属性值为save-update
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.User" table="t_user">
<!-- 用户的基本映射配置 -->
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="password" column="password"></property>
<!-- 用户与角色关系的映射配置: table是第三张表名称 -->
<set name="roles" table="t_user_role" cascade="save-update">
<!-- key里面配置的是外外键: 用户表在第三张表中的外键 -->
<key column="userid"></key>
<!-- 用户关联的角色的配置
class属性: 角色实体类的全限定类名
column属性:角色表在第三张表中的外键
-->
<many-to-many class="com.ycom1024.hibernate.po.Role" column="roleid"/>
</set>
</class>
</hibernate-mapping>
(2) 第二步:写代码实现:创建用户和角色对象,把角色放到用户里面,最终保存用户就可以了
@Test
public void testSave() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user1 = new User();
user1.setName("lucy");
user1.setPassword("12345678");
User user2 = new User();
user2.setName("mary");
user2.setPassword("12345689");
// 总经理
Role role1 = new Role();
role1.setName("Mananger");
role1.setMemo("Mananger");
// 秘书
Role role2 = new Role();
role2.setName("mishu");
role2.setMemo("mishu");
// 保安
Role role3 = new Role();
role3.setName("baoan");
role3.setMemo("baoan");
// 用户1-->role1/role2
user1.getRoles().add(role1);
user1.getRoles().add(role2);
// 用户2-->role2/role3
user2.getRoles().add(role2);
user2.getRoles().add(role3);
// 保存用户
session.save(user1);
session.save(user2);
tx.commit();
session.close();
sessionFactory.close();
}
----------------------------------------------------------------------------------
Hibernate:
insert
into
t_user
(name, password)
values
(?, ?)
Hibernate:
insert
into
t_role
(name, memo)
values
(?, ?)
Hibernate:
insert
into
t_role
(name, memo)
values
(?, ?)
Hibernate:
insert
into
t_user
(name, password)
values
(?, ?)
Hibernate:
insert
into
t_role
(name, memo)
values
(?, ?)
Hibernate:
insert
into
t_user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
t_user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
t_user_role
(userid, roleid)
values
(?, ?)
Hibernate:
insert
into
t_user_role
(userid, roleid)
values
(?, ?)
多对多级联删除
- 需求:在删除用户的时候,删除关联的角色
- 第一步:根据id查询得到用户
- 第二步:直接删除用户
@Test
public void testDelete1() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 1);
session.delete(user);
tx.commit();
session.close();
sessionFactory.close();
}
----------------------------------------------------------------------------------
Hibernate:
select
user0_.id as id1_1_0_,
user0_.name as name2_1_0_,
user0_.password as password3_1_0_
from
t_user user0_
where
user0_.id=?
Hibernate:
delete
from
t_user_role
where
userid=?
Hibernate:
delete
from
t_user
where
id=?
- 楼上的代码并没有删除用户关联的角色信息:并没有删除角色表中的记录,只是删除了用户-角色关系表中的用户与角色的对应关系:那么如果要做到级联删除的话,需要在用户表的映射配置文件的set标签的中配置cascade属性值为delete
<hibernate-mapping>
<class name="com.ycom1024.hibernate.po.User" table="t_user">
<!-- 用户的基本映射配置 -->
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="password" column="password"></property>
<!-- 用户与角色关系的映射配置: table是第三张表名称 -->
<set name="roles" table="t_user_role" cascade="save-update,delete">
<!-- key里面配置的是外外键: 用户表在第三张表中的外键 -->
<key column="userid"></key>
<!-- 用户关联的角色的配置
class属性: 角色实体类的全限定类名
column属性:角色表在第三张表中的外键
-->
<many-to-many class="com.ycom1024.hibernate.po.Role" column="roleid"/>
</set>
</class>
</hibernate-mapping>
- 测试代码
@Test
public void testDelete1() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 5);
session.delete(user);
tx.commit();
session.close();
sessionFactory.close();
}
---------------------------------------------------------------------------
Hibernate:
select
user0_.id as id1_1_0_,
user0_.name as name2_1_0_,
user0_.password as password3_1_0_
from
t_user user0_
where
user0_.id=?
Hibernate:
select
roles0_.userid as userid2_2_0_,
roles0_.roleid as roleid1_2_0_,
role1_.id as id1_0_1_,
role1_.name as name2_0_1_,
role1_.memo as memo3_0_1_
from
t_user_role roles0_
inner join
t_role role1_
on roles0_.roleid=role1_.id
where
roles0_.userid=?
Hibernate:
delete
from
t_user_role
where
userid=?
Hibernate:
delete
from
t_user_role
where
roleid=?
Hibernate:
delete
from
t_user_role
where
roleid=?
Hibernate:
delete
from
t_role
where
id=?
Hibernate:
delete
from
t_role
where
id=?
Hibernate:
delete
from
t_user
where
id=?
维护第三张表关系
- 需求:让某个用户有某个角色
(1) 第一步:根据id查询用户和角色
(2) 第二步: 把角色对象放到用户对象的集合中
@Test
public void testUpdate1() {
// 让用户lucy增加一个保安的角色
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User lucy = session.get(User.class, 7); // 查询得到用户lucy
Role baoan = session.get(Role.class, 12);// 查询得到角色保安
// 将角色对象添加到用户对象的角色集合中即可
lucy.getRoles().add(baoan);
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------------
Hibernate:
select
user0_.id as id1_1_0_,
user0_.name as name2_1_0_,
user0_.password as password3_1_0_
from
t_user user0_
where
user0_.id=?
Hibernate:
select
role0_.id as id1_0_0_,
role0_.name as name2_0_0_,
role0_.memo as memo3_0_0_
from
t_role role0_
where
role0_.id=?
Hibernate:
select
roles0_.userid as userid2_2_0_,
roles0_.roleid as roleid1_2_0_,
role1_.id as id1_0_1_,
role1_.name as name2_0_1_,
role1_.memo as memo3_0_1_
from
t_user_role roles0_
inner join
t_role role1_
on roles0_.roleid=role1_.id
where
roles0_.userid=?
Hibernate:
insert
into
t_user_role
(userid, roleid)
values
(?, ?)
- 需求:让某个用户没有某个角色
(1) 第一步:根据id查询用户和角色
(2) 第二步:从用户对象的set集合对象中删除角色对象
@Test
public void testUpdate2() {
// 让用户lucy去掉秘书的角色
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User lucy = session.get(User.class, 7); // 查询得到用户lucy
Role mishu = session.get(Role.class, 11);// 查询得到角色秘书
// 让用户对象中的set集合对象删除角色对象
lucy.getRoles().remove(mishu);
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------------
Hibernate:
select
user0_.id as id1_1_0_,
user0_.name as name2_1_0_,
user0_.password as password3_1_0_
from
t_user user0_
where
user0_.id=?
Hibernate:
select
role0_.id as id1_0_0_,
role0_.name as name2_0_0_,
role0_.memo as memo3_0_0_
from
t_role role0_
where
role0_.id=?
Hibernate:
select
roles0_.userid as userid2_2_0_,
roles0_.roleid as roleid1_2_0_,
role1_.id as id1_0_1_,
role1_.name as name2_0_1_,
role1_.memo as memo3_0_1_
from
t_user_role roles0_
inner join
t_role role1_
on roles0_.roleid=role1_.id
where
roles0_.userid=?
Hibernate:
delete
from
t_user_role
where
userid=?
and roleid=?