Hibernate多对多操作
来源:互联网 发布:帝国cms快速仿站 编辑:程序博客网 时间:2024/05/21 19:45
---------------------siwuxie095
Hibernate 多对多操作
以用户和角色为例
(一)多对多映射配置
第一步:创建两个实体类,用户和角色
第二步:让两个实体类之间互相表示
(1)在用户实体类中表示多个角色
(2)在角色实体类中表示多个用户
第三步:配置映射关系
(1)配置基本的映射
(2)配置关联关系的映射(多对多关系)
1)在用户的映射配置文件中,表示所有角色
2)在角色的映射配置文件中,表示所有用户
第四步:在核心配置文件中引入映射配置文件
(二)多对多级联保存
如:添加两个用户,为每个用户添加两个角色
(1)复杂写法
先在角色的映射配置文件中的set 标签添加inverse 属性,并
将其值设置为true,再进行具体实现
/**
*多对多级联保存的复杂写法
*
*
*手动加上 @Test以进行单元测试(将自动导入 JUnit 4的 jar包)
*
*选中方法名,右键->Run As->JUint Test
*/
@Test
publicvoid testSave(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//添加两个用户,为每个用户添加两个角色
//(1)
//创建用户和角色对象
User user1=new User();
user1.setUserName("小白");
user1.setUserPassword("8888");
User user2=new User();
user2.setUserName("小黑");
user2.setUserPassword("4444");
Role role1=new Role();
role1.setRoleName("保镖");
role1.setRoleMemo("强大的保镖");
Role role2=new Role();
role2.setRoleName("秘书");
role2.setRoleMemo("漂亮的秘书");
Role role3=new Role();
role3.setRoleName("司机");
role3.setRoleMemo("称职的司机");
//(2)
//建立用户和角色对象的关系
//
//在用户实体类中表示角色,在角色实体类中表示用户
//
//具体:
//把角色对象放到用户对象的 Set 集合中
//把用户对象放到角色对象的 Set 集合中
//
//user1 --- role1 / role2
//user2 --- role1 / role3
//
//注意:如果建立了双向的关系,一定要有一方放弃外
//键维护权。如下
user1.getRoleSet().add(role1);
user1.getRoleSet().add(role2);
user2.getRoleSet().add(role1);
user2.getRoleSet().add(role3);
role1.getUserSet().add(user1);
role1.getUserSet().add(user2);
role2.getUserSet().add(user1);
role3.getUserSet().add(user2);
//(3)保存到数据库(级联保存)
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
session.save(role3);
/*
*由于是多对多且进行了双向关联,所以一定要有一方
*放弃外键维护权,否则将无法保存到数据库中
*
*一般由被动方放弃外键维护权,这里角色是被动方
*
*具体做法:
*
*在角色的映射配置文件中的 set标签中添加 inverse
*属性,并将其值设置为 true
*/
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
(2)简化写法
先在用户的映射配置文件中的set 标签添加cascade 属性,并
将其值设置为save-update,再进行具体实现
/**
*多对多级联保存的简化写法
*
*在用户的映射配置文件中的 set标签
*添加 cascade属性,并将其值设置为
* save-update
*/
@Test
publicvoid testSaveX(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//添加两个用户,为每个用户添加两个角色
//(1)
//创建用户和角色对象
User user1=new User();
user1.setUserName("小白");
user1.setUserPassword("8888");
User user2=new User();
user2.setUserName("小黑");
user2.setUserPassword("4444");
Role role1=new Role();
role1.setRoleName("保镖");
role1.setRoleMemo("强大的保镖");
Role role2=new Role();
role2.setRoleName("秘书");
role2.setRoleMemo("漂亮的秘书");
Role role3=new Role();
role3.setRoleName("司机");
role3.setRoleMemo("称职的司机");
//(2)
//建立用户和角色对象的关系
//
//在用户实体类中表示角色
//
//具体:
//把角色对象放到用户对象的 Set 集合中
//
//user1 --- role1 / role2
//user2 --- role1 / role3
user1.getRoleSet().add(role1);
user1.getRoleSet().add(role2);
user2.getRoleSet().add(role1);
user2.getRoleSet().add(role3);
//(3)保存到数据库(级联保存)
session.save(user1);
session.save(user2);
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
(三)多对多级联删除(一般不使用,仅作了解)
如:删除某个用户
先在用户的映射配置文件中的set 标签添加cascade 属性,并
将其值设置为delete,再进行具体实现
/**
*多对多级联删除
*
*简化写法:在用户的映射配置文件中的 set标签
*添加 cascade属性,并将其值设置为 delete
*/
@Test
publicvoid testDelete(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//(1)
//通过 id 查询用户对象
User user=session.get(User.class,1);
//(2)
//调用 Session 的 delete()方法实现级联删除
session.delete(user);
//多对多级联删除,一般不使用,仅作了解即可
//
//注意:此时角色的映射配置文件中的 set 标签
//不能将 inverse 属性设为 true,否则将无法
//删除
//
//另外:set标签也不能将 cascade属性设为
//delete,否则 testSaveX() 方法保存的数据
//将全部删除
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
(四)维护第三张表
通过第三张表来维护多对多关系
如:让某个用户有某个角色
第一步:根据id 查询用户和角色
第二步:把角色对象放到用户对象的Set 集合中
再如:让某个用户没有某个角色
第一步:根据id 查询用户和角色
第二步:从用户对象的 Set 集合中移除角色对象
/**
*维护第三张表
*/
@Test
publicvoid testTable(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//让某个用户有某个角色
//(1)根据 id 查询用户对象和角色对象
User user=session.get(User.class,1);
Role role=session.get(Role.class,3);
//(2)把角色对象放到用户对象的 Set 集合中
user.getRoleSet().add(role);
//让某个用户没有某个角色
//(1)根据 id 查询用户对象和角色对象
User userx=session.get(User.class,1);
Role rolex=session.get(Role.class,1);
//(2)从用户对象的 Set 集合中移除角色对象
userx.getRoleSet().remove(rolex);
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
工程结构目录如下:
HibernateUtils.java:
package com.siwuxie095.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
static Configuration cfg=null;
static SessionFactory sessionFactory=null;
//或:加上 private final 亦可,不过此时不能等于 null
// private static final Configuration cfg;
// private static final SessionFactory sessionFactory;
//静态代码块
static {
//加载核心配置文件
cfg=new Configuration();
cfg.configure();
sessionFactory=cfg.buildSessionFactory();
}
//提供方法返回 sessionFactory
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
//提供方法返回与本地线程绑定的 Session
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
User.java:
package com.siwuxie095.entity;
import java.util.HashSet;
import java.util.Set;
//用户实体类
public class User {
private Integer uid;//用户 id
private String userName;//用户名称
private String userPassword;//用户密码
//在用户实体类中表示多个角色,即一个用户可以有多个角色
//
//Hibernate中要求使用 Set集合表示"多"的数据
private Set<Role> roleSet=new HashSet<Role>();
public Set<Role> getRoleSet() {
return roleSet;
}
publicvoid setRoleSet(Set<Role> roleSet) {
this.roleSet = roleSet;
}
public Integer getUid() {
return uid;
}
publicvoid setUid(Integer uid) {
this.uid = uid;
}
public String getUserName() {
return userName;
}
publicvoid setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
publicvoid setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
}
Role.java:
package com.siwuxie095.entity;
import java.util.HashSet;
import java.util.Set;
//角色实体类
public class Role {
private Integer rid;//角色 id
private String roleName;//角色名称
private String roleMemo;//角色描述
//在角色实体类中表示多个用户,即一个角色可以有多个用户
//
//Hibernate中要求使用 Set集合表示"多"的数据
private Set<User> userSet=new HashSet<User>();
public Set<User> getUserSet() {
return userSet;
}
publicvoid setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Integer getRid() {
return rid;
}
publicvoid setRid(Integer rid) {
this.rid = rid;
}
public String getRoleName() {
return roleName;
}
publicvoid setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleMemo() {
return roleMemo;
}
publicvoid setRoleMemo(String roleMemo) {
this.roleMemo = roleMemo;
}
}
HibernateManyToMany.java:
package com.siwuxie095.hibernatetest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import com.siwuxie095.entity.Role;
import com.siwuxie095.entity.User;
import com.siwuxie095.utils.HibernateUtils;
//多对多操作
public class HibernateManyToMany {
/**
*多对多级联保存的复杂写法
*
*
*手动加上 @Test以进行单元测试(将自动导入 JUnit 4的 jar包)
*
*选中方法名,右键->Run As->JUint Test
*/
@Test
publicvoid testSave(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//添加两个用户,为每个用户添加两个角色
//(1)
//创建用户和角色对象
User user1=new User();
user1.setUserName("小白");
user1.setUserPassword("8888");
User user2=new User();
user2.setUserName("小黑");
user2.setUserPassword("4444");
Role role1=new Role();
role1.setRoleName("保镖");
role1.setRoleMemo("强大的保镖");
Role role2=new Role();
role2.setRoleName("秘书");
role2.setRoleMemo("漂亮的秘书");
Role role3=new Role();
role3.setRoleName("司机");
role3.setRoleMemo("称职的司机");
//(2)
//建立用户和角色对象的关系
//
//在用户实体类中表示角色,在角色实体类中表示用户
//
//具体:
//把角色对象放到用户对象的 Set 集合中
//把用户对象放到角色对象的 Set 集合中
//
//user1 --- role1 / role2
//user2 --- role1 / role3
//
//注意:如果建立了双向的关系,一定要有一方放弃外
//键维护权。如下
user1.getRoleSet().add(role1);
user1.getRoleSet().add(role2);
user2.getRoleSet().add(role1);
user2.getRoleSet().add(role3);
role1.getUserSet().add(user1);
role1.getUserSet().add(user2);
role2.getUserSet().add(user1);
role3.getUserSet().add(user2);
//(3)保存到数据库(级联保存)
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
session.save(role3);
/*
*由于是多对多且进行了双向关联,所以一定要有一方
*放弃外键维护权,否则将无法保存到数据库中
*
*一般由被动方放弃外键维护权,这里角色是被动方
*
*具体做法:
*
*在角色的映射配置文件中的 set标签中添加 inverse
*属性,并将其值设置为 true
*/
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
/**
*多对多级联保存的简化写法
*
*在用户的映射配置文件中的 set标签
*添加 cascade属性,并将其值设置为
* save-update
*/
@Test
publicvoid testSaveX(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//添加两个用户,为每个用户添加两个角色
//(1)
//创建用户和角色对象
User user1=new User();
user1.setUserName("小白");
user1.setUserPassword("8888");
User user2=new User();
user2.setUserName("小黑");
user2.setUserPassword("4444");
Role role1=new Role();
role1.setRoleName("保镖");
role1.setRoleMemo("强大的保镖");
Role role2=new Role();
role2.setRoleName("秘书");
role2.setRoleMemo("漂亮的秘书");
Role role3=new Role();
role3.setRoleName("司机");
role3.setRoleMemo("称职的司机");
//(2)
//建立用户和角色对象的关系
//
//在用户实体类中表示角色
//
//具体:
//把角色对象放到用户对象的 Set 集合中
//
//user1 --- role1 / role2
//user2 --- role1 / role3
user1.getRoleSet().add(role1);
user1.getRoleSet().add(role2);
user2.getRoleSet().add(role1);
user2.getRoleSet().add(role3);
//(3)保存到数据库(级联保存)
session.save(user1);
session.save(user2);
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
/**
*多对多级联删除
*
*简化写法:在用户的映射配置文件中的 set标签
*添加 cascade属性,并将其值设置为 delete
*/
@Test
publicvoid testDelete(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//(1)
//通过 id 查询用户对象
User user=session.get(User.class,1);
//(2)
//调用 Session 的 delete()方法实现级联删除
session.delete(user);
//多对多级联删除,一般不使用,仅作了解即可
//
//注意:此时角色的映射配置文件中的 set 标签
//不能将 inverse 属性设为 true,否则将无法
//删除
//
//另外:set标签也不能将 cascade属性设为
//delete,否则 testSaveX() 方法保存的数据
//将全部删除
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
/**
*维护第三张表
*/
@Test
publicvoid testTable(){
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
//得到 SessionFactory 对象
sessionFactory=HibernateUtils.getSessionFactory();
//创建 Session 对象
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//让某个用户有某个角色
//(1)根据 id 查询用户对象和角色对象
User user=session.get(User.class,1);
Role role=session.get(Role.class,3);
//(2)把角色对象放到用户对象的 Set 集合中
user.getRoleSet().add(role);
//让某个用户没有某个角色
//(1)根据 id 查询用户对象和角色对象
User userx=session.get(User.class,1);
Role rolex=session.get(Role.class,1);
//(2)从用户对象的 Set 集合中移除角色对象
userx.getRoleSet().remove(rolex);
//提交事务
tx.commit();
}catch (Exception e) {
//回滚事务
tx.rollback();
}finally {
//关闭资源
session.close();
sessionFactory.close();
}
}
}
User.hbm.xml:
<?xmlversion="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>
<!--
(1)
class标签:配置实体类和数据库表的对应;
name属性:实体类的全路径,即全限定名;
table属性:数据库表的名称(数据库表由 Hibernate自动生成)
-->
<classname="com.siwuxie095.entity.User"table="t_user">
<!--
(2)
id标签:配置实体类 id和表 id对应(主键);
name属性:实体类里 id属性名称;
column属性:生成表中 id字段名称
-->
<idname="uid"column="uid">
<generatorclass="native"></generator>
</id>
<!--
(3)
property标签:配置其它属性和表中字段对应;
name属性:实体类属性名称;
column属性:生成表中字段名称
-->
<propertyname="userName"column="user_name"></property>
<propertyname="userPassword"column="user_password"></property>
<!--
(4)
set标签:配置关联关系的映射(配置关联对象),代表一个 Set集合;
name属性:关联另一方的对象的 Set集合的名称(在用户实体类中声明);
table属性:第三张表的名称;
cascade属性:save-update表示级联保存,delete表示级联删除(逗号隔开);
inverse属性:true表示放弃关系维护(放弃外键的维护权)(默认为 false)
-->
<setname="roleSet"table="user_role"cascade="delete">
<!--
key标签:配置当前对象(关联一方)在第三张表中的外键
column属性:当前对象(关联一方)在第三张表中的外键名称
-->
<keycolumn="user_id"></key>
<!--
many-to-many标签:配置实体类的多对多关联;
class:关联另一方的类的全路径,即角色实体类的全限定名;
column:关联的另一方在第三张表的外键名称,即角色表在第三张表中的外键名称
-->
<many-to-manyclass="com.siwuxie095.entity.Role"column="role_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
Role.hbm.xml:
<?xmlversion="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>
<classname="com.siwuxie095.entity.Role"table="t_role">
<idname="rid"column="rid">
<generatorclass="native"></generator>
</id>
<propertyname="roleName"column="role_name"></property>
<propertyname="roleMemo"column="role_memo"></property>
<!--
set标签:配置关联关系的映射(配置关联对象),代表一个 Set集合;
name属性:关联另一方的对象的 Set集合的名称(在角色实体类中声明);
table属性:第三张表的名称;
cascade属性:save-update表示级联保存,delete表示级联删除(逗号隔开);
inverse属性:true表示放弃关系维护(放弃外键的维护权)(默认为 false)
-->
<setname="userSet"table="user_role"cascade="save-update"inverse="false">
<!--
key标签:配置当前对象(关联一方)在第三张表中的外键
column属性:当前对象(关联一方)在第三张表中的外键名称
-->
<keycolumn="role_id"></key>
<!--
many-to-many标签:配置实体类的多对多关联;
class:关联另一方的类的全路径,即用户实体类的全限定名;
column:关联的另一方在第三张表的外键名称,即用户表在第三张表中的外键名称
-->
<many-to-manyclass="com.siwuxie095.entity.User"column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml:
<?xmlversion="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>
<!--第一部分:配置数据库信息(必须) -->
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--或使用 jdbc:mysql:///hibernate_db代替,省略 localhost:3306 -->
<propertyname="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_db</property>
<propertyname="hibernate.connection.username">root</property>
<propertyname="hibernate.connection.password">8888</property>
<!--第二部分:配置 Hibernate信息(可选) -->
<!--输出底层 sql语句 -->
<propertyname="hibernate.show_sql">true</property>
<!--输出底层 sql语句格式 -->
<propertyname="hibernate.format_sql">true</property>
<!--
Hibernate帮助创建表,不是自动创建,而需要配置之后。
update:如果已经有表,就更新,如果没有,就自动创建
-->
<propertyname="hibernate.hbm2ddl.auto">update</property>
<!--
配置数据库方言,让 Hibernate 框架识别不同数据库自己特有的语句
如:在 MySQL中实现分页的关键字 limit,只能在 MySQL 中使用,而
在 Oracle中实现分页的关键字则是 rownum
-->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--配置 Session绑定本地线程 -->
<propertyname="hibernate.current_session_context_class">thread</property>
<!--第三部分:引入映射配置文件,把映射配置文件放到核心配置文件(必须) -->
<mappingresource="com/siwuxie095/entity/User.hbm.xml"/>
<mappingresource="com/siwuxie095/entity/Role.hbm.xml"/>
</session-factory>
</hibernate-configuration>
【made by siwuxie095】
- Hibernate多对多操作
- Hibernate多对多操作
- Hibernate多对多操作
- Hibernate一对多,多对多操作
- Hibernate 多对多 删除操作
- Hibernate多对多操作步骤
- hibernate多表操作之多对多
- Hibernate操作多对多关系
- hibernate多对多关系操作
- hibernate多对一的操作解析
- Hibernate之多对多表,操作实例
- hibernate多表操作之一对多的单项操作
- hibernate初学8 多表操作之一对多操作
- Hibernate 多对多 删除操作(many-to-many)续
- hibernate 多对多的增删改操作
- hibernate 多对多的增删改操作
- hibernate中hbm的级联操作(多对多)
- hibernate多表操作之一对多的双向关联
- tensorflow 实现rnn
- 【OpenCV3.3】SVM与字符分类示例
- HDU6077-Time To Get Up
- Python3.x安装numpy和matplotlib的问题
- 2017 暑假艾教集训 day5
- Hibernate多对多操作
- python SyntaxError: non-default argument follows default argument
- HDU.2149 Public Sale (博弈论 巴什博弈)
- Android学习笔记17-自定义控件
- 错误记录——Invalid field value for field "position".
- 获取数据库连接工具类
- 2017百度之星资格赛—1003度度熊与邪恶大魔王
- SQL语句基础模板
- HDU.2147 kiki's game (博弈论 PN分析)