本教程每节课都附带源码,强烈大家建议配合源码学习。
本节源码:http://download.youkuaiyun.com/detail/e421083458/5253687
在开始新课之前先讲一下:创建测试专用Source Folder进行测试。
1.新建Source Folder名称为test2.创建package=com.bjsxt.hiberante
3.创建测试脚本:
HibernateQLTest.java
package com.bjsxt.hiberante;
import java.util.Date;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.Session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.bjsxt.hibernate.Category;
import com.bjsxt.hibernate.Gender;
import com.bjsxt.hibernate.Student;
import com.bjsxt.hibernate.StudentPK;
import com.bjsxt.hibernate.TTeacher;
import com.bjsxt.hibernate.TTeacherPK;
import com.bjsxt.hibernate.Teacher;
public class HibernateQLTest {
private static SessionFactory sf;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("BeforeClass");
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("AfterClass");
sf.close();
}
}
没错,我们将重复操作的步骤放到了方法中。这样测试效率更高了!:>
注意:我们观察hibernate生成表的结构并不是为了将来就用它生成,(可能还有自己的扩展,比如index等)而是为了明白我们应该建立什么样的表和实体类映射
下面只讲实体类,映射自己添加!
自增主键映射:
package com.bjsxt.hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Category {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试方法:
@Test
public void testSave(){
Session session = sf.openSession();
session.beginTransaction();
for(int i=0;i<10;i++){
Category c = new Category();
c.setName("c"+i);
session.save(c);
}
session.getTransaction().commit();
session.close();
System.out.println("yes!!!");
}
uuid作为主键
package com.bjsxt.hibernate;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "_teacher")
public class Teacher {
private String id;
private String name;
private String title;
private String yourWifeName;
private Date birthDate;
@Id
@GeneratedValue(generator="teacherUUID")
@GenericGenerator(name="teacherUUID", strategy="uuid")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
测试方法:
@Test
public void testTeacher(){
Session session = sf.openSession();
session.beginTransaction();
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("middle");
t.setYourWifeName("up");
t.setBirthDate(new Date());
session.save(t);
session.getTransaction().commit();
session.close();
}
联合主键XML方式
package com.bjsxt.hibernate;
public class Student {
private StudentPK pk;
private String sex;
private boolean good;
public StudentPK getPk() {
return pk;
}
public void setPk(StudentPK pk) {
this.pk = pk;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
}
package com.bjsxt.hibernate;
import java.io.Serializable;
public class StudentPK implements Serializable {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o){
if(o instanceof StudentPK){
StudentPK pk = (StudentPK) o;
if(this.id == pk.getId()&&this.name.equals(pk.getName())){
return true;
}
}
return false;
}
@Override
public int hashCode(){
return this.name.hashCode();
}
}
关联文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Student" table="__student">
<composite-id name="pk" class="com.bjsxt.hibernate.StudentPK">
<key-property name="id"></key-property>
<key-property name="name"></key-property>
</composite-id>
<property name="sex" />
<property name="good" type="yes_no"></property>
</class>
</hibernate-mapping>
测试方法:
@Test
public void testStudent(){
Session session = sf.openSession();
session.beginTransaction();
StudentPK pk = new StudentPK();
pk.setId(1);
pk.setName("zhangsan");
Student t = new Student();
t.setPk(pk);
t.setSex("man");
t.setGood(false);
session.save(t);
session.getTransaction().commit();
session.close();
}
联合主键Annotation方式
package com.bjsxt.hibernate;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
@Entity
public class TTeacher {
private TTeacherPK ttpk;
private String title;
private String yourWifeName;
private Date birthDate;
private boolean good=true;
private Gender gender;
@Id
public TTeacherPK getTtpk() {
return ttpk;
}
public void setTtpk(TTeacherPK ttpk) {
this.ttpk = ttpk;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
@Enumerated(EnumType.STRING)
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
}
TTeacherPK.java
package com.bjsxt.hibernate;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class TTeacherPK implements Serializable {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o){
if(o instanceof StudentPK){
StudentPK pk = (StudentPK) o;
if(this.id == pk.getId()&&this.name.equals(pk.getName())){
return true;
}
}
return false;
}
@Override
public int hashCode(){
return this.name.hashCode();
}
}
测试方法:
@Test
public void testTTeacher(){
Session session = sf.openSession();
session.beginTransaction();
TTeacherPK ttpk = new TTeacherPK();
ttpk.setId(1);
ttpk.setName("name");
TTeacher tt = new TTeacher();
tt.setTtpk(ttpk);
tt.setBirthDate(new Date());
tt.setGender(Gender.MALE);
tt.setGood(true);
tt.setTitle("title");
tt.setYourWifeName("wife");
session.save(tt);
session.getTransaction().commit();
session.close();
}
当然Annotaion的方式有2种,如果大家有兴趣可以研究一下!
总结:
1.xml生成id
<id name="id" >
<generator class="native"></generator>
</id>
常用四个:native identity sequence uuid(跨平台 native uuid)
2.注解方式:
自定义ID
@GeneratedValue
表示的意思为AUTO_INCREMENT(直接写相当如native)
默认:对 MySQL,使用auto_increment
对 Oracle使用hibernate_sequence(名称固定)
IDENTITY(@GeneratedValue(strategy=GenerationType.IDENTITY))
SEQUENCE(@GeneratedValue(strategy=GenerationType.SEQUENCE))
@SequenceGenerator(可自定义在数据库生成指定的sequence名)
@Id
//在@GeneratedValue中增加 generator="teacherSEQ"
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
//"teacherSEQ"为@SequenceGenerator的标识名
//"teacherSEQ_DB"为指定到数据库生成的Sequence名
@SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")
public int getId() {
return id;
}
TABLE (使用附加表作为主键的方式)
@TableGenerator
@TableGenerator(name="teacherID",
table="teacherID_DB",
pkColumnName="key_value",
pkColumnValue="pk_value",
valueColumnName="teacher",
allocationSize=1)
如果使用注解方式的uuid 如下:
@Id
@GeneratedValue(generator="teacherUUID")
@GenericGenerator(name="teacherUUID", strategy="uuid")
3.FAQ;
用Junit测试时Hibernate Session Factory初始化异常不提示.疑似一个bug
用main来做测试
比如:
public static void main(String args[]){
sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
StudentPK pk = new StudentPK();
pk.setId(1);
pk.setName("zhangsan");
Student t = new Student();
t.setPk(pk);
t.setSex("man");
t.setGood(false);
session.save(t);
session.getTransaction().commit();
session.close();
sf.close();
}
field [age] not found on com.bjsxt.hibernate.Student
4.联合主键
4.1 Xml方式: composite-id
将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除 并新加入属性“StudentPK”)
public class StudentPK implements Serializable {
private String id;
private String name;
新建pojo类必须实现 java.io.Serializable 序列化接口
新pojo类要重写equals和hashCode方法
@Override
public boolean equals(Object o) {
if(o instanceof StudentPk) {
StudentPk pk = (StudentPk)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
联合主键生成策略XML配置方法
<hibernate-mapping>
<class name="com.bjsxt.pojo.Student" >
<composite-id name="studentPK" class="com.bjsxt.pojo.StudentPK">
<key-property name="id"></key-property>
<key-property name="name"></key-property>
</composite-id>
<property name="age" />
<property name="sex" />
<property name="good" type="yes_no"></property>
</class>
</hibernate-mapping>
4.2 Annotation
前三步与Xml方式前三步一样 都要建立新pojo类 都要实现Serializable接口 重写equals和hashCode方法.
方法1在新类前写@Embeddable,在原pojo类的新属性“TercherPK”的get方法前写@ld,如下
@ Embeddable
public class TeacherPK implements Serializable {
private String id;
private String name;
@Entity
public class Teacher {
private TeacherPK teacherPK ;
@Id
public TeacherPK getTeacherPK() {
return teacherPK;
}
方法2:@EmbeddedlD(*) 新pojo类无需加注解,只需在原pojo类新属性“TercherPK”的get方法前写@EmbeddedlD即可
方法3:@ld @IdClass(*) 新pojo类无需加注解,原pojo类的id,name属性保留不变,也无需新增“TercherPK”属性。 只在id,name的get方法前都加@Id,并在原pojo类前加“@IdClass(TeacherPK).class)”,如下
@Entity
@IdClass(TeacherPK.class)
public class Teacher {
private String id;
private String name;
@Id
public String getId() {
return id;
}
@Id
public String getName() {
return name;
}