用一个简单的例子,来记一下,hibernate的部分注解的使用和配置。我这里还是举出一些最常见的,如单向和双向的一对多,单向和双向的多对多。新建个Java工程,做测试类来说明,我打算这样干。
首先是单向的一对多,代码如下,先是两个实体类:
- 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() ;
- }
- }
最后是hibernate的cfg.xml配置,代码如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.password">123456</property>
- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <property name="show_sql">true</property>
- <!-- 独立线程运行,如果通过getCurrentSession()来获得Session,需要设置如下 -->
- <property name="current_session_context_class">thread</property>
- <!-- <property name="hibernate.hbm2ddl.auto">create</property> -->
- <!-- 映射持久化类 -->
- <mapping class="cn.serup.model.Company"/>
- <mapping class="cn.serup.model.Organization"/>
- </session-factory>
- </hibernate-configuration>
以上则是单向的一对多,即company里有organization的对象,organization里没有其他关联对象。
下面就是双向的一对多,即company里有organization的对象,organization里有company的set。只需要修改上面的代码即可,实体类代码如下(就是修改一点点就可以了):
- 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;
- }
- }
单向的多对多的测试代码如下,至于hibernate的cfg.xml就不用变了:
- 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() ;
- }
- }
以上则是单向和双向的一对多的配置与测试。下面是单向和双向的多对多的配置和测试。
------------------------------------------------------------------------------------------------------------------------------------
单向的多对多,实体类代码如下:
- 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() ;
- }
- }
接下来是双向的多对多,实体类代码如下:
- 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中间表,字段的名称u_id r_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() ;
- }
- }
以上,就是双向的多对多的配置和测试。还有的,就是一些别的属性的配置,如级联啊,fetch策略之类的。
级联(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、一般使用默认就可以了