Hibernate Annotation
使用hibernate Annotation来映射实体
准备工作
下载
hibernate-distribution-3.3.2.GA
hibernate-annotations-3.4.0.GA
slf4j
导入相关依赖包
Hibernate HOME:
/hibernate3.jar
/lib/bytecode(二进制)
/lib/optional(可选的)
/lib/required(必须的)
导入required下的所有jar包
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate3.jar
javassist-3.9.0.GA.jar
jta-1.1.jar
slf4j-api-1.5.10.jar
slf4j-log4j12-1.5.10.jar
log4j-1.2.14.jar
mysql.jar
---Annotation包
ejb3-persistence.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
简单的例子,通过annotation注解来映射实体PO
1、建立(Java Project)项目:hibernate_0100_annotation_HelloWorld_default
2、在项目根下建立lib目录
a) 导入相关依赖jar包
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
ejb3-persistence.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate3.jar
javassist-3.9.0.GA.jar
jta-1.1.jar
log4j-1.2.14.jar
mysql.jar
slf4j-api-1.5.10.jar
slf4j-log4j12-1.5.10.jar
3、建立PO持久化类 cn.serup.model.Teacher 内容如下
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.Id;
//@Entity表示该是实体类 @Entity public class Teacher {
private int id ;
private String username ;
private String password ;
//ID为主键,主键手动分配 @Id public int getId() { return id; }
public void setId(int id) { this.id = id; }
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; }
}
|
4、在src目录中建立hibernate.cfg.xml(hibernate配置文件)文件,内容如下
<!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="connection.url">jdbc:mysql://localhost/hibernate</property> <property name="connection.username">root</property> <property name="connection.password">saber</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property>
<!-- 独立线程运行,如果通过getCurrentSession()来获得Session,需要设置如下 --> <property name="current_session_context_class">thread</property>
<!-- 映射持久化类 --> <mapping class="cn.serup.model.Teacher" />
</session-factory> </hibernate-configuration> |
5.、建立新的源码包test
a) 编写单元测试,结构如下cn.serup.hibernate.test.TeacherTest 内容如下:
package cn.serup.hibernate.test;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Teacher;
public class TeacherTest {
private static SessionFactory sessionFactory ;
@Test public void testSaveTeacher() { Teacher t = new Teacher() ; t.setId(2) ; t.setUsername("努尔哈赤") ; t.setPassword("12345") ;
Session session = sessionFactory.getCurrentSession() ;
session.beginTransaction() ;
session.save(t) ;
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() {
new SchemaExport(new AnnotationConfiguration().configure()).create(true, true) ;
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
Annotation表名称与字段映射,长度
1、项目:hibernate_0200_annotation_column
2、表名称映射,在默认情况下使用@Entity,则使用类名做为表名
3、所有的注解写在get()方法上面
4、表名映射
a) @Table(name="t_teacher")
3、字段映射
a) 默认情况下,则使用属性名称来作为列名(字段名)
b) 在get()方法上写注解
i. @Column(name="t_username")
ii. 长度
iii. @Column(name="t_username",length=35)
c) 默认情况下会讲所有的属性映射到表中,如果不想某个属性映射到表中,如下编写
i. @Transient(瞬时、临时(或者透明))
Annotation映射主键属性(ID生成策略)
1、项目:hibernate_0300_annotation_ID
2、使用@Id注解可以将实体bean中的某个属性定义为标识符(identifier),该属性的值可以通过应用自身进行设置(ID手动分配,但不能重复)
3、(EJB3规范)也可以通过Hiberante生成(推荐). 使用 @GeneratedValue注解可以定义该标识符的生成策略:
· AUTO - 可以是identity column类型,或者sequence类型或者table类型,取决于不同 的底层数据库.
· TABLE - 使用表保存id值
· IDENTITY - identity column
· SEQUENCE - sequence
AUTO相当于XML映射文件中的Native
4、AUTO ,写上@GeneratedValue则会默认选择AUTO来生成主键,会根据你的方言来选择数据库提供的自增机制,作为主键的生产策略,如果数据库是MySQL,则使用auto_increment
@Id @GeneratedValue //或者@GeneratedValue(strategy=GenerationType.AUTO) public int getId() { .... } |
5、IDENTITY 取得最大的ID值+1,作为主键
@Id @GeneratedValue(strategy=GenerationType.IDENTITY) public int getId() { .... } |
6、TABLE 使用hilo(高低位算法,来产生主键)
@Id @GeneratedValue(strategy=GenerationType.TABLE) public int getId() { .... } |
7、SEQUENCE Oracle的自增机制
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) public int getId() { .... } |
使用Oracle的SEQUENCE 的话。他会自动建一张SEQUENCE 表,默认表名hibernate_sequence
如果想改SEQUENCE 表名的话。如下编写
@SequenceGenerator(name="aa",sequenceName="teacherSEQ_DB") public class Teacher { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="aa") public int getId() { ... } } |
说明:
@SequenceGenerator(name="aa",sequenceName="teacherSEQ_DB")
Name为引用名称sequenceName为表名称
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="aa")
使用类SEQUENCE为主键生成策略,更改表名,使用generator="aa"引用类上定义好的aa
Annotation关系映射
1、一对一外键关联映射(单向)
2、一对一外键关联映射(双向)
3、一对一主键关联映射(不重要)在这不演示
在实际中很少用,使用注解@PrimaryKeyJoinColumn
意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用
注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML
映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。
因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了
4、多对一关联映射
5、一对多关联映射(单向)
6、一对多关联映射(双向)
7、多对多关联映射(单向)
8、多对多关联映射(双向)
一对一外键关联映射(单向)
1、项目:hibernate_0400_annotation_one2one_fk_1
2、建立PO
a) cn.serup.model.Body
b) cn.serup.model.Heart
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne;
@Entity public class Body {
private int id ;
private String bodyName ;
private Heart heart ;
public String getBodyName() { return bodyName; }
@OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="bodyid",unique=true) //一对一外键关联,使用@OneToOne,并设置了级联操作 //@JoinColum设置了外键的名称为bodyid如果不设置,则默认为heart_id //外键的值是唯一的(unique),不可重复,与Heart的主键一直 public Heart getHeart() { return heart; }
@Id @GeneratedValue public int getId() { return id; }
public void setBodyName(String bodyName) { this.bodyName = bodyName; }
public void setHeart(Heart heart) { this.heart = heart; }
public void setId(int id) { this.id = id; } }
|
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;
@Entity public class Heart {
private int id ;
private String heartName ;
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getHeartName() { return heartName; }
public void setHeartName(String heartName) { this.heartName = heartName; }
}
|
编写单元测试cn.serup.hibernate.test.One2One_1
package cn.serup.hibernate.test;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Body; import cn.serup.model.Heart;
public class One2One_1 {
private static SessionFactory sessionFactory ;
@Test public void testSaveTeacher() { Heart h = new Heart() ; h.setHeartName("h2") ;
Body b = new Body() ; b.setBodyName("b2") ; b.setHeart(h) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ; session.save(h) ; session.save(b) ; session.beginTransaction().commit() ; }
@Test public void testLoadOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ; Body b = (Body) session.get(Body.class, 1) ; System.out.println(b.getId() +" "+b.getBodyName());
Heart h = b.getHeart() ; System.out.println(h.getId() +" "+h.getHeartName());
session.beginTransaction().commit() ; }
@Test public void testDeleteOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Body b = (Body) session.get(Body.class, 1) ;
session.delete(b) ;
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { new SchemaExport(new AnnotationConfiguration().configure()) .create(true, true) ;
sessionFactory = new AnnotationConfiguration().configure() .buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
一对一双向关联关系:hibernate_0500_annotation_one2one_fk_2
改动Heart对象
package cn.serup.model;
import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne;
@Entity public class Heart {
private int id ;
private String heartName ;
private Body body ;
@OneToOne(mappedBy="heart",cascade=CascadeType.ALL) //一对一双向关联关系,使用@OneToOne //注意:需要加上mappedBy="heart",如果不加上的话, //Heart也会生成一个外键(body_id) //mapped="heart"需要指向与他关联对象的一个属性 //说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的 //主体端负责维护联接列 //对于不需要维护这种关系的从表则通过mappedBy属性进行声明 //mappedBy的值指向主体的关联属性 //规律:只有是双向关联关系,都加上mapped //cascade=CascadeType.ALL级联 public Body getBody() { return body; }
public void setBody(Body body) { this.body = body; }
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getHeartName() { return heartName; }
public void setHeartName(String heartName) { this.heartName = heartName; }
}
|
测试,从Heart中加载Body
@Test public void testLoadOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Heart h = (Heart) session.load(Heart.class, 1) ; System.out.println(h.getId() +" "+h.getHeartName());
Body b = h.getBody() ; System.out.println(b.getId()+ " " +b.getBodyName());
session.beginTransaction().commit() ; } |
多对一关联映射
1、项目:hibernate_0700_annotation_many2one
2、建立PO
a) cn.serup.model.Organization
b) cn.serup.model.Company
c) 多个公司对应一个组织机构
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;
@Entity public class Organization {
private int id ;
private String orgName ;
public String getOrgName() { return orgName; }
public void setOrgName(String orgName) { this.orgName = orgName; }
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
}
|
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne;
@Entity public class Company {
private int id ;
private String compayName ;
private Organization org ;
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getCompayName() { return compayName; }
public void setCompayName(String compayName) { this.compayName = compayName; }
@ManyToOne(targetEntity=Organization.class) @JoinColumn(name="orgid") //多对一注解@ManyToOne //targetEntity指定了关联对象 //@JoinColumn(name="orgid")指定生产的外键的字段名,默认是org_id public Organization getOrg() { return org; }
public void setOrg(Organization org) { this.org = org; }
}
|
单元测试
package cn.serup.hibernate.test;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Organization; import cn.serup.model.Company;
public class Many2One {
private static SessionFactory sessionFactory ;
@Test public void testSaveOne2One() { Organization o = new Organization() ; o.setOrgName("谷度培训机构") ;
Company c = new Company() ; c.setCompayName("广州分公司") ; c.setOrg(o) ;
Company c1 = new Company() ; c1.setCompayName("成都分公司") ; c1.setOrg(o) ;
Company c2 = new Company() ; c2.setCompayName("天津分公司") ; c2.setOrg(o) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
session.save(o) ; session.save(c) ; session.save(c1) ; session.save(c2) ;
session.beginTransaction().commit() ; }
@Test public void testLoadOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Company c = (Company)session.load(Company.class,1) ;
System.out.println(c.getCompayName()+"org:"+c.getOrg().getOrgName());
session.beginTransaction().commit() ; }
@Test public void testDeleteOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Company c = (Company) session.load(Company.class, 1) ;
session.delete(c) ;
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { //new SchemaExport(new AnnotationConfiguration().configure()) //.create(true, true) ;
sessionFactory = new AnnotationConfiguration().configure() .buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
一对多关联映射(单向)
1、项目:hibernate_0800_annotation_one2many_1
2、建立PO
a) cn.serup.model.Organization
b) cn.serup.model.Company
package cn.serup.model;
import java.util.Set;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany;
@Entity public class Organization {
private int id ;
private String orgName ;
private Set<Company> company ;
@OneToMany @JoinColumn(name="orgid") /** * 一对多注解@OneToMany(单向) * 如果只写@OneToMany的话,hibernate会建一张中间表来 * 维护他们之间的关系, * 加上@JoinColumn(name="orgid"),则不会建中间表,他会在 * 多的一端加上外键orgid,来维护他们之间的关系 */ public Set<Company> getCompany() { return company; }
@Id @GeneratedValue public int getId() { return id; }
public String getOrgName() { return orgName; }
public void setCompany(Set<Company> company) { this.company = company; }
public void setId(int id) { this.id = id; }
public void setOrgName(String orgName) { this.orgName = orgName; } }
|
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;
@Entity public class Company {
private int id ;
private String compayName ;
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getCompayName() { return compayName; }
public void setCompayName(String compayName) { this.compayName = compayName; } }
|
编写单元测试
package cn.serup.hibernate.test;
import java.util.HashSet; import java.util.Iterator; import java.util.Set;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Company; import cn.serup.model.Organization;
public class Many2One {
private static SessionFactory sessionFactory ;
@SuppressWarnings("unchecked") @Test public void testSaveOne2One() { Organization o = new Organization() ; o.setOrgName("谷度培训机构") ;
Company c = new Company() ; c.setCompayName("广州分公司") ;
Company c1 = new Company() ; c1.setCompayName("成都分公司") ;
Company c2 = new Company() ; c2.setCompayName("天津分公司") ;
Set set = new HashSet() ; set.add(c) ; set.add(c1) ; set.add(c2) ;
o.setCompany(set) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
session.save(o) ; session.save(c) ; session.save(c1) ; session.save(c2) ;
session.beginTransaction().commit() ; }
@SuppressWarnings("unchecked") @Test public void testLoadOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Organization o = (Organization)session.load(Organization.class, 1) ;
System.out.println(o.getId()+" "+o.getOrgName()) ;
Set list = o.getCompany() ;
for(Iterator it = list.iterator(); it.hasNext();) { Company c = (Company)it.next() ; System.out.println(c.getId()+" "+c.getCompayName()); }
session.beginTransaction().commit() ; }
@Test public void testDeleteOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
//Company c = (Company) session.load(Company.class, 1) ;
//session.delete(c) ;
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { new SchemaExport(new AnnotationConfiguration().configure()) .create(true, true) ;
sessionFactory = new AnnotationConfiguration().configure() .buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
一对多关联映射(双向)
1、建立项目:hibernate_0900_annotation_one2many_2
2、建立PO
a) cn.serup.model.Organization
b) cn.serup.model.Company
package cn.serup.model;
import java.util.Set;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany;
@Entity public class Organization {
private int id ;
private String orgName ;
private Set<Company> company ;
@OneToMany(mappedBy="org") @JoinColumn(name="orgid") /** * 一对多双向,在一的一端中设置mappedBy * 说明多的一端为主导 * 如果指定了外键字段名称,则多的一端也需要指定相同的字段名称 */ public Set<Company> getCompany() { return company; }
public void setCompany(Set<Company> company) { this.company = company; }
public String getOrgName() { return orgName; }
public void setOrgName(String orgName) { this.orgName = orgName; }
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
}
|
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne;
@Entity public class Company {
private int id ;
private String compayName ;
private Organization org ;
@ManyToOne @JoinColumn(name="orgid") /** * 一对多双向 * 需要指定外键与一的一端给的外键名称一致,@JoinColumn(name="orgid") * 也可以不指定,如果在多的一端不指定,则一的一端也不能指定 * 否则为生成两个外键 */ public Organization getOrg() { return org; }
public void setOrg(Organization org) { this.org = org; }
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getCompayName() { return compayName; }
public void setCompayName(String compayName) { this.compayName = compayName; }
}
|
编写单元测试
package cn.serup.hibernate.test;
import java.util.Iterator; import java.util.Set;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Company; import cn.serup.model.Organization;
public class Many2One {
private static SessionFactory sessionFactory ;
@Test public void testSaveOne2One() { Organization o = new Organization() ; o.setOrgName("谷度培训机构") ;
Company c = new Company() ; c.setCompayName("广州分公司") ; c.setOrg(o) ;
Company c1 = new Company() ; c1.setCompayName("成都分公司") ; c1.setOrg(o) ;
Company c2 = new Company() ; c2.setCompayName("天津分公司") ; c2.setOrg(o) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
session.save(o) ; session.save(c) ; session.save(c1) ; session.save(c2) ;
session.beginTransaction().commit() ; }
@SuppressWarnings("unchecked") @Test public void testLoadOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
Organization o = (Organization)session.load(Organization.class, 1) ;
System.out.println(o.getId()+" "+o.getOrgName()) ;
Set set = o.getCompany() ;
for(Iterator it = set.iterator(); it.hasNext();) { Company c = (Company)it.next() ; System.out.println(c.getId()+" "+c.getCompayName()); }
session.beginTransaction().commit() ; }
@Test public void testDeleteOne2One() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction() ;
//Company c = (Company) session.load(Company.class, 1) ;
//session.delete(c) ;
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { new SchemaExport(new AnnotationConfiguration().configure()) .create(true, true) ;
sessionFactory = new AnnotationConfiguration().configure() .buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
多对多关联映射(单向)
1、建立项目:hibernate_1000_annotation_many2many_1
2、建立PO
a) cn.serup.model.User
b) cn.serup.model.Role
package cn.serup.model;
import java.util.HashSet; import java.util.Set;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany;
@Entity public class User {
private int id ;
private String username ;
private Set<Role> role = new HashSet<Role>() ;
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
@ManyToMany /** * 多对多映射:注解@ManyToMany(单向) * 默认情况下,hibernate会自动的创建一张中间表, * 来维护多对多关系 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id * 如果想更换表名和字段名称,注解如下: */ @JoinTable(name="t_u_r", joinColumns={@JoinColumn(name="u_id")}, inverseJoinColumns={@JoinColumn(name="r_id")} ) public Set<Role> getRole() { return role; }
public void setRole(Set<Role> role) { this.role = role; }
}
|
package cn.serup.model;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;
@Entity public class Role {
private int id ;
private String roleName ;
/*private Set<User> user = new HashSet<User>() ;
@ManyToMany public Set<User> getUser() { return user; }
public void setUser(Set<User> user) { this.user = user; }*/
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
}
|
编写单元测试
package cn.serup.hibernate.test;
import java.util.HashSet; import java.util.Iterator; import java.util.Set;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Role; import cn.serup.model.User;
public class Many2ManyTest {
private static SessionFactory sessionFactory = null ;
@Test public void testSaveUR() { Role r1 = new Role() ; r1.setRoleName("项目组长") ;
Role r3 = new Role() ; r3.setRoleName("项目经理") ;
Role r2 = new Role() ; r2.setRoleName("技术总监") ;
User u1 = new User() ; u1.setUsername("唐骏") ;
User u2 = new User() ; u2.setUsername("李开复") ;
User u3 = new User() ; u3.setUsername("柳传志") ;
Set<Role> s1 = new HashSet<Role>() ; s1.add(r1) ; s1.add(r3) ;
Set<Role> s2 = new HashSet<Role>() ; s2.add(r1) ; s2.add(r2) ;
Set<Role> s3 = new HashSet<Role>() ; s3.add(r1) ; s3.add(r2) ; s3.add(r3) ;
u1.setRole(s1) ; u2.setRole(s2) ; u3.setRole(s3) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction().begin() ;
session.save(r1) ; session.save(r2) ; session.save(r3) ;
session.save(u1) ; session.save(u2) ; session.save(u3) ;
session.beginTransaction().commit() ; }
@Test public void testLoadUR() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction().begin() ;
User u = (User) session.get(User.class,3) ;
System.out.println("用户:"+u.getUsername()) ;
Set<Role> s1 = u.getRole() ; System.out.print("拥有职务:"); for(Iterator<Role> it = s1.iterator(); it.hasNext();) { Role r = (Role) it.next() ; System.out.print("/t【"+r.getRoleName()+"】"); }
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
多对多关联映射(双向)
3、建立项目:hibernate_1000_annotation_many2many_2
4、建立PO
a) cn.serup.model.User
b) cn.serup.model.Role
package cn.serup.model;
import java.util.HashSet; import java.util.Set;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany;
@Entity public class User {
private int id ;
private String username ;
private Set<Role> role = new HashSet<Role>() ;
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
@ManyToMany /** * 多对多映射:注解@ManyToMany(单向) * 默认情况下,hibernate会自动的创建一张中间表, * 来维护多对多关系 * 默认中间表的名称 :user_role中间表,字段的名称user_id role_id * 如果想更换表名和字段名称,注解如下: */ @JoinTable(name="t_u_r", joinColumns={@JoinColumn(name="u_id")}, inverseJoinColumns={@JoinColumn(name="r_id")} ) /** * @JoinTable(name="t_u_r", * 指定中间表的表名 * joinColumns={@JoinColumn(name="u_id")}, * 指定当前对象的外键 * inverseJoinColumns={@JoinColumn(name="r_id")} * 指定关联对象的外键 */
public Set<Role> getRole() { return role; }
public void setRole(Set<Role> role) { this.role = role; }
}
|
package cn.serup.model;
import java.util.HashSet; import java.util.Set;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany;
@Entity public class Role {
private int id ;
private String roleName ;
private Set<User> user = new HashSet<User>() ;
@ManyToMany(mappedBy="role") /** * 多对多,双向关联映射 */ public Set<User> getUser() { return user; }
public void setUser(Set<User> user) { this.user = user; }
@Id @GeneratedValue public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getRoleName() { return roleName; }
public void setRoleName(String roleName) { this.roleName = roleName; }
}
|
编写单元测试
package cn.serup.hibernate.test;
import java.util.HashSet; import java.util.Iterator; import java.util.Set;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;
import cn.serup.model.Role; import cn.serup.model.User;
public class Many2ManyTest {
private static SessionFactory sessionFactory = null ;
public void testSaveUR() { Role r1 = new Role() ; r1.setRoleName("项目组长") ;
Role r3 = new Role() ; r3.setRoleName("项目经理") ;
Role r2 = new Role() ; r2.setRoleName("技术总监") ;
User u1 = new User() ; u1.setUsername("唐骏") ;
User u2 = new User() ; u2.setUsername("李开复") ;
User u3 = new User() ; u3.setUsername("柳传志") ;
Set<Role> s1 = new HashSet<Role>() ; s1.add(r1) ; s1.add(r3) ;
Set<Role> s2 = new HashSet<Role>() ; s2.add(r1) ; s2.add(r2) ;
Set<Role> s3 = new HashSet<Role>() ; s3.add(r1) ; s3.add(r2) ; s3.add(r3) ;
u1.setRole(s1) ; u2.setRole(s2) ; u3.setRole(s3) ;
Session session = sessionFactory.getCurrentSession() ; session.beginTransaction().begin() ;
session.save(r1) ; session.save(r2) ; session.save(r3) ;
session.save(u1) ; session.save(u2) ; session.save(u3) ;
session.beginTransaction().commit() ; }
@Test public void testLoadUR() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction().begin() ;
User u = (User) session.get(User.class,3) ;
System.out.println("用户:"+u.getUsername()) ;
Set<Role> s1 = u.getRole() ; System.out.print("拥有职务:"); for(Iterator<Role> it = s1.iterator(); it.hasNext();) { Role r = (Role) it.next() ; System.out.print("/t【"+r.getRoleName()+"】"); }
session.beginTransaction().commit() ; }
@Test public void testLoadRU() { Session session = sessionFactory.getCurrentSession() ; session.beginTransaction().begin() ;
Role r = (Role) session.get(Role.class,1) ;
System.out.println("职务:"+r.getRoleName()) ;
Set<User> s1 = r.getUser() ; System.out.print("谁拥有该职务:"); for(Iterator<User> it = s1.iterator(); it.hasNext();) { User u = (User) it.next() ; System.out.print("/t【"+u.getUsername()+"】"); }
session.beginTransaction().commit() ; }
@BeforeClass public static void beforeClass() { sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory() ; }
@AfterClass public static void afterClass() { sessionFactory.close() ; }
}
|
级联(cascade)属性
1、CascadeType.ALL(包括增、删、改、查,联动操作),其实查不算在内,查Fetch
2、CascadeType.MERGE(合并的join)--不重要
3、CascadeType.PERSIST(保存的时候在级联)
4、CascadeType.REFRESH(刷新说明:比如现在我查询出了数据,另外一个人在我查询数据之后,他对数据做了修改,这是才会级联上,hibernate会自动刷新我查询出来的数据)
5、CascadeType.REMOVE (只要在删除操作时才会级联)
6、我们一般都只设置CascadeType.ALL就OK了,
7、Cascade不是必须的,他的作用只是可以让我们快速的开发,我们也可以通过手动增、删、改、查
Fetch捉取策略
1、FetchType.EAGER(渴望的,希望马上得到)
a) 一对多关系,比如通过get()方法来get出一的一端,他之后会出一条SQL语句,不会自动去查询多的一端,如果设置FetchType.EAGER,会讲他的关联对象查询出来
b) 如果是load的话,他不会发出SQL语句,因为load支持延迟加载,只有真正获取数据时才会发SQL
2、FetchType.LAZY(懒加载)
a) 只有真正获取数据时才发出SQL语句
3、默认是:FetchType.LAZY(一对多)
4、默认是:FetchType.EAGER(多对一)
5、一般使用默认就可以了