【Hibernate】Hibernate框架配置详解
通过Hibernate我们可以方便地操作数据库读取出来的信息,减少了繁琐的JDBC操作。
一般情况下,有两种方式可以进行Hibernate的配置,一种是通过配置文件进行配置,另一种是通过注解进行配置。
我将通过注解简单介绍Hibernate框架的配置。
Hibernate框架的配置一般可以分为以下几个步骤:
1.添加基本的Hibernate Jar包
2.添加注解的Jar包
3.编写Hibernate.cfg.xml文件
4.编写POJO文件,并编写注释
5.编写测试文件,导出到数据库进行测试。
一、导入基本的Hibernate Jar包
点击这里下载:http://pan.baidu.com/s/1gdf3K47 密码:siok
二、导入Hibernate Annotation 的Jar包
点击这里下载:http://pan.baidu.com/s/1gdf3K47 密码:siok
三、编写Hibernate.cfg.xml文件
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 <!-- Generated by MyEclipse Hibernate Tools. --> 7 <hibernate-configuration> 8 9 <session-factory> 10 <!-- 配置JDBC连接属性 --> 11 <property name="myeclipse.connection.profile"> 12 com.mysql.jdbc.Driver 13 </property> 14 <property name="connection.url"> 15 jdbc:mysql://localhost:3306/basehibernate 16 </property> 17 <property name="connection.username">root</property> 18 <property name="connection.password">sa</property> 19 <property name="connection.driver_class"> 20 com.mysql.jdbc.Driver 21 </property> 22 <property name="dialect"> 23 org.hibernate.dialect.MySQLDialect 24 </property> 25 26 <!-- 自动建表 --> 27 <property name="hbm2ddl.auto">auto</property> 28 <property name="connection.autocommit">true</property>
29 <mapping class="com.basehibernate.pojo.Department" /> 30 <mapping class="com.basehibernate.pojo.Employee" /> 31 <mapping class="com.basehibernate.pojo.Meal" /> 32 <mapping class="com.basehibernate.pojo.OrderMeal" /> 33 <mapping class="com.basehibernate.pojo.GradeMeal" /> 34 <mapping class="com.basehibernate.pojo.RewardMeal" /> 35 36 </session-factory> 37 38 </hibernate-configuration>
不同数据库连接在Hibernate.cfg.xml中的配置不同,这里以MySQL为例。
如果你用的是其他数据库,你可以点击这里查看相对应的Hibernate.cfg.xml文件:Hibernate 连接MySQL/SQLServer/Oracle数据库的hibernate.cfg.xml文件
5、编写POJO文件并编写注解
Department类:
1 package com.basehibernate.pojo; 2 3 import java.util.List; 4 5 import javax.persistence.Column; 6 import javax.persistence.Entity; 7 import javax.persistence.GeneratedValue; 8 import javax.persistence.GenerationType; 9 import javax.persistence.Id; 10 import javax.persistence.OneToMany; 11 import javax.persistence.Table; 12 13 /** 14 * 部门类 15 * 时间:2014年5月8日 16:06:54 16 * 修改:2014年6月3日 20:17:27 17 * @author chenyr 18 * 19 */ 20 /* @Entity 表示将这个POJO类作为一个实体解析 21 * @Table表示数据库中的表格, name对应数据库的表明, catalog对应数据库名(可省略) 22 */ 23 @Entity 24 @Table(name = "t_busi_dept", catalog = "basehibernate") 25 public class Department { 26 27 /** 部门编号 **/ 28 private int deptId; 29 30 /** 部门名称 **/ 31 private String deptName; 32 33 /** 部门员工关系 **/ 34 private List<Employee> employees; 35 36 public Department() { 37 super(); 38 // TODO Auto-generated constructor stub 39 } 40 41 public Department(int deptId, String deptName, List<Employee> employees) { 42 super(); 43 this.deptId = deptId; 44 this.deptName = deptName; 45 this.employees = employees; 46 } 47 48 /* 49 * @Id 表示将这个属性作为数据库表的主键 50 * @Column 表示将这个属性作为数据库的一个字段, name属性指定数据库字段名, unique指定是否唯一, nullable指定是否允许为空, length指定字段长度 51 * @GeneratedValue 与@Id一起配合使用,指定主键的生成方式 52 */ 53 @Id 54 @Column(name = "id", unique = true, nullable = false, length = 12) 55 @GeneratedValue( strategy = GenerationType.IDENTITY) 56 public int getDeptId() { 57 return deptId; 58 } 59 60 public void setDeptId(int deptId) { 61 this.deptId = deptId; 62 } 63 64 /* 65 * 普通属性列可以用@Column注解生成为一个普通的字段,也可以不用@Column注解。因为如果一个字段没有注解,那么Hibernate会自动将其作为一个普通的字段 66 * 如果你不想Hibernate自动将这个字段进行处理,那么请用注解 @Transient 将其标注 67 */ 68 public String getDeptName() { 69 return deptName; 70 } 71 72 public void setDeptName(String deptName) { 73 this.deptName = deptName; 74 } 75 76 /* 77 * @OneToMany 一般情况下一对多的关系由多的一方维护,即Department类为被控方 78 * mappedBy 表示由多的一方中与自己关联的属性进行维护,也及由Employee中的dept属性维护 79 * targetEntity 表示与之关联的实体,也即 Employee类,可以省略 80 */ 81 @OneToMany(mappedBy = "dept", targetEntity = Employee.class) 82 public List<Employee> getEmployees() { 83 return employees; 84 } 85 86 public void setEmployees(List<Employee> employees) { 87 this.employees = employees; 88 } 89 }
Employee 类:
1 package com.basehibernate.pojo; 2 3 import java.util.List; 4 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.GenerationType; 8 import javax.persistence.Id; 9 import javax.persistence.JoinColumn; 10 import javax.persistence.JoinTable; 11 import javax.persistence.ManyToOne; 12 import javax.persistence.OneToMany; 13 import javax.persistence.Table; 14 15 /** 16 * 员工类<P> 17 * 时间:2014年5月8日 18:24:46<P> 18 * 修改:2014年6月3日 20:16:57<P> 19 * @author chenyr<P> 20 * 21 */ 22 /* 23 * 更多注释的意义请参照Department类 24 */ 25 @Entity 26 @Table(name = "t_busi_empl", catalog = "basehibernate") 27 public class Employee { 28 29 /** 工号 **/ 30 private int emplId; 31 32 /** 订餐昵称 **/ 33 private String nickname; 34 35 /** 订餐密码 **/ 36 private String password; 37 38 /** 是否启用订餐密码 **/ 39 private boolean pwFlag; 40 41 /** 是否自动订餐 **/ 42 private boolean autoEat; 43 44 /** 员工姓名 **/ 45 private String emplName; 46 47 /** 所属部门 **/ 48 private Department dept; 49 50 public Employee() { 51 } 52 53 @Id 54 @GeneratedValue( strategy = GenerationType.IDENTITY) 55 public int getEmplId() { 56 return emplId; 57 } 58 59 public void setEmplId(int emplId) { 60 this.emplId = emplId; 61 } 62 63 public String getNickname() { 64 return nickname; 65 } 66 67 public void setNickname(String nickname) { 68 this.nickname = nickname; 69 } 70 71 public String getPassword() { 72 return password; 73 } 74 75 public void setPassword(String password) { 76 this.password = password; 77 } 78 79 public boolean isPwFlag() { 80 return pwFlag; 81 } 82 83 public void setPwFlag(boolean pwFlag) { 84 this.pwFlag = pwFlag; 85 } 86 87 public String getEmplName() { 88 return emplName; 89 } 90 91 public void setEmplName(String emplName) { 92 this.emplName = emplName; 93 } 94 95 public boolean isAutoEat() { 96 return autoEat; 97 } 98 99 public void setAutoEat(boolean autoEat) { 100 this.autoEat = autoEat; 101 } 102 103 /* 104 * @ManyToOne 本身类是多的一方,作为主控方,即Employee类为主控方 105 * @JoinTable 表示两者之间的关系在数据库中建成一个新的表 106 * name:表示中间表的名称 107 * joinColumns:建立本类表与中间表的外键关系,即建立员工表与中间表的外键关系 name表示新表中外键的名字 108 * inverseJoinColumns:建立被控方表与中间表的外键关系,即建立部门表与中间表的外键关系 name表示新表中外键的名字 109 */ 110 @ManyToOne() 111 @JoinTable( 112 name = "t_busi_mid_deptempl", 113 joinColumns = @JoinColumn(name = "emplid"), 114 inverseJoinColumns = @JoinColumn(name = "deptid") 115 ) 116 public Department getDept() { 117 return dept; 118 } 119 120 public void setDept(Department dept) { 121 this.dept = dept; 122 } 123 }
如果你想要了解更多的关于Hibernate Annotation的知识,你可以阅读我的另一篇博文:Hibernate Annotation注解详解
五、编写测试文件
编写测试文件,自动生成数据库表:
1 package com.basehibernate.test; 2 3 /** 4 * POJO注解导入数据库测试类 5 * 用于测试Annotation注解的POJO类是否能自动生成数据库表 6 * 时间:2014年6月4日 10:15:06 7 * @author chenyr 8 */ 9 10 import org.hibernate.cfg.AnnotationConfiguration; 11 import org.hibernate.tool.hbm2ddl.SchemaExport; 12 import org.junit.Test; 13 14 15 public class HibernateUtil { 16 17 @Test public void initiateHibernate() 18 { 19 /* 这里必须用AnnotatioinConfiguration类,因为你是用注解配置的,而不是用配置文件配置的 */ 20 AnnotationConfiguration config = new AnnotationConfiguration().configure(); 21 22 SchemaExport export = new SchemaExport(config); 23 export.create(true, true); 24 } 25 }
提示:①Hibernate注解的POJO类里必须要有一个作为主键,否则会出现“identifier not found"的错误。
②如果你使用的是Oracle数据库,因为Oracle数据库不支持主键自增长,必须使用序列实现自增长。你可以使用下面你的代码标注主键:
1 @Id 2 @SequenceGenerator(name = "generator",sequenceName="product_id_seq") 3 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator") 4 public int getId() { 5 return id; 6 }
③如果你执行Junit测试之后,Junit没有报错,但是数据库没有创建对应的表,那可能是因为你没有导入对应的驱动包。
④如果Junit执行成功,但是数据库里只有部分的表。那么请检查POJO类文件的注解是否正确,重点检查类头@Entity @Table 部分的注解,两个POJO类中@Table 注解中的name属性相同会导致这个错误。
连接Oracle时,在@Table注解中加入了catalog属性也会出现这个错误。