用一个简单的例子,来记一下,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、一般使用默认就可以了
相关推荐
4. 创建实体类:定义与数据库表对应的Java类,使用Hibernate的注解(如@Entity、@Table、@Id等)进行ORM映射。 5. 定义DAO:创建数据访问对象(DAO)接口,包含CRUD操作。这些接口通常由Spring管理,通过代理模式...
这个"springmvc+hibernate注解框架整合 demo"是一个示例项目,展示了如何通过注解方式将这两个框架无缝集成。 **Spring MVC 框架** Spring MVC 是 Spring 框架的一部分,它提供了处理HTTP请求、转发响应以及管理...
【标题】"HibernateDemo"是一个基于Java的开源对象关系映射框架示例,它用于简化数据库操作。这个压缩包提供了一个简单的入门项目,帮助初学者理解如何使用Hibernate框架。通过这个例子,我们可以深入学习Hibernate...
这个 "springMvc+hibernate Demo" 压缩包文件很可能是为了展示如何将这两个框架整合在一起,创建一个完整的数据驱动的 Web 应用。 **Spring MVC 框架** Spring MVC 是 Spring 框架的一部分,设计用于构建可维护、松...
在本示例中,我们探讨的是一个基于...总之,这个“spring3.2 hibernate4 demo CRUD”实例提供了一个完整的、实战性的学习平台,帮助开发者快速上手Spring和Hibernate的整合,理解如何在Java Web开发中有效地管理数据。
【hibernate+maven demo项目工程】是一个基于Hibernate ORM框架和Maven构建工具的示例项目,旨在帮助开发者理解和实践如何在实际开发中整合这两项技术。该项目的主要目的是展示如何利用Maven管理依赖,以及如何配置...
在这个“Springmvc+hibernate整合Demo”中,我们将会探讨如何将这两个框架结合在一起,以创建一个功能丰富的客户关系管理(CRM)系统。 **Spring MVC 框架** Spring MVC 是 Spring 框架的一部分,提供了一个用于...
- **约束注解**: Hibernate Validator 提供了一系列的预定义注解,如 `@NotNull`、`@Size`、`@Pattern` 等,用于在字段上声明验证规则。 - **验证器**: 验证器是执行验证逻辑的组件,它会根据注解上的规则检查对象的...
标题"spring+hibernate整合demo"表明这是一个示例项目,展示了如何将Spring和Hibernate这两个框架结合使用。整合Spring和Hibernate可以使应用程序更易于管理,因为Spring可以控制Hibernate的生命周期,并提供事务...
这个"spring+hibernate框架demo"提供了一个整合这两个框架的小项目,便于初学者理解和学习。 Spring 框架: 1. **依赖注入**:Spring 的核心特性之一,它允许通过配置文件或注解来管理对象及其依赖关系,降低了组件...
1. **实体(Entity)**: 在Hibernate中,实体通常对应数据库中的表,它们是Java类,通过注解或XML配置与数据库表进行映射。 2. **对象关系映射(ORM)**: Hibernate 提供了ORM工具,将Java对象与数据库表之间的映射...
这个“springMVC+hibernate搭建的一个demo”旨在为初学者提供一个快速入门的实例,帮助他们理解和配置这些技术的集成环境。 SpringMVC是Spring框架的一部分,它提供了处理HTTP请求、管理控制器、数据绑定、视图解析...
总结起来,"hibernate基础demo"是一个关于如何使用Hibernate框架的教程,特别是通过注解的方式来简化数据库操作。它涵盖了Hibernate的基本配置、实体类的注解映射、会话工厂和会话的使用、以及查询和事务管理等核心...
《Hibernate注解详解》 Hibernate 是一款强大的Java对象关系映射(ORM)框架,它极大地简化了数据库操作。在Hibernate中,注解是用于描述Java类及其属性如何映射到数据库表的重要工具。本文将全面解析Hibernate中的...
在“hibernate框架demo”项目中,开发者可能已经创建了一个简单的Java应用,演示了如何使用Hibernate进行数据操作。通过查看源代码,你可以学习到如何配置SessionFactory,如何创建和管理Session,以及如何执行基本...
在本项目中,"hibernateDemo.rar" 是一个压缩包,包含了一个使用Spring Boot、JPA、Hibernate和Redis构建的示例应用。这个项目旨在展示如何整合这些技术来实现高效的数据存储和缓存管理。以下是对每个组件的详细解释...
本文将深入探讨如何结合 Spring 的注解配置与 Hibernate 实现数据持久化,通过一个实际的 demo 示例来阐述整个过程。 首先,Spring 框架以其依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented ...
这个“hibernateSearch+demo”项目提供了一个实战示例,帮助开发者理解并应用 Hibernate Search 的核心概念和功能。 在 Hibernate Search 中,主要涉及以下关键知识点: 1. **全文索引**:Hibernate Search 使用 ...
【hibernate的demo】 在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。本demo旨在提供一个基本的Hibernate使用示例,帮助理解其核心概念和功能。 一、Hibernate概述 ...