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】

原创粉丝点击