Hibernate的一对多实例
一对多在现实生活中很常见,今天做了个Hibernate的一对多的实例,也是个入门过程,写下来跟大家分享。
最重要的是xml配置文件,之前因为把英文"(引号)错误的复制成中文的“”(引号),导致后面编译各种出问题,排查了好久,也百度了各种博客,最后发现是引号的问题。
在现实生活中,部门和员工的关系属于一对多的,一个部门有多个员工,一个员工属于一个部门。
第一步,创建Java工程,名字为HibernateMapping,把Hibernate的jar包和sql server的jar包(或者mysql的jar包)导入进来,并创建Employee,Department实体类和xml配置文件。目录结构和hibernate包如下:
第二步,编辑Employee和Department实体类,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package cn.hibernate.onetomany; 2 3 public class Employee { 4 private int empNo;//工号 5 private String empName;//姓名 6 private Department dep;//部门 7 public int getEmpNo() { 8 return empNo; 9 } 10 public void setEmpNo(int empNo) { 11 this.empNo = empNo; 12 } 13 public String getEmpName() { 14 return empName; 15 } 16 public void setEmpName(String empName) { 17 this.empName = empName; 18 } 19 public Department getDep() { 20 return dep; 21 } 22 public void setDep(Department dep) { 23 this.dep = dep; 24 } 25 public Employee(int empNo, String empName, Department dep) { 26 27 this.empNo = empNo; 28 this.empName = empName; 29 this.dep = dep; 30 } 31 32 public Employee(){ 33 34 } 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package cn.hibernate.onetomany; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class Department { 7 private int depId;//部门号 8 private String depName;//部门名 9 private Set<Employee> emps = new HashSet<Employee>(); 10 public int getDepId() { 11 return depId; 12 } 13 public void setDepId(int depId) { 14 this.depId = depId; 15 } 16 public String getDepName() { 17 return depName; 18 } 19 public void setDepName(String depName) { 20 this.depName = depName; 21 } 22 public Set<Employee> getEmps() { 23 return emps; 24 } 25 public void setEmps(Set<Employee> emps) { 26 this.emps = emps; 27 } 28 29 public Department(int depId, String depName, Set<Employee> emps) { 30 this.depId = depId; 31 this.depName = depName; 32 this.emps = emps; 33 } 34 35 public Department(){ 36 37 } 38 }
两个实体类的代码要注意的是它们要有属性的get和set方法,而且在部门类中有员工的集合,员工类中有部门的属性。
第三步,编辑hibernate的核心配置文件hibernate.cfg.xml,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 6 <hibernate-configuration> 7 <session-factory> 8 9 <property name="hibernate.connection.dialect"> 10 org.hibernate.dialect.SQLServer2005Dialect 11 <!--mysql的方言:org.hibernate.dialect.MySQLDialect--> 12 </property> 13 14 <property name="hibernate.connection.driver_class"> 15 com.microsoft.sqlserver.jdbc.SQLServerDriver 16 <!--mysql的驱动:com.mysql.jdbc.Driver--> 17 </property> 18 19 <property name="hibernate.connection.url"> 20 jdbc:sqlserver://10.86.57.121:1433;DatabaseName=HibernateDemo; 21 <!--mysql的数据库:jdbc:mysql:///hibernate_demo--> 22 </property> 23 24 <property name="hibernate.connection.username">sa<!--mysql的登录名:root --></property> 25 <property name="hibernate.connection.password">123456</property> 26 27 <!-- 28 <property name=“hibernate.show_sql”>true</property> 29 <property name=“hibernate.format_sql”>true</property> 30 <property name=“hibernate.hbm2ddl.auto”>create</property> 31 --> 32 <property name="hibernate.show_sql">true</property> 33 <property name="hibernate.format_sql">true</property> 34 <property name="hibernate.hbm2ddl.auto">update</property> 35 36 <mapping resource="cn/hibernate/onetomany/department.hbm.xml" /> 37 <mapping resource="cn/hibernate/onetomany/employee.hbm.xml"/> 38 </session-factory> 39 </hibernate-configuration>
这个配置文件很重要,我出的各种问题都在这里,比如中文引号和约束文件:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
有的博客写的是http://www.hibernate.org/hibernate-configuration-3.0.dtd什么的,结果导致hibernate无法加载,所以还是用http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd更靠谱
第四步,编辑hibernate的映射文件,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping> 7 <class name="cn.hibernate.onetomany.Employee" table="t_emp"> 8 <id name="empNo" column="empNo"> 9 <generator class="native"></generator> 10 </id> 11 12 <property name="empName"></property> 13 <!-- name是一的一方的属性,即在Employee.java中定义的private Department那个变量 14 column是外键,这个要跟另一个映射文件的外键一致 15 --> 16 <many-to-one name="dep" column="dep_emp_id" class="cn.hibernate.onetomany.Department"></many-to-one> 17 </class> 18 </hibernate-mapping>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping> 7 <class name="cn.hibernate.onetomany.Department" table="t_dep"> 8 <id name="depId" column="depId" type="int"> 9 <generator class="native"></generator> 10 </id> 11 12 <property name="depName"></property> 13 <!-- name是多的一方的属性,即在Department.java中定义的private Set<Employee>那个变量 --> 14 <set name="emps"> 15 <!-- column是外键,和另一个映射文件的外键对应 --> 16 <key column="dep_emp_id"></key> 17 <one-to-many class="cn.hibernate.onetomany.Employee"/> 18 </set> 19 </class> 20 </hibernate-mapping>
这两个配置文件也很重要,而且比较难理解,一定要注意谁是多的一方,谁是一的一方
第五步,编写测试程序MainTest.java,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package cn.hibernate.onetomany; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.Transaction; 6 import org.hibernate.cfg.Configuration; 7 import org.junit.Test; 8 9 public class MainTest { 10 @Test 11 public void test(){ 12 Configuration cfg = new Configuration().configure(); 13 SessionFactory factory = cfg.buildSessionFactory(); 14 Session session = null; 15 16 session = factory.openSession(); 17 Transaction tx = session.beginTransaction(); 18 19 Department dep = new Department(); 20 dep.setDepName("Waijiao"); 21 Employee em1 = new Employee(); 22 Employee em2 = new Employee(); 23 em1.setEmpName("Wangyi"); 24 em2.setEmpName("Huachunying"); 25 26 dep.getEmps().add(em1); 27 dep.getEmps().add(em2); 28 em1.setDep(dep); 29 em2.setDep(dep); 30 31 session.save(dep); 32 session.save(em1); 33 session.save(em2); 34 35 System.out.println("Add Success!"); 36 tx.commit(); 37 } 38 }
这个是测试,也可以写成main主函数,但是那样要有捕获异常以及事务回滚等操作。
最后,Run as JUnit Test,再查看数据库,新建了t_dep和t_emp表,查询两个表的结果,都已经更新完成。
外交部,里面有我们酷酷的王毅部长和亲爱的华春莹,中国必强~
欢迎大家留言讨论