您的位置:首页 > 其它

hibernate多对多关系配置--增删改查

2016-04-08 10:19 351 查看
hibernate多对多关联配置--并实现增删改查
hibernate就不多介绍了,这里就直接上我项目中使用的例子做说明。
数据模型



这是项目中用户和用户组的数据模型er图草稿,具体的model对象字段就以项目中的为主了。
model类以及pojo接口,这里pojo接口用不上,大家测试的时候也可以去掉
package com.supre.model;
import java.io.Serializable;
import java.util.Set;

public class User {

private int userId;
private String userNo;
private String userName;
private String password;
private String telephone;
private String remark;
private int userStatus;
private Set<Group> groups;

public User() {
super();
// TODO Auto-generated constructor stub
}

public User(int userId, String userNo) {
super();
this.userId = userId;
this.userNo = userNo;
}

public User(int userId, String userNo, String userName, String password,
String telephone, String remark, int userStatus, Set<Group> groups) {
super();
this.userId = userId;
this.userNo = userNo;
this.userName = userName;
this.password = password;
this.telephone = telephone;
this.remark = remark;
this.userStatus = userStatus;
this.groups = groups;
}

public int getUserId() {
return userId;
}

public void setUserId(int userId) {
this.userId = userId;
}

public String getUserNo() {
return userNo;
}

public void setUserNo(String userNo) {
this.userNo = userNo;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getTelephone() {
return telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public int getUserStatus() {
return userStatus;
}

public void setUserStatus(int userStatus) {
this.userStatus = userStatus;
}

public Set<Group> getGroups() {
return groups;
}

public void setGroups(Set<Group> groups) {
this.groups = groups;
}

@Override
public String toString() {
return "User [userId=" + userId + ", userNo=" + userNo + ", userName="
+ userName + ", password=" + password + ", telephone="
+ telephone + ", remark=" + remark + ", userStatus="
+ userStatus + ", groupSize=" + groups.size() + "]";
}

}


package com.supre.model;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;

public class Group{

private int groupId;
private String groupName;
private Date createTime;
private String remark;
//private User user;   //负责人
private Set<User> users;

public Group() {
super();
// TODO Auto-generated constructor stub
}

public int getGroupId() {
return groupId;
}

public void setGroupId(int groupId) {
this.groupId = groupId;
}

public String getGroupName() {
return groupName;
}

public void setGroupName(String groupName) {
this.groupName = groupName;
}

public Date getCreateTime() {
return createTime;
}

public void setCreateTime(Date createTime) {
this.createTime = createTime;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public Set<User> getUsers() {
return users;
}

public void setUsers(Set<User> users) {
this.users = users;
}

public Group(int groupId, String groupName, Date createTime, String remark,
Set<User> users) {
super();
this.groupId = groupId;
this.groupName = groupName;
this.createTime = createTime;
this.remark = remark;
this.users = users;
}

@Override
public String toString() {
return "Group [groupId=" + groupId + ", groupName=" + groupName
+ ", createTime=" + createTime + ", remark=" + remark
+ ", userSize=" + users.size() + "]";
}

}


hibernate的配置信息
这里项目中使用的xml配置 hibernate主配置文件:hibernate.xml 配置数据库连接信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/idisk?useUnicode=true&characterEncoding=utf-8</property>
<property name="connection.username">root</property>
<property name="connection.password">supre2015</property>
<property name="show_sql">true</property>

<mapping resource="hibernate/user.hbm.xml"/>
<mapping resource="hibernate/group.hbm.xml"/>
</session-factory>
</hibernate-configuration>


Model类User的映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.supre.model">
<class name="User" table="tb_user">
<id name="userId" column="user_id">
<generator class="native"></generator>
</id>
<property name="userNo" column="user_no"></property>
<property name="userName" column="user_name"></property>
<property name="password" column="password"></property>
<property name="telephone" column="telephone"></property>
<property name="remark" column="remark"></property>
<property name="userStatus" column="user_status"></property>
<set name="groups" table="user_group" inverse="true" cascade="none" lazy="false">
<key column="user_id"></key>
<many-to-many class="Group" column="group_id" ></many-to-many>
</set>
</class>
</hibernate-mapping>


Model类Group的映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.supre.model">
<class name="Group" table="tb_group">
<id name="groupId" column="group_id">
<generator class="native"></generator>
</id>
<property name="groupName" column="group_name"></property>
<property name="createTime" column="create_time"></property>
<property name="remark" column="remark"></property>
<!-- <many-to-one name="user" class="User" column="user_id" lazy="false"></many-to-one> -->
<set name="users" table="user_group" inverse="false" cascade="none" lazy="false">
<key column="group_id"></key>
<many-to-many class="User" column="user_id" lazy="false"></many-to-many>
</set>
</class>
</hibernate-mapping>


hibernate的帮助类
package com.supre.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateSessionFactory {

private static SessionFactory factory;
private static Configuration cfg;
private static ThreadLocal<Session> local = new ThreadLocal<Session>();

static {
cfg = new Configuration().configure("hibernate.xml");
factory = cfg.buildSessionFactory();
}

public static void buildSessionFactory() {
cfg = new Configuration().configure("hibernate.xml");
factory = cfg.buildSessionFactory();
}
private HibernateSessionFactory(){};

public static SessionFactory getSessionFactory(){
return factory;
}
public static Session getSession(){
Session session=local.get();
if(session==null || !session.isOpen()){
if(factory==null){
buildSessionFactory();
}
session = factory.openSession();
local.set(session);
}
return session;
}
public  static void closeSession(){
Session session=local.get();
if(session!=null && session.isOpen()){
session.close();
}
local.set(null);
}
}


下面是测试类,

package com.supre.util;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;

import com.supre.model.Group;
import com.supre.model.User;

public class TestHibernate {

public static void main(String[] args) {
//		testAddGroup();
//		testAddUser();
//		testAddGroup2();
//		testAddUser2();
//		testAddUser3();
//		testSelect();
//		testDeleteUser();
testDeleteGroup();
}

//测试添加简单主控方对象(Group)
public static void testAddGroup(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
Group g = new Group();
g.setGroupName("分组1");
s.save(g);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

//测试添加简单被控方对象(User)
public static void testAddUser(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
User u = new User();
u.setUserName("用户1");
s.save(u);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

//测试添加主控方对象(Group)以及对应关系
/**
* 如果主控方(group.hbm.xml)
* 配置cascade=‘save-update’,则在下述结果中会修改被控方(User)数据
* 配置cascade=‘none’,则在下述结果不会修改被控方(User)数据
*/
public static void testAddGroup2(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
User u = new User();
u.setUserId(3);//数据库中已有的用户id
User u1 = new User();
u1.setUserId(4);//数据库中已有的用户id
Group g = new Group();
g.setGroupName("分组4");
Set<User> us = new HashSet<>();
us.add(u);
us.add(u1);
g.setUsers(us);
s.save(g);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

//测试添加被控方对象(User)以及对应关系
/**
*这里被控方和主控方都配置cascade="none"
*
* 如下代码中,无法实现将关系添加到user_group表中,
* 相反会删掉g和g1在user_group中的全部关系,
* 因为g和g1中的users全部为空的
*/
public static void testAddUser2(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
User u = new User();
u.setUserName("用户4");
Group g = new Group();
g.setGroupId(6);//数据库中已有的用户id
Group g1 = new Group();
g1.setGroupId(8);//数据库中已有的用户id
Set<Group> gs = new HashSet<>();
gs.add(g);
gs.add(g1);
u.setGroups(gs);
s.save(u);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

//测试添加被控方对象(User)以及对应关系
/**
* 这里被控方和主控方都配置cascade="none"
*
* 因为Group是主控方(维护关系方),在添加或者修改关系时,
* 必须由Group方来控制,下面代码中的1和2两处是必须的,
* 如果没有下面1和2两行代码,则只会简单的添加User数据,
* 不写将关系写到user_group表中
*/
public static void testAddUser3(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
User u = new User();
u.setUserName("用户8");
Group g = (Group) s.get(Group.class, 9);
Group g1 = (Group) s.get(Group.class, 10);
Set<Group> gs = new HashSet<>();
g.getUsers().add(u); // ----1
g1.getUsers().add(u); // -----2
gs.add(g);
gs.add(g1);
u.setGroups(gs);
s.save(u);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

/**
* update和save方法大致一样,不过要注意主控方(Group)执行update方法前,
* 必须先将原Group中的users取到,再进行修改,这样才能保证修改时能准确的维护关系
* 如果是修改关系,则通过修改Group中的users来修改关系
*/
public static void testUpdate(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
Group g = (Group) s.get(Group.class, 9);
g.setGroupName("管理员");
//g.getUsers().remove(new User(7, ""));
s.save(g);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

/**
*  这里被控方和主控方都配置cascade="none"
*  如果主控方group.hbm.xml中配置的cascade="delete"或者cascade="all"
*  则删除的时候会级联删除掉User
*/
public static void testDeleteGroup(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
//删除指定的User以及关系
Group g = (Group) s.get(Group.class, 9);
User u = (User) s.get(User.class, 7);
g.getUsers().remove(u);//删除关系需要先把users中的相应的user移除掉
s.delete(g);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

/**
*  这里被控方和主控方都配置cascade="none"
* 	这里如果需要删除关系还是需要先获得主控方,通过主控方来维护关系
*/
public static void testDeleteUser(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
//删除指定的User以及关系
User u = (User) s.get(User.class, 12);
Set<Group> gs = u.getGroups();
for (Group g : gs) {
g.getUsers().remove(u); //如果需要删除关系就需要此操作
}
s.delete(u);
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}

/**
* 这里查询不分主控方和被控方
* 配置查询加载方式
* 	lazy="false" 不使用懒加载,查询时直接加载关联数据
*  lazy="true" 支持懒加载,只有在用到关联数据时再去执行查询
*  支持懒加载需要注意:在用到关联数据时只能在一个事务内(即一个数据库session内)
*  如果事务外使用到该数据,程序则会报数据库连接异常,因为在事务外执行查询时,session已经关闭。
* 这里要根据自己项目中需要来采取最佳配置
*/
public static void testSelect(){
Session s = HibernateSessionFactory.getSession();
s.beginTransaction();
List<Group> gs = s.createQuery("from Group").list();
for (Group g : gs) {
/**
* 这里还需要注意,这里打印对象时不能使用默认的toString()方法
* 因为默认的toString()方法中对Set集合的处理是直接调用Set集合中每个对象的toString()
* 如果Group对象中有User值,则在会出现Group.toString() 中调用Set中的 User.toString()
* 而User.toString()中则会掉用Set中的Group.toString()方法,而出现死循环而导致内存溢出异常
*/
System.out.println(g);//
}
Set<User> us = gs.get(3).getUsers();
for (User user : us) {
System.out.println(user);
}
List<User> users = s.createQuery("from User").list();
for (User u : users) {
System.out.println(u);
}
s.flush();
s.getTransaction().commit();
s.clear();
s.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: