Hibernate Annotation

本文详细介绍了如何使用Hibernate Annotation来映射实体,包括简单的实体PO映射、表名称与字段映射、主键生成策略、各种关系映射(一对一、多对一、一对多、多对多)以及级联(cascade)属性和Fetch策略。通过实例展示了Hibernate Annotation在数据库操作中的应用。
摘要由CSDN通过智能技术生成

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.xmlhibernate配置文件)文件,内容如下

<!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(truetrue) ;

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

4AUTO 写上@GeneratedValue则会默认选择AUTO来生成主键,会根据你的方言来选择数据库提供的自增机制,作为主键的生产策略,如果数据库是MySQL,则使用auto_increment

@Id

@GeneratedValue

//或者@GeneratedValue(strategy=GenerationType.AUTO)

public int getId() { .... }

5IDENTITY 取得最大的ID+1,作为主键

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

public int getId() { .... }

6TABLE 使用hilo(高低位算法,来产生主键)

@Id

@GeneratedValue(strategy=GenerationType.TABLE)

public int getId() { .... }

7SEQUENCE Oracle的自增机制

@Id

@GeneratedValue(strategy=GenerationType.SEQUENCE)

public int getId() { .... }

使用OracleSEQUENCE 的话。他会自动建一张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(truetrue) ;

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(truetrue) ;

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(truetrue) ;

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.ALLOK了,

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、一般使用默认就可以了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值