用一个简单的例子,来记一下,hibernate的部分注解的使用和配置。我这里还是举出一些最常见的,如单向和双向的一对多,单向和双向的多对多。新建个Java工程,做测试类来说明,我打算这样干。
首先是单向的一对多,代码如下,先是两个实体类:
- packagecn.serup.model;
- importjava.util.Set;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.JoinColumn;
- importjavax.persistence.OneToMany;
- @Entity
- publicclassOrganization{
- privateintid;
- privateStringorgName;
- privateSet<Company>company;
- @OneToMany
- @JoinColumn(name="orgid")
- /**
- *一对多注解@OneToMany(单向)
- *如果只写@OneToMany的话,hibernate会建一张中间表来
- *维护他们之间的关系,
- *加上@JoinColumn(name="orgid"),则不会建中间表,他会在
- *多的一端加上外键orgid,来维护他们之间的关系
- */
- publicSet<Company>getCompany(){
- returncompany;
- }
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicStringgetOrgName(){
- returnorgName;
- }
- publicvoidsetCompany(Set<Company>company){
- this.company=company;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicvoidsetOrgName(StringorgName){
- this.orgName=orgName;
- }
- }
- packagecn.serup.model;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- @Entity
- publicclassCompany{
- privateintid;
- privateStringcompayName;
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetCompayName(){
- returncompayName;
- }
- publicvoidsetCompayName(StringcompayName){
- this.compayName=compayName;
- }
- }
然后,测试类代码如下:
- packagecn.serup.hibernate.test;
- importjava.util.HashSet;
- importjava.util.Iterator;
- importjava.util.Set;
- importorg.hibernate.Session;
- importorg.hibernate.SessionFactory;
- importorg.hibernate.cfg.AnnotationConfiguration;
- importorg.hibernate.tool.hbm2ddl.SchemaExport;
- importorg.junit.AfterClass;
- importorg.junit.BeforeClass;
- importorg.junit.Test;
- importcn.serup.model.Company;
- importcn.serup.model.Organization;
- publicclassMany2One{
- privatestaticSessionFactorysessionFactory;
- @SuppressWarnings("unchecked")
- @Test
- publicvoidtestSaveOne2One(){
- Organizationo=newOrganization();
- o.setOrgName("谷度培训机构");
- Companyc=newCompany();
- c.setCompayName("广州分公司");
- Companyc1=newCompany();
- c1.setCompayName("成都分公司");
- Companyc2=newCompany();
- c2.setCompayName("天津分公司");
- Setset=newHashSet();
- set.add(c);
- set.add(c1);
- set.add(c2);
- o.setCompany(set);
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- session.save(o);
- session.save(c);
- session.save(c1);
- session.save(c2);
- session.beginTransaction().commit();
- }
- @SuppressWarnings("unchecked")
- @Test
- publicvoidtestLoadOne2One(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- Organizationo=(Organization)session.load(Organization.class,1);
- System.out.println(o.getId()+""+o.getOrgName());
- Setlist=o.getCompany();
- for(Iteratorit=list.iterator();it.hasNext();){
- Companyc=(Company)it.next();
- System.out.println(c.getId()+""+c.getCompayName());
- }
- session.beginTransaction().commit();
- }
- @Test
- publicvoidtestDeleteOne2One(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- //Companyc=(Company)session.load(Company.class,1);
- //session.delete(c);
- session.beginTransaction().commit();
- }
- @BeforeClass
- publicstaticvoidbeforeClass(){
- newSchemaExport(newAnnotationConfiguration().configure())
- .create(true,true);
- sessionFactory=newAnnotationConfiguration().configure()
- .buildSessionFactory();
- }
- @AfterClass
- publicstaticvoidafterClass(){
- sessionFactory.close();
- }
- }
最后是hibernate的cfg.xml配置,代码如下:
- <?xmlversion="1.0"encoding="UTF-8"?>
- <!DOCTYPEhibernate-configurationPUBLIC
- "-//Hibernate/HibernateConfigurationDTD3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <propertyname="hibernate.connection.password">123456</property>
- <propertyname="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
- <propertyname="hibernate.connection.username">root</property>
- <propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <propertyname="show_sql">true</property>
- <!--独立线程运行,如果通过getCurrentSession()来获得Session,需要设置如下-->
- <propertyname="current_session_context_class">thread</property>
- <!--<propertyname="hibernate.hbm2ddl.auto">create</property>-->
- <!--映射持久化类-->
- <mappingclass="cn.serup.model.Company"/>
- <mappingclass="cn.serup.model.Organization"/>
- </session-factory>
- </hibernate-configuration>
以上则是单向的一对多,即company里有organization的对象,organization里没有其他关联对象。
下面就是双向的一对多,即company里有organization的对象,organization里有company的set。只需要修改上面的代码即可,实体类代码如下(就是修改一点点就可以了):
- packagecn.serup.model;
- importjava.util.Set;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.JoinColumn;
- importjavax.persistence.OneToMany;
- @Entity
- publicclassOrganization{
- privateintid;
- privateStringorgName;
- privateSet<Company>company;
- @OneToMany(mappedBy="org")
- @JoinColumn(name="orgid")
- /**
- *一对多双向,在一的一端中设置mappedBy
- *说明多的一端为主导
- *如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
- */
- publicSet<Company>getCompany(){
- returncompany;
- }
- publicvoidsetCompany(Set<Company>company){
- this.company=company;
- }
- publicStringgetOrgName(){
- returnorgName;
- }
- publicvoidsetOrgName(StringorgName){
- this.orgName=orgName;
- }
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- }
- packagecn.serup.model;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.JoinColumn;
- importjavax.persistence.ManyToOne;
- @Entity
- publicclassCompany{
- privateintid;
- privateStringcompayName;
- privateOrganizationorg;
- @ManyToOne
- @JoinColumn(name="orgid")
- /**
- *一对多双向
- *需要指定外键与一的一端给的外键名称一致,@JoinColumn(name="orgid")
- *也可以不指定,如果在多的一端不指定,则一的一端也不能指定
- *否则为生成两个外键
- */
- publicOrganizationgetOrg(){
- returnorg;
- }
- publicvoidsetOrg(Organizationorg){
- this.org=org;
- }
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetCompayName(){
- returncompayName;
- }
- publicvoidsetCompayName(StringcompayName){
- this.compayName=compayName;
- }
- }
单向的多对多的测试代码如下,至于hibernate的cfg.xml就不用变了:
- packagecn.serup.hibernate.test;
- importjava.util.Iterator;
- importjava.util.Set;
- importorg.hibernate.Session;
- importorg.hibernate.SessionFactory;
- importorg.hibernate.cfg.AnnotationConfiguration;
- importorg.hibernate.tool.hbm2ddl.SchemaExport;
- importorg.junit.AfterClass;
- importorg.junit.BeforeClass;
- importorg.junit.Test;
- importcn.serup.model.Company;
- importcn.serup.model.Organization;
- publicclassMany2One{
- privatestaticSessionFactorysessionFactory;
- @Test
- publicvoidtestSaveOne2One(){
- Organizationo=newOrganization();
- o.setOrgName("谷度培训机构");
- Companyc=newCompany();
- c.setCompayName("广州分公司");
- c.setOrg(o);
- Companyc1=newCompany();
- c1.setCompayName("成都分公司");
- c1.setOrg(o);
- Companyc2=newCompany();
- c2.setCompayName("天津分公司");
- c2.setOrg(o);
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- session.save(o);
- session.save(c);
- session.save(c1);
- session.save(c2);
- session.beginTransaction().commit();
- }
- @SuppressWarnings("unchecked")
- @Test
- publicvoidtestLoadOne2One(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- Organizationo=(Organization)session.load(Organization.class,1);
- System.out.println(o.getId()+""+o.getOrgName());
- Setset=o.getCompany();
- for(Iteratorit=set.iterator();it.hasNext();){
- Companyc=(Company)it.next();
- System.out.println(c.getId()+""+c.getCompayName());
- }
- session.beginTransaction().commit();
- }
- @Test
- publicvoidtestDeleteOne2One(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction();
- //Companyc=(Company)session.load(Company.class,1);
- //session.delete(c);
- session.beginTransaction().commit();
- }
- @BeforeClass
- publicstaticvoidbeforeClass(){
- newSchemaExport(newAnnotationConfiguration().configure())
- .create(true,true);
- sessionFactory=newAnnotationConfiguration().configure()
- .buildSessionFactory();
- }
- @AfterClass
- publicstaticvoidafterClass(){
- sessionFactory.close();
- }
- }
以上则是单向和双向的一对多的配置与测试。下面是单向和双向的多对多的配置和测试。
------------------------------------------------------------------------------------------------------------------------------------
单向的多对多,实体类代码如下:
- packagecn.serup.model;
- importjava.util.HashSet;
- importjava.util.Set;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.JoinColumn;
- importjavax.persistence.JoinTable;
- importjavax.persistence.ManyToMany;
- @Entity
- publicclassUser{
- privateintid;
- privateStringusername;
- privateSet<Role>role=newHashSet<Role>();
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetUsername(){
- returnusername;
- }
- publicvoidsetUsername(Stringusername){
- this.username=username;
- }
- @ManyToMany
- /**
- *多对多映射:注解@ManyToMany(单向)
- *默认情况下,hibernate会自动的创建一张中间表,
- *来维护多对多关系
- *默认中间表的名称:user_role中间表,字段的名称user_idrole_id
- *如果想更换表名和字段名称,注解如下:
- */
- @JoinTable(name="t_u_r",
- joinColumns={@JoinColumn(name="u_id")},
- inverseJoinColumns={@JoinColumn(name="r_id")}
- )
- publicSet<Role>getRole(){
- returnrole;
- }
- publicvoidsetRole(Set<Role>role){
- this.role=role;
- }
- }
- packagecn.serup.model;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- @Entity
- publicclassRole{
- privateintid;
- privateStringroleName;
- /*privateSet<User>user=newHashSet<User>();
- @ManyToMany
- publicSet<User>getUser(){
- returnuser;
- }
- publicvoidsetUser(Set<User>user){
- this.user=user;
- }*/
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetRoleName(){
- returnroleName;
- }
- publicvoidsetRoleName(StringroleName){
- this.roleName=roleName;
- }
- }
测试类代码如下:
- packagecn.serup.hibernate.test;
- importjava.util.HashSet;
- importjava.util.Iterator;
- importjava.util.Set;
- importorg.hibernate.Session;
- importorg.hibernate.SessionFactory;
- importorg.hibernate.cfg.AnnotationConfiguration;
- importorg.junit.AfterClass;
- importorg.junit.BeforeClass;
- importorg.junit.Test;
- importcn.serup.model.Role;
- importcn.serup.model.User;
- publicclassMany2ManyTest{
- privatestaticSessionFactorysessionFactory=null;
- @Test
- publicvoidtestSaveUR(){
- Roler1=newRole();
- r1.setRoleName("项目组长");
- Roler3=newRole();
- r3.setRoleName("项目经理");
- Roler2=newRole();
- r2.setRoleName("技术总监");
- Useru1=newUser();
- u1.setUsername("唐骏");
- Useru2=newUser();
- u2.setUsername("李开复");
- Useru3=newUser();
- u3.setUsername("柳传志");
- Set<Role>s1=newHashSet<Role>();
- s1.add(r1);
- s1.add(r3);
- Set<Role>s2=newHashSet<Role>();
- s2.add(r1);
- s2.add(r2);
- Set<Role>s3=newHashSet<Role>();
- s3.add(r1);
- s3.add(r2);
- s3.add(r3);
- u1.setRole(s1);
- u2.setRole(s2);
- u3.setRole(s3);
- Sessionsession=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
- publicvoidtestLoadUR(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction().begin();
- Useru=(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();){
- Roler=(Role)it.next();
- System.out.print("\t【"+r.getRoleName()+"】");
- }
- session.beginTransaction().commit();
- }
- @BeforeClass
- publicstaticvoidbeforeClass(){
- sessionFactory=newAnnotationConfiguration().configure().buildSessionFactory();
- }
- @AfterClass
- publicstaticvoidafterClass(){
- sessionFactory.close();
- }
- }
接下来是双向的多对多,实体类代码如下:
- packagecn.serup.model;
- importjava.util.HashSet;
- importjava.util.Set;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.JoinColumn;
- importjavax.persistence.JoinTable;
- importjavax.persistence.ManyToMany;
- @Entity
- publicclassUser{
- privateintid;
- privateStringusername;
- privateSet<Role>role=newHashSet<Role>();
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetUsername(){
- returnusername;
- }
- publicvoidsetUsername(Stringusername){
- this.username=username;
- }
- @ManyToMany
- /**
- *多对多映射:注解@ManyToMany(单向)
- *默认情况下,hibernate会自动的创建一张中间表,
- *来维护多对多关系
- *默认中间表的名称:user_role中间表,字段的名称u_idr_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")}
- *指定关联对象的外键
- */
- publicSet<Role>getRole(){
- returnrole;
- }
- publicvoidsetRole(Set<Role>role){
- this.role=role;
- }
- }
- packagecn.serup.model;
- importjava.util.HashSet;
- importjava.util.Set;
- importjavax.persistence.Entity;
- importjavax.persistence.GeneratedValue;
- importjavax.persistence.Id;
- importjavax.persistence.ManyToMany;
- @Entity
- publicclassRole{
- privateintid;
- privateStringroleName;
- privateSet<User>user=newHashSet<User>();
- @ManyToMany(mappedBy="role")
- /**
- *多对多,双向关联映射
- */
- publicSet<User>getUser(){
- returnuser;
- }
- publicvoidsetUser(Set<User>user){
- this.user=user;
- }
- @Id
- @GeneratedValue
- publicintgetId(){
- returnid;
- }
- publicvoidsetId(intid){
- this.id=id;
- }
- publicStringgetRoleName(){
- returnroleName;
- }
- publicvoidsetRoleName(StringroleName){
- this.roleName=roleName;
- }
- }
测试代码如下:
- packagecn.serup.hibernate.test;
- importjava.util.HashSet;
- importjava.util.Iterator;
- importjava.util.Set;
- importorg.hibernate.Session;
- importorg.hibernate.SessionFactory;
- importorg.hibernate.cfg.AnnotationConfiguration;
- importorg.junit.AfterClass;
- importorg.junit.BeforeClass;
- importorg.junit.Test;
- importcn.serup.model.Role;
- importcn.serup.model.User;
- publicclassMany2ManyTest{
- privatestaticSessionFactorysessionFactory=null;
- publicvoidtestSaveUR(){
- Roler1=newRole();
- r1.setRoleName("项目组长");
- Roler3=newRole();
- r3.setRoleName("项目经理");
- Roler2=newRole();
- r2.setRoleName("技术总监");
- Useru1=newUser();
- u1.setUsername("唐骏");
- Useru2=newUser();
- u2.setUsername("李开复");
- Useru3=newUser();
- u3.setUsername("柳传志");
- Set<Role>s1=newHashSet<Role>();
- s1.add(r1);
- s1.add(r3);
- Set<Role>s2=newHashSet<Role>();
- s2.add(r1);
- s2.add(r2);
- Set<Role>s3=newHashSet<Role>();
- s3.add(r1);
- s3.add(r2);
- s3.add(r3);
- u1.setRole(s1);
- u2.setRole(s2);
- u3.setRole(s3);
- Sessionsession=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
- publicvoidtestLoadUR(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction().begin();
- Useru=(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();){
- Roler=(Role)it.next();
- System.out.print("\t【"+r.getRoleName()+"】");
- }
- session.beginTransaction().commit();
- }
- @Test
- publicvoidtestLoadRU(){
- Sessionsession=sessionFactory.getCurrentSession();
- session.beginTransaction().begin();
- Roler=(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();){
- Useru=(User)it.next();
- System.out.print("\t【"+u.getUsername()+"】");
- }
- session.beginTransaction().commit();
- }
- @BeforeClass
- publicstaticvoidbeforeClass(){
- sessionFactory=newAnnotationConfiguration().configure().buildSessionFactory();
- }
- @AfterClass
- publicstaticvoidafterClass(){
- 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、一般使用默认就可以了