hibernate4,manytomany
接着上一篇的博文,来说说manytomany,这里运用到的场景如:一个老师对应多个学生,一学生对应多个老师;系统应用有多个功能菜单,可以对应多个用户。详细贴代码:
import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name="T_User") public class Users implements Serializable { /** * 主键Id */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int userId; /** * 用户名 */ @Column(name="username") private String userName; /** * 年龄 */ @Column(name="age") private int age;
//其他的get,set方法已省掉。 //用户对应功能url /** * 多对多 ,这里配置延迟加载,cascade最好的情况不要写all,影响性能,大家可以看看他里面的值,就知道对应的意思
* joinColumns / inverseJoinColuments 不要写反了, 不然会报找不到另外一张表不存在,还有就是 中间表 t_userFunTree创建外键约束时候,要选择进行更新和删除操作要级联,而不是约束。 */ @ManyToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY) @JoinTable(name="t_userFunTree", joinColumns={@JoinColumn(name="funId")}, inverseJoinColumns={@JoinColumn(name="userId")}) private Set<FunTree> funTree; public Set<FunTree> getFunTree() { return funTree; } public void setFunTree(Set<FunTree> funTree) { this.funTree = funTree; }
功能树节点类:类结构很简单,只为演示manytomany的效果
package com.ecoinfo.teaching.vo; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name="T_FunTree") public class FunTree { /** * 主键Id */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int funId; /** * 用户名 */ @Column private String nodeName; /** * 功能url */ @Column private String functionUrl; /** * 备注 */ @Column private String remark; /** * 父节点 */ @Column private int parentId; //同样省略掉get/set方法 //每个功能树funTree也对应多个user @ManyToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY) private Set<Users> users; public Set<Users> getUsers() { return users; } public void setUsers(Set<Users> users) { this.users = users; } }
Test测试类代码:
import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Repository; import com.ecoinfo.teaching.dao.FunTreeDao; import com.ecoinfo.teaching.dao.UserDao; import com.ecoinfo.teaching.vo.Article; import com.ecoinfo.teaching.vo.FunTree; import com.ecoinfo.teaching.vo.Player; import com.ecoinfo.teaching.vo.Team; import com.ecoinfo.teaching.vo.Users; import com.sun.mail.handlers.text_xml; /** * 测试保存一对多 多对多 * @author a * */ @Repository public class TestSaveObj { //注解 @Autowired private FunTreeDao funTreeDao; @Autowired private UserDao userDao; public void setFunTreeDao(FunTreeDao funTreeDao) { this.funTreeDao = funTreeDao; } public void setUsrDao(UserDao userDao) { this.userDao = userDao; } /** * 模拟数据 * @param args */ public static void main(String[] args) {
//spring-context.xml配置文件的jdbc配置文件时在src包下 ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml"); SessionFactory sessionFactory = (SessionFactory) context.getBean("sessionFactory"); Session session = sessionFactory.openSession(); session.beginTransaction(); System.out.println("程序开始执行......."); //manytomany //addByManyToMany(session); //updateByManyToMany(session); deleteByManyToMany(session); //getByManyToMany(session); session.close(); System.out.println("程序结束执行......."); } public static void addByManyToMany(Session session){ Users user = new Users(); user.setUserName("addUser"); user.setAge(28); FunTree f1 = new FunTree(); f1.setFunctionUrl("/addChild1"); f1.setNodeName("addNodeName1_hce"); f1.setRemark("addRemark1-jk"); f1.setParentId(4); FunTree f2 = new FunTree(); f2.setFunctionUrl("/addChild2_jjd"); f2.setNodeName("addNodeName2_upa"); f2.setRemark("addRemark2_rr"); f2.setParentId(4); Set<FunTree> funTreeSet = new HashSet<FunTree>(); funTreeSet.add(f1); funTreeSet.add(f2); user.setFunTree(funTreeSet); session.save(user); session.getTransaction().commit(); } public static void updateByManyToMany(Session session){ Users users = (Users) session.get(Users.class, 1); users.setUserName("nmae111"); //添加users对应集合项 到中间件表中 FunTree f1 = new FunTree(); FunTree f2 = new FunTree(); f1=(FunTree) session.get(FunTree.class, 2); f1.setFunctionUrl("/test"); f2=(FunTree) session.get(FunTree.class, 3); // f1.setFunId(2); // f2.setFunId(3); Set<FunTree> funTreeSet = new HashSet<FunTree>(); funTreeSet.add(f1); funTreeSet.add(f2); users.setFunTree(funTreeSet); session.update(users); session.getTransaction().commit(); } public static void deleteByManyToMany(Session session){ Users user = (Users) session.get(Users.class, 1); //可获得查询对象的内容 System.out.println("userName:"+user.getUserName()); System.out.println("对应funTree集合:"+user.getFunTree().size()); //删除操作 session.delete(user); session.getTransaction().commit(); } public static void getByManyToMany(Session session){ Users user = (Users) session.get(Users.class, 1); //可获得查询对象的内容 System.out.println("userName:"+user.getUserName()); System.out.println("对应funTree集合:"+user.getFunTree().size()); Iterator<FunTree> it = user.getFunTree().iterator(); while(it.hasNext()){ FunTree funTree = (FunTree)it.next(); System.out.println(funTree.getNodeName()); } } }
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd" default-autowire="byName"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jdbc.properties</value><!--jdbc配置文件 在src路径下--> </list> </property> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="10" /> <property name="initialSize" value="10" /> <property name="maxActive" value="100" /> </bean> <!-- 配置SessionFactory,由Spring自动根据数据源创建SessionFactory对象 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${jdbc.dialect}</prop> <prop key="hiberante.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> </props> </property> <property name="packagesToScan"> <list> <value>com.ecoinfo.teaching.vo</value> </list> </property> </bean> <!-- 事物配置 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 扫描并自动装配 --> <context:component-scan base-package="com.teaching.service.impl" /> <context:component-scan base-package="com.teaching.dao.impl" /> <context:component-scan base-package="com.teaching.controller" /> </beans>
表结构代码:
CREATE TABLE `t_user` ( `userId` int(11) NOT NULL auto_increment, `username` varchar(255) default NULL, `age` int(11) default NULL, PRIMARY KEY (`userId`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk; CREATE TABLE `t_funtree` ( `funId` int(11) NOT NULL auto_increment, `nodename` varchar(255) default NULL, `functionurl` varchar(255) default NULL, `remark` varchar(255) default NULL, `parentid` int(11) default NULL, PRIMARY KEY (`funId`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk; CREATE TABLE `t_userfuntree` ( `userId` int(11) default NULL, `funId` int(11) default NULL, KEY `pk_uft_funId` (`funId`), KEY `pk_uft_userId` (`userId`), CONSTRAINT `pk_uft_userId` FOREIGN KEY (`userId`) REFERENCES `t_user` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `pk_uft_funId` FOREIGN KEY (`funId`) REFERENCES `t_funtree` (`funId`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=gbk;