以用户和角色为例,一个用户可以有多个角色,一个角色也可以属于多个用户,这种关系刚好是多对多的关系.
创建javabean
User.java
public class User {
private Long user_id;
private String user_name;
private String user_password;
private String user_state;
//多对多中关联的另一方
private Set<Role> roles = new HashSet<Role>();
//get set...
}
Role.java
public class Role {
private Long role_id;
private String role_name;
//多对多中关联的另一方
private Set<User> users = new HashSet<User>();
//get set...
}
创建映射文件
User.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="blog.csdn.net.mchenys.domain.User" table="t_user">
<id name="user_id" column="user_id">
<generator class="native"/>
</id>
<property name="user_name" column="user_name"/>
<property name="user_password" column="user_password"/>
<property name="user_state" column="user_state"/>
<!--
set标签属性
name:javabean中集合的属性名
table:中间表的名字,这个必现2边保持一致
key标签属性
column:中间表中对应该类的外键名
many-to-many标签属性
class:另一方的类全路径名
column:另一方的类在中间表的外键名
-->
<set name="roles" table="user_role">
<key column="uid"/>
<many-to-many class="blog.csdn.net.mchenys.domain.Role" column="rid"/>
</set>
</class>
</hibernate-mapping>
Role.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="blog.csdn.net.mchenys.domain.Role" table="t_role">
<id name="role_id" column="role_id">
<generator class="native"/>
</id>
<property name="role_name" column="role_name"/>
<!--
set标签属性
name:javabean中集合的属性名
table:中间表的名字,这个必现2保持一致
inverse:true表示放弃维护外键,多对多关系中必须有一方放弃维护,否则会报错
key标签属性
column:中间表中对应该类的外键名
many-to-many标签属性
class:另一方的类全路径名
column:另一方的类在中间表的外键名
-->
<set name="users" table="user_role" inverse="true">
<key column="rid"/>
<many-to-many class="blog.csdn.net.mchenys.domain.User" column="uid"/>
</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>
<!-- 记住:先配置SessionFactory标签,一个数据库对应一个SessionFactory标签 -->
<session-factory>
<!-- 必须要配置的参数有5个,4大参数,数据库的方言 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day03</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 数据库的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<!-- 显示SQL语句,在控制台显示 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!-- 生成数据库的表结构
update:如果没有表结构,创建表结构。如果存在,不会创建,可动态添加字段(新增属性和映射即可),不能删除字段
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 开启绑定本地的session -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 映射配置文件,需要引入映射的配置文件 -->
<mapping resource="blog/csdn/net/mchenys/domain/User.hbm.xml"/>
<mapping resource="blog/csdn/net/mchenys/domain/Role.hbm.xml"/>
</session-factory>
</hibernate-configuration>
双向关联保存
/**
* 测试双向关联保存
*/
@Test
public void test1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 创建用户
User u1 = new User();
u1.setUser_name("小张");
User u2 = new User();
u2.setUser_name("小李");
// 创建角色
Role r1 = new Role();
r1.setRole_name("管理员");
Role r2 = new Role();
r1.setRole_name("老师");
// 双向关联
u1.getRoles().add(r1);
u1.getRoles().add(r2);
r1.getUsers().add(u1);
r2.getUsers().add(u1);
u2.getRoles().add(r1);
r1.getUsers().add(u2);
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
tr.commit();
}
级联保存
/**
* 级联保存:保存用户级联保存角色
*/
@Test
public void test2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 创建用户
User u1 = new User();
u1.setUser_name("张三");
User u2 = new User();
u2.setUser_name("赵四");
// 创建角色
Role r1 = new Role();
r1.setRole_name("经理");
Role r2 = new Role();
r2.setRole_name("销售");
//单项关联
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
// 级联保存数据
session.save(u1);
session.save(u2);
tr.commit();
}
记得要在User.hbm.xml配置文件中添加cascade属性到set标签上,例如:
如何修改中间表的数据
要修改中间表的数据也很简单,反应到java层面就是操作集合中的对象,只不过得先通过Hibernate先去查找出相关联的数据才能操作,下面以张三用户删除经理角色为例
/**
* 操作中间表数据:让张三去掉经理这角色
*/
@Test
public void test3() {
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 查找张三用户
User user = session.get(User.class, 3L);
// 查找经理角色
Role role = session.get(Role.class, 4L);
// 操作集合来解除关联,不需要执行update操作,因为持久态的对象可以有自动更新的功能
user.getRoles().remove(role);
// 提交
tr.commit();
}