标签:
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>
<?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>
<?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(); } }
标签:
原文地址:http://blog.csdn.net/cb2474600377/article/details/51094001