主要是体现数据之间的关系,多对多之间的关系,保存与删除,
这次是员工角色之间的关系,一个员工可以对应多个角色,一个角色也可以是由多个员工扮演,实体类均省略setget与tostring方法
Role实体类:
public class Role {
private Long role_id;
private String role_name;
private String role_memo;
//表达多对多
private Set<User> users=new HashSet<User>();
}
User实体类:
public class User {
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private Character user_state;
//表达多对多
private Set<Role> roles=new HashSet<Role>();
}
由于是多对多的关系,因此在每个类的属性里,都是用set集合来表示相关联的属性
演示多对多的操作
public class Demo {
@Test
//保存员工以及角色
public void fun1(){
//1获得session
Session session = HibernateUtils.openSession();
//2开启事务
Transaction tx = session.beginTransaction();
//3操作
//-------------------------------------------------------------
//1创建两个User
User u1=new User();
u1.setUser_name("深田咏美");
User u2=new User();
u2.setUser_name("樱空桃");
//2创建两个角色
Role r1=new Role();
r1.setRole_name("女优");
Role r2=new Role();
r2.setRole_name("女友");
//3用户表达关系
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
u2.getRoles().add(r2);
//4角色表达关系
r1.getUsers().add(u1);
r1.getUsers().add(u2);
r2.getUsers().add(u1);
r2.getUsers().add(u2);
//5调用save方法依次保存
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);
//-------------------------------------------------------------
//4提交事务
tx.commit();
//5关闭
session.close();
}
@Test
//为樱空桃增加一个角色
public void fun2(){
//1获得session
Session session = HibernateUtils.openSession();
//2开启事务
Transaction tx = session.beginTransaction();
//3操作
//-------------------------------------------------------------
//1获得深田用户
User u = session.get(User.class,2l);
//2创建新角色
Role r=new Role();
r.setRole_name("情人");
//3将角色添加到用户
u.getRoles().add(r);
//4将角色持久化
session.save(r);
//-------------------------------------------------------------
//4提交事务
tx.commit();
//5关闭
//session.close();
}
@Test
//为樱空桃解除一个角色
public void fun3(){
//1获得session
Session session = HibernateUtils.openSession();
//2开启事务
Transaction tx = session.beginTransaction();
//3操作
//-------------------------------------------------------------
//1获得用户
User u = session.get(User.class,1l);
//2获得要移除的角色
Role r = session.get(Role.class, 1l);
//将用户中的角色移除
u.getRoles().remove(r);
//-------------------------------------------------------------
//4提交事务
tx.commit();
//5关闭
//session.close();
}
}
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">
<!-- 配置表与实体对象关系 -->
<!-- package属性:填写一个包名,元素内部凡是需要书写完整类名的属性,可以直接填写简单类名 -->
<hibernate-mapping package="cn.itheima.domain">
<!--
class元素:配置实体与表的对应关系
name:完整类名
table:数据库表名
-->
<class name="Role" table="sys_role">
<!--
id元素:配置主键映射的属性
column(可选):填写表中的主键列名,默认值,列名会默认使用属性名
type(可选):填写列(属性类型),hibernate会自动检测实体属性类型
每种类型有三种填法:java类型、hibernate类型、数据库类型
not-null(可选):配置该属性(列)是否不能为空,默认值false
length(可选):配置数据库中列的长度,默认值:使用数据库累心最大长度
-->
<id name="role_id" >
<!-- generator:主键生成策略 -->
<generator class="native"></generator>
</id>
<!--
property元素:除id之外的普通属性映射
name:填写属性名
column(可选):填写列名
type(可选):填写列(属性类型),hibernate会自动检测实体属性类型
每种类型有三种填法:java类型、hibernate类型、数据库类型
not-null(可选):配置该属性(列)是否不能为空,默认值false
length(可选):配置数据库中列的长度,默认值:使用数据库累心最大长度
-->
<property name="role_name" ></property>
<property name="role_memo" ></property>
<!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性:外键列名
class属性:与我关联的对象完整类名
-->
<!-- 级联操作 cascade
save-update:级联保存更新
delete:级联删除
all:save-update+delete
级联操作:简化操作
-->
<!-- inverse属性:配置关系是否维护
true:放弃维护外键关系
false(默认):customer维护关系
inverse:性能优化,提高关系维护的性能
结论:在将来开发中,如遇到多对多关系,一定要选择一方放弃维护关系
一般谁来放弃要看业务方向,例如录入员工时,需要为员工指定角色,
那么业务方向就是有员工维护角色,角色不需要维护与员工的关系,角色放弃维护
-->
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
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">
<!-- 配置表与实体对象关系 -->
<!-- package属性:填写一个包名,元素内部凡是需要书写完整类名的属性,可以直接填写简单类名 -->
<hibernate-mapping package="cn.itheima.domain">
<!--
class元素:配置实体与表的对应关系
name:完整类名
table:数据库表名
-->
<class name="Role" table="sys_role">
<!--
id元素:配置主键映射的属性
column(可选):填写表中的主键列名,默认值,列名会默认使用属性名
type(可选):填写列(属性类型),hibernate会自动检测实体属性类型
每种类型有三种填法:java类型、hibernate类型、数据库类型
not-null(可选):配置该属性(列)是否不能为空,默认值false
length(可选):配置数据库中列的长度,默认值:使用数据库累心最大长度
-->
<id name="role_id" >
<!-- generator:主键生成策略 -->
<generator class="native"></generator>
</id>
<!--
property元素:除id之外的普通属性映射
name:填写属性名
column(可选):填写列名
type(可选):填写列(属性类型),hibernate会自动检测实体属性类型
每种类型有三种填法:java类型、hibernate类型、数据库类型
not-null(可选):配置该属性(列)是否不能为空,默认值false
length(可选):配置数据库中列的长度,默认值:使用数据库累心最大长度
-->
<property name="role_name" ></property>
<property name="role_memo" ></property>
<!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性:外键列名
class属性:与我关联的对象完整类名
-->
<!-- 级联操作 cascade
save-update:级联保存更新
delete:级联删除
all:save-update+delete
级联操作:简化操作
-->
<!-- inverse属性:配置关系是否维护
true:放弃维护外键关系
false(默认):customer维护关系
inverse:性能优化,提高关系维护的性能
结论:在将来开发中,如遇到多对多关系,一定要选择一方放弃维护关系
一般谁来放弃要看业务方向,例如录入员工时,需要为员工指定角色,
那么业务方向就是有员工维护角色,角色不需要维护与员工的关系,角色放弃维护
-->
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
各个配置属性的作用全都在注释里,就不单独列出来了