Hibernate学习记录

Hibernate学习记录

本次学习是在hibernate3环境下,没有结合struts2Spring,测试是直接用java类的main方法在控制台输出。

一、准备工作

oracle数据库(其他数据库也可以,都是相似的)、hibernate3.jar等架包。

二、使用步骤

         a.创建工程,引入hibernate和驱动开发包

         b.src下添加hibernate.cfg.xml主配置

         c.根据数据表创建Entity实体类

         d.编写实体类和数据表的映射文件xxx.hbm.xml

        e.利用Hibernate API实现增删改查操作

三、简单的实例

1、在src下添加hibernate.cfg.xml主配置,配置内容如下:

<!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">oracle.jdbc.driver.OracleDriver</property>

                   <!--   连接数据库的地址-->

                   <property   name="hibernate.connection.url">jdbc:oracle:thin:@localhost :1521:orcl</property>

                   <!--   连接数据库的用户名-->

                   <property   name="hibernate.connection.username">hr</property>

                   <!--   连接数据库的密码-->

                   <property   name="hibernate.connection.password">orcl</property>

 

                   <property   name="hibernate.connection.pool.size">20 </property>

                   <property   name="hibernate.show_sql">true </property>

                   <property   name="jdbc.fetch_size">50 </property>

                   <property   name="jdbc.batch_size">23 </property>

                   <property   name="jdbc.use_scrollable_resultset">false </property>

                   <property   name="Connection.useUnicode">true </property>

 

                   <!--hibernate.dialect   只是Hibernate使用的数据库方言,就是要用Hibernate连接那种类型的数据库服务器。-->

                   <property   name="hibernate.dialect">org.hibernate.dialect.OracleDialect   </property>

                  

                   <!--指定映射文件-->

                   <mapping   resource="com/neusoft/test/entity/User.hbm.xml" />

         </session-factory>

</hibernate-configuration>

 

2、根据数据表创建Entity实体类,com/neusoft/test/entity/User.java,代码如下:

package com.neusoft.test.entity;

 

public class User {

         private   int id;

         private   String userName;

         private   String password;

         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;

         }

}

需要注意的是实体类定义的字段最好与数据库(oracle不区分大小写)中的字段一致,如果不一致会麻烦一些,且配置容易出错。

 

3、编写实体类和数据表的映射文件com/neusoft/test/entity/User.hbm.xml,该配置文件存放的位置不是固定的,但是要与hibernate.cfg.xml主配置中“指定映射文件”相对应,具体配置如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

         "-//Hibernate/Hibernate   Mapping DTD 3.0//EN"

         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping   package="com.neusoft.test.entity">

         <class   name="User" table="demo_user_t">

                   <id   name="id">

                            <column   name="id"></column>

                            <!--主键生成策略,sequenceoracle自增策略,别的数据库要使用各自适用的 -->

                            <generator />

                   </id>

                   <property   name="userName" column="userName"/>

                   <property   name="password" />

         </class>

</hibernate-mapping>

name属性对应的是实体类中的属性字段,必须是一致的(区分大小写),如果该字段与数据库表中的字段是一致的,则不需要column;如果不一致,则需要column指明该字段是与数据库中哪个字段是对应的。

数据库的表名为demo_user_t,含有字段iduserNamepassword

 

4、测试,进行增删改查。新建一个test1.java。代码如下:

package com.neusoft.test.action;

 

import java.util.List;

import org.hibernate.*;

import com.neusoft.test.entity.User;

import com.neusoft.test.utils.HibernateUtil;

 

public class test1 {

         /**

          * main函数,选择要执行的动作

          */

         public   static void main(String args[]) {

                   testFindAll();

         }

 

         /**

          * 测试添加操作

          */

         public   static void testAdd() {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   User   user = new User();

                   user.setId(1);//   user.setId()要根据主键生成策略而定

                   user.setuserName("1");

                   user.setPassword("1");

                   session.save(user);//   保存

                   tx.commit();//   提交事务

                   session.close();//   关闭session

         }

 

         /**

          * 测试更新操作

          */

         public   static void testUpdate() {

                   Session   session = HibernateUtil.getSession();

                   Transaction   tx = session.beginTransaction();

                   //   ID=1主键做条件查询

                   User   user = (User) session.load(User.class, 1);

                   user.setuserName("11");

                   user.setPassword("11");

                   session.update(user);

                   tx.commit();

                   session.close();

         }

 

         /**

          * 测试删除操作

          */

         public   static void testDelete() {

                   Session   session = HibernateUtil.getSession();

                   Transaction   tx = session.beginTransaction();

                   User   user = new User();

                   user.setId(1);

                   //   User user = (User)session.get(User.class, 1);

                   session.delete(user);//   执行一个delete语句,ID做条件删除

                   tx.commit();

                   session.close();

         }

 

         /**

          * 测试查询操作

          */

         @SuppressWarnings("unchecked")

         public   static void testFindAll() {

                   Session   session = HibernateUtil.getSession();

                   //   利用Query执行一个HQL查询语句

                   Query   query = session.createQuery("from User");

                   List<User>   list = query.list();

                   for   (User u : list) {

                            System.out.println(u.getId()   + "  " + u.getuserName() +   "  "

                                               +   u.getPassword());

                   }

                   session.close();

         }

 

         public   static void testFindById() {

                   Session   session = HibernateUtil.getSession();

                   //   利用Query执行一个HQL查询语句

                   User   user = (User) session.get(User.class, 1);

                   System.out.println(user.getId()   + "  " + user.getuserName() +   "  "

                                     +   user.getPassword());

                   session.close();

         }

 

         @SuppressWarnings("unchecked")

         public   static void testFindByName() {

                   Session   session = HibernateUtil.getSession();

                   //   利用Query执行一个HQL查询语句

                   Query   query = session.createQuery("from User where userName='1'");

                   List<User>   list = query.list();

                   for   (User u : list) {

                            System.out.println(u.getId()   + "  " + u.getuserName() +   "  "

                                               +   u.getPassword());

                   }

                   session.close();

         }

}

需要一个自定义的hibernate工具类HibernateUtil,代码如下:

package com.neusoft.test.utils;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class HibernateUtil {

//  static   SessionFactory sessionFactory= new   Configuration().configure().buildSessionFactory();

         static   SessionFactory sessionFactory = new Configuration().configure(

                            "hibernate.cfg.xml").buildSessionFactory();

         static   Session session = sessionFactory.openSession();

 

         public   static Session getSession() {

                   return   session;

         }

 

         public   static void closeSession() {

                   //   TODO Auto-generated method stub

                   session.close();

         }

}

四、深入学习

首先要说明,有多个实例化类时,可以定义定义多个映射文件xxx.hbm.xml,然后在主配文件hibernate.cfg.xml中指定所有映射文件;也可以只定义一个映射文件,在映射文件中定义多个实例化类(class的定义)。

还有一点要注意,一个实例化类只能被映射文件定义一次。如果要对同一个表进行不同功能的操作,则建多个与之对应的实例化类,然后在映射文件中定义不同功能的实例化类。

每次做完一个小test要将数据库表内的数据清空,否则会对其他的测试产生影响,有可能报错。

 

1 映射集合属性

1List集合映射:

数据库表students

schools

映射文件中添加如下配置:

<class name="Student"   table="students">

                   <id   name="id">

                            <column   name="id"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <list   name="schools" table="schools">

                            <!--   外键,对应该表的某个字段,默认参考上面定义的id -->

                            <key   column="student_id" not-null="true"></key>

                            <list-index   column="list_order"></list-index>

                            <element   type="string" column="school_name"></element>

                   </list>

         </class>

实例化类如下:

package com.neusoft.test.entity;

 

import java.util.ArrayList;

import java.util.List;

 

@SuppressWarnings("unchecked")

public class Student {

         private   int id;

         private   String name;

         private   int age;

         private   List<String> schools = new ArrayList();

         public   int getId() {

                   return   id;

         }

         public   void setId(int id) {

                   this.id   = id;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   List getSchools() {

                   return   schools;

         }

         public   void setSchools(List schools) {

                   this.schools   = schools;

         }

}

测试类如下:

package com.neusoft.test.action;

 

import java.util.ArrayList;

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Student;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestListStudent {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                  

                   //添加

                   Student   student = new Student();

                   student.setAge(12);

                   student.setName("aqq");

                   List   list = new ArrayList();

                   list.add("zqas");

                   list.add("zxxdfg");

                   list.add("zaadfg");

                   student.setSchools(list);

                   session.save(student);

                   tx.commit();//   提交事务

                  

                   //查询

                   Query   query = session.createQuery("from Student");

                   List<Student>   list1 = query.list();

                   for   (Student s : list1) {

                            System.out.print("id:"   + s.getId() + "  姓名:" + s.getName()

                                               +   "  年龄:"   + s.getAge() + "  上过的学校:");

                            List<String>   list2 = s.getSchools();

                            for   (String str : list2) {

                                     System.out.print(str   + " ");

                            }

                            System.out.println();

                   }

                   session.close();//   关闭session

         }

}

 

2Set集合映射

映射文件配置:

<class name="Student_set"   table="students">

                   <id   name="id">

                            <column   name="id"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <set   name="schools" table="schools">

                            <key   column="student_id" not-null="true"></key>

                            <element   type="string" column="school_name"></element>

                   </set>

         </class>

实例化类如下:

package com.neusoft.test.entity;

 

import java.util.HashSet;

import java.util.Set;

 

@SuppressWarnings("unchecked")

public class Student_set {

         private   int id;

         private   String name;

         private   int age;

         private   Set<String> schools=new HashSet();

        

         public   Set<String> getSchools() {

                   return   schools;

         }

         public   void setSchools(Set<String> schools) {

                   this.schools   = schools;

         }

         public   int getId() {

                   return   id;

         }

         public   void setId(int id) {

                   this.id   = id;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

测试类如下:

package com.neusoft.test.action;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Student_set;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestSetStudent {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Student_set   student = new Student_set();

                   student.setAge(20);

                   student.setName("mm");

                   Set   set = new HashSet();

                   set.add("zxc1");

                   set.add("zxc2");

                   student.setSchools(set);

                   session.save(student);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Student_set");

                   List<Student_set>   list = query.list();

                   for   (Student_set s : list) {

                            System.out.print("id:"   + s.getId() + "  姓名:" + s.getName()

                                               +   "  年龄:"   + s.getAge() + "  上过的学校:");

                            Set<String>   list2 = s.getSchools();

                            for   (String str : list2) {

                                     System.out.print(str   + " ");

                            }

                            System.out.println();

                   }

                   session.close();//   关闭session

         }

}

 

3Map集合属性

新建数据库表scores

映射文件配置:

<class name="Student_map"   table="students">

                   <id   name="id">

                            <column   name="id"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <map   name="scores" table="scores">

                            <key   column="student_id" not-null="true"></key>

                            <map-key   type="string" column="course"></map-key>

                            <element   type="integer" column="score"></element>

                   </map>

         </class>

实例化类:

package com.neusoft.test.entity;

 

import java.util.HashMap;

import java.util.Map;

 

@SuppressWarnings("unchecked")

public class Student_map {

         private   int id;

         private   String name;

         private   int age;

         private   Map scores = new HashMap();

 

         public   Map getScores() {

                   return   scores;

         }

         public   void setScores(Map scores) {

                   this.scores   = scores;

         }

         public   int getId() {

                   return   id;

         }

         public   void setId(int id) {

                   this.id   = id;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Student_map;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestMapStudent {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Student_map   student = new Student_map();

                   student.setAge(18);

                   student.setName("yuiu");

                   Map   map=new HashMap();

                   map.put("数学",85);

                   map.put("语文",95);

                   map.put("英语",89);

                   student.setScores(map);

                   session.save(student);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Student_map");

                   List<Student_map>   list = query.list();

                   for   (Student_map s : list) {

                            System.out.print("id:"   + s.getId() + "  姓名:" + s.getName()

                                               +   "  年龄:"   + s.getAge() + "  成绩:");

                            Map   map1 = s.getScores();

                           

//                          第一种Map遍历

//                          Iterator   it = map.entrySet().iterator();

//                          while   (it.hasNext()) {

//                                   Map.Entry   entry = (Map.Entry) it.next();

//                                   Object   key = entry.getKey();

//                                   Object   value = entry.getValue();

//                                   System.out.print(key   + ":" + value + " ");

//                          }

 

//                          第二种Map遍历

                            for   (Object o : map1.keySet()) {

                                     System.out.print(o   + ":" + map1.get(o) + " ");

                            }

//                          第三种Map遍历

//                          for   (Iterator i = map.keySet().iterator(); i.hasNext();) {

//                                   Object   obj = i.next();

//                                   System.out.print(obj   +":" + map.get(obj) + " ");

//                          }

                            System.out.println();

                   }

                   session.close();//   关闭session

         }

}

 

4)映射组件属性

组件属性的意思是持久化类的属性既不是基本数据类型,也不是 String 字符串,而是某个组件变量,该组件属性的类型可以是自定义类。

显然无法直接用 property 映射 name 属性。为了映射组件属性, Hibernate 提供了 component 元素。每个 component 元素映射一个组件属性,组件属性必须指定该属性的类型,component 元素中的 class 属性用于确定组件的类型。

新建数据库表worker_table

映射文件配置:

<class name="Worker"   table="worker_table">

                   <id   name="id">

                            <column   name="id"></column>

                            <generator />

                   </id>

                   <property   name="age" />

                   <component   name="name">

                            <property   name="last" />

                            <property   name="first" />

                   </component>

         </class>

实例化类:

package com.neusoft.test.entity;

 

public class Worker {

         private   int id;

         private   int age;

         private   Name name;

 

         public   Name getName() {

                   return   name;

         }

         public   void setName(Name name) {

                   this.name   = name;

         }

         public   int getId() {

                   return   id;

         }

         public   void setId(int id) {

                   this.id   = id;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

辅助类:

package com.neusoft.test.entity;

 

public class Name {

         private   String last;

         private   String first;

 

         public   String getLast() {

                   return   last;

         }

         public   void setLast(String last) {

                   this.last   = last;

         }

         public   String getFirst() {

                   return   first;

         }

         public   void setFirst(String first) {

                   this.first   = first;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Name;

import com.neusoft.test.entity.Worker;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestWorker {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Worker   worker=new Worker();

                   Name   name= new Name();

                   name.setLast("Cloze");

                   name.setFirst("Tom");

                   worker.setAge(25);

                   worker.setName(name);

                   session.save(worker);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Worker");

                   List<Worker>   worker1 = query.list();

                   for   (Worker w : worker1) {

                            System.out.println("id:"   + w.getId() + "  姓名:"

                                               +   w.getName().getLast() + " " + w.getName().getFirst()

                                               +   "  年龄:"   + w.getAge());

                   }

                   session.close();//   关闭session

         }

 

}

 

5)集合组件属性映射

集合除了存放 String 字符串以外,还可以存放组件类型。实际上,更多情况下,集合组件存放的都是组件类型。

新建数据库表company_table

映射文件配置:

<class name="Worker2"   table="worker_table">

                   <id   name="id">

                            <column   name="id"></column>

                            <generator />

                   </id>

                   <property   name="age" />

                   <component   name="name">

                            <property   name="last" />

                            <property   name="first" />

                   </component>

                   <list   name="company" table="company_table">

                            <key   column="id" not-null="true"/>

                            <list-index   column="list_order"/>

                            <composite-element>

                                     <property   name="name"></property>

                                     <property   name="address"></property>

                            </composite-element>

                   </list>

         </class>

实例化类:

package com.neusoft.test.entity;

 

import java.util.ArrayList;

import java.util.List;

 

@SuppressWarnings("unchecked")

public class Worker2 {

         private   int id;

         private   int age;

         private   Name name;

         private   List<Company> company = new ArrayList();

 

         public   List<Company> getCompany() {

                   return   company;

         }

         public   void setCompany(List<Company> company) {

                   this.company   = company;

         }

         public   Name getName() {

                   return   name;

         }

         public   void setName(Name name) {

                   this.name   = name;

         }

         public   int getId() {

                   return   id;

         }

         public   void setId(int id) {

                   this.id   = id;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

辅助类:

package com.neusoft.test.entity;

 

public class Company {

         private   String name;

         private   String address;

 

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   String getAddress() {

                   return   address;

         }

         public   void setAddress(String address) {

                   this.address   = address;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.ArrayList;

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Company;

import com.neusoft.test.entity.Name;

import com.neusoft.test.entity.Worker2;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestWorkerAndCompany {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   List   list = new ArrayList();

                   Worker2   worker=new Worker2();

                   worker.setAge(22);

                   Name   name= new Name();

                   name.setLast("Cloze");

                   name.setFirst("Tom");

                   worker.setName(name);

                   Company   company=new Company();

                   company.setName("aaa");

                   company.setAddress("aaaaaaaaaa");

                   list.add(company);

                   Company   company2=new Company();

                   company2.setName("bbbb");

                   company2.setAddress("bbbbbbbbbb");

                   list.add(company2);

                   Company   company3=new Company();

                   company3.setName("ccc");

                   company3.setAddress("ccccccc");

                   list.add(company3);

                   worker.setCompany(list);

                   session.save(worker);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Worker2");

                   List<Worker2>   worker1 = query.list();

                   for   (Worker2 w : worker1) {

                            System.out.println("id:"   + w.getId() + "  姓名:"

                                               +   w.getName().getLast() + " " + w.getName().getFirst()

                                               +   "  年龄:"   + w.getAge() + " 工作过的公司:");

                            for(Company   c :w.getCompany()){

                                     System.out.println(c.getName()+"   "+c.getAddress());

                            }

                            System.out.println();

                   }

                   session.close();//   关闭session

         }

}

 

2 关联关系映射

1)单向 N-1

单向 N-1 关联只需从 N 的一端可以访问 1 的一端。模型:多个人(Person)对应同一个地址(Address)。只需要从人实体端找到相应的地址实体。无须关心从某个地址找到全部住户。

Person 端增加了 Address 属性,该属性不是一个普通的组件属性,而是引用了另外一个持久化类,使用 many-to-one 元素映射 N-1 的持久化属性。

many-to-one 元素的作用类似于 property 元素,用于映射持久化类的某个属性,区别是改元素映射的是关联持久化类。与 property 元素类似,many-to-one 元素也必须拥有 name 属性,用于确定该属性的名字,column 属性确定外键列的列名.

新建数据库表person_table

address_table

映射配置:

<class name="Person"   table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <!--   多对一,columnAddress在该表中的外键列名 -->

                   <many-to-one   name="address" column="addressid"></many-to-one>

         </class>

<class name="Address"   table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

         </class>

实例化类1

package com.neusoft.test.entity;

 

public class Person {

         private   int personid;

private String name;

         private   int age;

         private   Address address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Address getAddress() {

                   return   address;

         }

         public   void setAddress(Address address) {

                   this.address   = address;

         }

}

实例化类2

package com.neusoft.test.entity;

 

public class Address {

         private   int addressid;

         private   String addressdetail;

         private   int personid;

 

         public   int getPersonid() {

                   return   personid;

}

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   String getAddressdetail() {

                   return   addressdetail;

         }

         public   void setAddressdetail(String addressdetail) {

                   this.addressdetail   = addressdetail;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address;

import com.neusoft.test.entity.Person;

import com.neusoft.test.utils.HibernateUtil;

 

public class AddManyToOne {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Person   person=new Person();

                   person.setName("aa");

                   person.setAge(22);

                   Address   address=new Address();

                  

//                 新建一个地址,然后添加给person

                   address.setAddressdetail("wqesdasdasd");

                   person.setAddress(address);

                   session.save(address);

                  

//                 直接添加已有的地址

//                 address.setAddressid(1);

//                 person.setAddress(address);

                  

                   session.save(person);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person");

                   List<Person>   list = query.list();

                   for   (Person p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               +   p.getAddress().getAddressdetail());

                   }

                   session.close();//   关闭session

         }

}

 

2基于外键的单向 1-1

单向 1-1POJO N-1 没有丝毫区别。

基于外键的单向 1-1 映射文件:只需要在原有的 many-to-one 元素添加 unique=“true”,用以表示 N 的一端必须唯一即可,N的一端增加了唯一约束, 即成为单向 1-1

 

3)基于主键的单向 1-1

基于主键关联的持久化类不能拥有自己的主键生成器,它的主键由关联类负责生成。增加one-to-one元素来映射关联属性,必须为one-to-one元素增加constrained="true"属性,表明该类的主键由关联类生成。

映射配置:

<class name="Person2"   table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <!--   基于主键关联时,主键生成策略是foreign,表明根据关联类生成主键   -->

                            <generator>

                                     <!--   关联持久化类的属性名 -->

                                     <param   name="property">address</param>

                            </generator>

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <!--   关联映射 基于主键 1-1 -->

                   <one-to-one   name="address" constrained="true"></one-to-one>

         </class>

<class name="Address"   table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

         </class>

实例化类:

package com.neusoft.test.entity;

 

public class Person2 {

         private   int personid;

         private   String name;

private int age;

         private   Address address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Address getAddress() {

                   return   address;

         }

         public   void setAddress(Address address) {

                   this.address   = address;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address;

import com.neusoft.test.entity.Person2;

import com.neusoft.test.utils.HibernateUtil;

 

public class AddOneToOne {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Person2   person=new Person2();

                   person.setName("aa");

                   person.setAge(22);

                   Address   address=new Address();

                  

//                 新建一个地址,然后添加给person

                   address.setAddressdetail("wqesdasdasd");

                   person.setAddress(address);

                   session.save(address);

                  

                   session.save(person);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person2");

                   List<Person2>   list = query.list();

                   for   (Person2 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               +   p.getAddress().getAddressdetail());

                   }

                   session.close();//   关闭session

         }

}

 

4单向的 1-N

单向 1-N 关联的 POJO 需要使用集合属性。因为一的一端需要访问 N 的一端,而 N 的一端将以集合的形式表现。

不推荐使用单向的 1-N 关联:使用 1 的一端控制关联关系时,会额外多出 update 语句。插入数据时无法同时插入外键列,因而无法为外键列添加非空约束

映射配置:

<class name="Person3"   table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <!--   单向1-N -->

                   <set   name="address" table="address_table">

                            <key   column="personid"></key>

                            <one-to-many />

                   </set>

         </class>

<class name="Address"   table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

         </class>

实例化类:

package com.neusoft.test.entity;

 

import java.util.Set;

 

public class Person3 {

         private   int personid;

private String name;

         private   int age;

         private   Set<Address> address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Set<Address> getAddress() {

                   return   address;

         }

         public   void setAddress(Set<Address> address) {

                   this.address   = address;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address;

import com.neusoft.test.entity.Person3;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestOneToMany{

         @SuppressWarnings("unchecked")

         public static   void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Person3   person=new Person3();

                   person.setName("gfg");

                   person.setAge(35);

                   Set   set=new HashSet();

                  

                   Address   address=new Address();

                   address.setAddressdetail("zxcvzxc");

                   session.save(address);

                   set.add(address);

                  

                   Address   address2=new Address();

                   address2.setAddressdetail("esdasd");

                   session.save(address2);

                   set.add(address2);

                  

                   Address   address3=new Address();

                   address3.setAddressid(105);

                   set.add(address3);

                   person.setAddress(set);

                   session.save(person);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person3");

                   List<Person3>   list = query.list();

                   for   (Person3 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               );

                            Set<Address>   address1=p.getAddress();

                            for(Address   a: address1){

                                     System.out.println(a.getAddressdetail());

                            }

                   }

                   session.close();//   关闭session

         }

}

 

5)单向的 N-N

与映射集合属性类似,必须为setlist等集合元素添加 key 子元素,用以映射关联的外键列。与集合映射不同的是,建立 N-N 关联时,集合中的元素使用 many-to-many,而不是使用 element 子元素

N-N 的关联必须使用连接表。

新建数据库表person_address_table

映射配置:

<class name="Person4"   table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

<!-- 单向N-N   -->

                   <!--   person_address_table为额外的表,表列必须含有key对应的字段和elt,其中elt是固定的 -->

                   <set   name="address" table="person_address_table">

                            <key   column="personid" />

                            <many-to-many/>

                   </set>

         </class>

<class name="Address"   table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

         </class>

实例化类:

package com.neusoft.test.entity;

 

import java.util.Set;

 

public class Person4 {

         private   int personid;

         private   String name;

         private   int age;

         private   int addressid;

         private   Set<Address> address;

 

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Set<Address> getAddress() {

                   return   address;

         }

         public   void setAddress(Set<Address> address) {

                   this.address   = address;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address;

import com.neusoft.test.entity.Person4;

import com.neusoft.test.utils.HibernateUtil;

 

public class TestManyToMany {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                  

                   Address   address1=new Address();

                   address1.setAddressdetail("zxcvzxc");

                  

                   Address   address2=new Address();

                   address2.setAddressdetail("esdasd");

                  

                   Set   set_address=new HashSet();

                   set_address.add(address1);

                   set_address.add(address2);

                  

                   Person4   person1=new Person4();

                   person1.setName("gfg");

                   person1.setAge(35);

                   person1.setAddress(set_address);

                  

                   Person4   person2=new Person4();

                   person2.setName("gfg");

                   person2.setAge(35);

                   person2.setAddress(set_address);

                  

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

 

                   session.save(address1);

                   session.save(address2);

                   session.save(person1);

                   session.save(person2);

                  

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person4");

                   List<Person4>   list = query.list();

                   for   (Person4 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               );

                            Set<Address>   address=p.getAddress();

                            for(Address   a: address){

                                     System.out.println(a.getAddressdetail());

                            }

                   }

                   session.close();//   关闭session

         }

}

 

6双向 1-NN-1

对于 1-N 的关联,Hibernate 推荐使用双向关联,而且不要让 1 的一端控制关联关系,而是使用 N 的一端控制关联关系。

双向 1-N N-1 是完全相同的。

1 的一端需要使用集合属性元素来映射关联关系。集合属性元素同样需要增加 key 元素,还需要使用 one-to-many 元素来映射关联属性。

N 的一端需要增加 many-to-one 元素来映射关联属性。

映射配置:

<hibernate-mapping   package="com.neusoft.test.entity">

         <class   name="Person" table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

<generator   />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <!--   双向1-NN-1

                             cascade级联关系

                             inverse=true:将控制权抛出(给双向的另一方)

                   -->

                   <set   name="address" table="address_table"   cascade="save-update" inverse="true">

                            <key   column="personid"></key>

                            <one-to-many/>

                   </set>

         </class>

 

         <class   name="Address" table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

                   <many-to-one   name="person" column="personid"></many-to-one>

         </class>

</hibernate-mapping>

 注意:在上面的配置文件中,两个持久化类的配置文件都需要指定外键列的列名,此时不可以省略。因为不使用连接表的1-N关联的外键,而外键只保存在N一端的表中,如果两边指定的外键列名不同,将导致关联映射出错。如果不指定外键列的列名,该列名由系统自动生成,而系统很难保存自动生成的两个列名相同。

实例化类1

package com.neusoft.test.entity;

 

import java.util.Set;

 

public class Person {

         private   int personid;

         private   String name;

         private   int age;

         private   Set<Address> address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Set<Address> getAddress() {

                   return   address;

         }

         public   void setAddress(Set<Address> address) {

                   this.address   = address;

         }

}

实例化类2

package com.neusoft.test.entity;

 

public class Address {

         private   int addressid;

         private   String addressdetail;

         private   Person person;

 

         public   Person getPerson() {

                   return   person;

         }

         public   void setPerson(Person person) {

                   this.person   = person;

         }

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   String getAddressdetail() {

                   return   addressdetail;

         }

         public   void setAddressdetail(String addressdetail) {

                   this.addressdetail   = addressdetail;

         }

}

 

测试类:

package com.neusoft.test.action;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address;

import com.neusoft.test.entity.Person;

import com.neusoft.test.utils.HibernateUtil;

 

public class test {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Person   person = new Person();

                   person.setName("ghgh");

                   person.setAge(33);

 

                   Address   address = new Address();

                   address.setAddressdetail("gdsfasg");

                   address.setPerson(person);

 

                   Address   address2 = new Address();

                   address2.setAddressdetail("rtyrtyt");

                   address2.setPerson(person);

 

                   Set   set = new HashSet();

                   set.add(address);

                   set.add(address2);

                   person.setAddress(set);

 

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   session.save(person);

                   session.save(address);

                   session.save(address2);

                   tx.commit();//   提交事务

 

                   //1的一段query

                   Query   query = session.createQuery("from Person");

                   List<Person>   list = query.list();

                   for   (Person p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:");

                            Set<Address>   address1 = p.getAddress();

                            for   (Address a : address1) {

                                     System.out.println(a.getAddressdetail());

                            }

                   }

 

                   //N的一段query

                   Query   query1 = session.createQuery("from Address");

                   List<Address>   list1 = query1.list();

                   for   (Address a : list1) {

                            System.out

                                               .println("   地址id" +   a.getAddressid() + " 详情:"

                                                                 +   a.getAddressdetail() + " id"

                                                                 +   a.getPerson().getPersonid() + " 人名:"

                                                                 +   a.getPerson().getName() + " 年龄:"

                                                                 +   a.getPerson().getAge());

                   }

                   session.close();//   关闭session

         }

}

 

7inverse

只有集合标记(setmaplistarraybag)才有inverse属性。

Hibernate 中,inverse 指定了关联关系的方向。关联关系中 inverse = false 的为主动方,由主动方负责维护关联关系。

在没有设置 inverse=true 的情况下,父子两边都维护父子关系

1-N 关系中,将 many 方设为主控方(inverse = false) 将有助于性能改善(如果要国家元首记住全国人民的名字,不是太可能,但要让全国人民知道国家元首,就容易的多);若将 1 方设为主控方会额外多出 update 语句。插入数据时无法同时插入外键列,因而无法为外键列添加非空约束。

 

8cascade

只有关系标记才有cascade属性:many-to-oneone-to-one ,set(map, bag, idbag, list, array) + one-to-many(many-to-many)

级联指的是当主控方执行操作时,关联对象(被动方)是否同步执行同一操作。

pojo和它的关系属性的关系就是主控方 -- 被动方的关系,如果关系属性是一个set,那么被动方就是set中的每一个元素。一个操作因级联cascade可能触发多个关联操作。前一个操作叫主控操作,后一个操作叫关联操作

inverse 指的是关联关系的控制方向,而cascade指的是层级之间的连锁操作。

cascade属性的可选值:

all : 所有情况下均进行关联操作。

none:所有情况下均不进行关联操作。这是默认值。

save-update:在执行save/update/saveOrUpdate时进行关联操作。

delete:在执行delete时进行关联操作

delete-orphan:表示删除孤儿,delete-orphan在前者的基础上增加了一点,针对持久化对象,如果它和它所关联的对象的引用关系不存在了,则进行级联删除。

all-delete-orphan:包含alldelete-orphan的行为

 

9双向N-N关联

双向N-N关联需要两端都使用集合属性,两端都增加对集合属性的访问。双向N-N关联也必须使用连接表。

双向N-N的关联映射需要在两边增加集合元素,用于映射集合属性。集合属性应增加key子元素用以映射外键列,集合元素里还应增加many-to-many子元素关联实体类

注意:在双向N-N关联的两边都需定连接表的表名及外键列的列名。两个集合元素settable元素的值必须指定,而且必须相同。set元素的两个子元素:keymany-to-many都必须指定column属性,其中,keymany-to-many分别指定本持久化类和关联类在连接表中的外键列名,因
此两边的keymany-to-manycolumn属性交叉相同。也就是说,一边的set元素的keycloumn值为a,many-to-manycolumnb;则另一边的set元素的keycolumnb,many-to-manycolumn值为a.

映射配置:

<class name="Person2"   table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <!--   双向N-N -->

                   <!--   person_address_table为额外的表,表列必须含有key对应的字段和elt,其中elt是固定的 -->

                   <set   name="address" table="person_address_table">

                            <key   column="personid" />

                            <many-to-many   column="addressid"/>

                   </set>

         </class>

         <class   name="Address2" table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

                   <!--   双向N-N -->

                   <!--   person_address_table为额外的表,表列必须含有key对应的字段和elt,其中elt是固定的 -->

                   <set   name="person" inverse="true"   table="person_address_table">

                            <key   column="addressid" />

                            <many-to-many   column="personid"/>

                   </set>

         </class>

实例化类1

package com.neusoft.test.entity;

 

import java.util.Set;

 

public class Person2 {

         private   int personid;

         private   String name;

         private   int age;

         private   Set<Address2> address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Set<Address2> getAddress() {

                   return   address;

         }

         public   void setAddress(Set<Address2> address) {

                   this.address   = address;

         }

}

 

实例化类2

package com.neusoft.test.entity;

 

import java.util.Set;

 

public class Address2 {

         private   int addressid;

         private   String addressdetail;

         private   Set<Person2> person;

 

         public   Set<Person2> getPerson() {

                   return   person;

         }

         public   void setPerson(Set<Person2> person) {

                   this.person   = person;

         }

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   String getAddressdetail() {

                   return   addressdetail;

         }

         public   void setAddressdetail(String addressdetail) {

                   this.addressdetail   = addressdetail;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address2;

import com.neusoft.test.entity.Person2;

import com.neusoft.test.utils.HibernateUtil;

 

public class test2 {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

 

                   Address2   address1 = new Address2();

                   address1.setAddressdetail("zxcvzxc");

 

                   Address2   address2 = new Address2();

                   address2.setAddressdetail("esdasd");

 

                   Person2   person1 = new Person2();

                  person1.setName("gfg");

                   person1.setAge(35);

 

                   Person2   person2 = new Person2();

                   person2.setName("gfg");

                   person2.setAge(35);

 

                   Set   set_address = new HashSet();

                   set_address.add(address1);

                   set_address.add(address2);

 

                   Set   set_person = new HashSet();

                   set_person.add(person1);

                   set_person.add(person2);

 

                   person1.setAddress(set_address);

                   person2.setAddress(set_address);

                   address1.setPerson(set_person);

                   address2.setPerson(set_person);

 

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

 

                   session.save(address1);

                   session.save(address2);

                   session.save(person1);

                   session.save(person2);

 

                   tx.commit();//   提交事务

 

                   Query   query = session.createQuery("from Person2");

                   List<Person2>   list = query.list();

                   for   (Person2 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:");

                            Set<Address2>   address = p.getAddress();

                            for   (Address2 a : address) {

                                     System.out.println(a.getAddressdetail());

                            }

                   }

 

                   Query   query1 = session.createQuery("from Address2");

                   List<Address2>   list1 = query1.list();

                   for   (Address2 a : list1) {

                            System.out.println("  地址id" + a.getAddressid() + "  地址详细:"

                                               +   a.getAddressdetail());

                            Set<Person2>   person = a.getPerson();

                            for   (Person2 p : person) {

                                     System.out.println("  id" + p.getPersonid() + "  姓名:"

                                                        +   p.getName() + "  年龄:" + p.getAge());

                            }

                   }

                   session.close();//   关闭session

         }

}

 

10)双向1-1关联

单向的1-1关联有三种映射策略:基于主键,基于外键和使用连接表。双向的1-1关联同样有这三种映射策略。

双向的1-1关联需要修改POJO类,让两边都增加对关联类的访问

基于外键的双向1-1关联

映射配置:

<!-- 双向1-1主实体 -->

         <class   name="Person3" table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                  <property name="age"   />

                   <one-to-one   name="address" cascade="all"   property-ref="person"></one-to-one>

         </class>

<!-- 双向1-1从属实体 -->

         <class   name="Address3" table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator />

                   </id>

                   <property   name="addressdetail" />

                   <!--   unique="true" 确定是双向的1-1 -->

                   <many-to-one   name="person" column="personid"   unique="true"></many-to-one>

         </class>

实例化类1

package com.neusoft.test.entity;

 

public class Person3 {

         private   int personid;

         private   String name;

         private   int age;

         private   Address3 address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Address3 getAddress() {

                   return   address;

         }

         public   void setAddress(Address3 address) {

                   this.address   = address;

         }

}

实例化类2

package com.neusoft.test.entity;

 

public class Address3 {

         private   int addressid;

         private   String addressdetail;

         private   Person3 person;

 

         public   Person3 getPerson() {

                   return   person;

         }

         public   void setPerson(Person3 person) {

                   this.person   = person;

         }

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   String getAddressdetail() {

                   return   addressdetail;

         }

         public   void setAddressdetail(String addressdetail) {

                   this.addressdetail   = addressdetail;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address3;

import com.neusoft.test.entity.Person3;

import com.neusoft.test.utils.HibernateUtil;

 

@SuppressWarnings("unchecked")

public class test3 {

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Person3   person=new Person3();

                   person.setName("uytua");

                   person.setAge(28);

                   Address3   address=new Address3();

                  

//                 新建一个地址,然后添加给person

                   address.setAddressdetail("wqesdasdasd");

                   address.setPerson(person);

                   person.setAddress(address);

                  

                   session.save(address);

                   session.save(person);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person3");

                   List<Person3>   list = query.list();

                   for   (Person3 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               +   p.getAddress().getAddressdetail());

                   }

                   session.close();//   关闭session

         }

}

 

基于主键的双向1-1关联

基于主键的映射策略:指一端的主键生成器使用foreign略,表明根据对方的主键来生成自己的主键,自己并不能独立生成主键。

任意一边都可以采用foreign主键生成器,表明根据对方主键生成自己的主键。

采用foreign主键生成器策略的一端增加one-to-one元素映射关联属性,其one-to-one属性还应增加constrained=true”属性;另一端增加one-to-one元素映射关联属性。

constrained(约束) :表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。

映射配置:

<!-- 基于主键的双向1-1关联 -->

         <class   name="Person4" table="person_table">

                   <id   name="personid">

                            <column   name="personid"></column>

                            <generator />

                   </id>

                   <property   name="name" />

                   <property   name="age" />

                   <one-to-one   name="address" cascade="all"></one-to-one>

         </class>

         <class   name="Address4" table="address_table">

                   <id   name="addressid">

                            <column   name="addressid"></column>

                            <generator>

                                     <param   name="property">person</param>

                            </generator>

                   </id>

                   <property   name="addressdetail" />

                   <one-to-one   name="person" constrained="true"></one-to-one>

         </class>

实例化类1

package com.neusoft.test.entity;

 

public class Person4 {

         private   int personid;

         private   String name;

         private   int age;

         private   Address4 address;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

         public   Address4 getAddress() {

                   return   address;

         }

         public   void setAddress(Address4 address) {

                   this.address   = address;

         }

}

实例化类2

package com.neusoft.test.entity;

 

public class Address4 {

         private   int addressid;

         private   String addressdetail;

         private   Person4 person;

 

         public   Person4 getPerson() {

                   return   person;

         }

         public   void setPerson(Person4 person) {

                   this.person   = person;

         }

         public   int getAddressid() {

                   return   addressid;

         }

         public   void setAddressid(int addressid) {

                   this.addressid   = addressid;

         }

         public   String getAddressdetail() {

                   return   addressdetail;

         }

         public   void setAddressdetail(String addressdetail) {

                   this.addressdetail   = addressdetail;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.List;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Address4;

import com.neusoft.test.entity.Person4;

import com.neusoft.test.utils.HibernateUtil;

 

@SuppressWarnings("unchecked")

public class test4 {

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                   Person4   person=new Person4();

                   person.setName("uytua");

                   person.setAge(28);

                   Address4   address=new Address4();

                  

//                 新建一个地址,然后添加给person

                   address.setAddressdetail("wqesdasdasd");

                   address.setPerson(person);

                   person.setAddress(address);

                  

                   session.save(address);

                   session.save(person);

                   tx.commit();//   提交事务

                  

                   Query   query = session.createQuery("from Person4");

                   List<Person4>   list = query.list();

                   for   (Person4 p : list) {

                            System.out.println("id:"   + p.getPersonid() + "  姓名:" + p.getName()

                                               +   "  年龄:"   + p.getAge() + "  地址:"

                                               +   p.getAddress().getAddressdetail());

                   }

                   session.close();//   关闭session

         }

}

 

3 、继承映射

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念。Hibernate 的继承映射可以理解持久化类之间的继承关系。例如:人和学生之间的关系。学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到。

Hibernate支持三种继承映射策略:

每个具体类一张表(table per concrete class) 将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系开数据模型中考虑域模型中的继承关系和多态。

每个类分层结构一张表(table per class hierarchy) 对于继承关系中的子类使用同一个表,这就需要在数据库表中增加额外的区分子类类型的字段。

每个子类一张表(table per subclass) 域模型中的每个类映射到一个表,通过关系数据模型中的外键来描述表之间的继承关系。这也就相当于按照域模型的结构来建立数据库中的表,并通过外键来建立表之间的继承关系。

 

1 subclass 继承映射 ( 单表继承 )

采用 subclass 元素的继承映射可以实现对于继承关系中的子类使用同一个表。(所有父类和子类都映射同一个表)

在这种映射策略下,整个继承树的所有实例都保保存在同一个表内。因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到低是哪个类的实例----这个列被称为辨别者列(discriminator)

在这种映射策略下,使用 subclass 来映射子类,使用 discriminator-value 指定辨别者列的值。

新建数据库表person_table

映射配置:

<hibernate-mapping   package="com.neusoft.test.entity">

         <class   name="Person" table="person_table"   lazy="false">

                   <id   name="personid">

                            <generator />

                   </id>

                   <discriminator   column="type" type="string" />

                   <property   name="name" />

                   <property   name="age" />

                   <subclass   name="Student" discriminator-value="Student">

                            <property   name="school_name" />

                   </subclass>

                   <subclass   name="Worker" discriminator-value="Worker">

                            <property   name="company_name" />

                   </subclass>

         </class>

</hibernate-mapping>

实体类1

package com.neusoft.test.entity;

 

public class Person {

         private   int personid;

         private   String name;

         private   int age;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

实体类2

package com.neusoft.test.entity;

 

public class Student extends Person {

         private   String school_name;

 

         public   String getSchool_name() {

                   return   school_name;

         }

         public   void setSchool_name(String schoolName) {

                   school_name   = schoolName;

         }

}

实体类3

package com.neusoft.test.entity;

 

public class Worker extends Person {

         private   String company_name;

 

         public   String getCompany_name() {

                   return   company_name;

         }

         public   void setCompany_name(String companyName) {

                   company_name   = companyName;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.Iterator;

import java.util.List;

 

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Person;

import com.neusoft.test.entity.Student;

import com.neusoft.test.entity.Worker;

import com.neusoft.test.utils.HibernateUtil;

 

public class test {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                  

                   Person   person = new Person();

                   person.setName("小丽");

                   person.setAge(22);

                   Student   student = new Student();

                   student.setName("小明");

                   student.setAge(19);

                   student.setSchool_name("清华");

                   Worker   worker = new Worker();

                   worker.setName("小王");

                   worker.setAge(26);

                   worker.setCompany_name("neusoft");

                  

                   session.save(person);

                   session.save(student);

                   session.save(worker);

                   tx.commit();//   提交事务

 

                   List   personList = session.createQuery("from Person").list();

        for   (Iterator iter = personList.iterator(); iter.hasNext();) {

           Person a = (Person)iter.next();

           System.out.print(" 姓名:"+a.getName()+"  年龄:"+a.getAge()+"  职业:");

            //能够正确鉴别出正直的类型,HQL是支持多态查询的。

            if   (a instanceof Student) {

                  System.out.print("Student");

                                     Student   s=(Student)a;

                  System.out.println("  学校:"+s.getSchool_name());

            }   else if (a instanceof Worker) {

                  System.out.print("Worker");

                  Worker w=(Worker)a;

                  System.out.println("  公司:"+w.getCompany_name());

              }else

                  System.out.println("什么都不是");

        }

       

//        List   list = session.createQuery("from java.lang.Object").list();

//        for   (Iterator iter = list.iterator(); iter.hasNext();){

//              Object o =iter.next();

//              if (o instanceof Student) {

//                                   Student   s=(Student)o;

//                                   System.out.print("   姓名:"+s.getName()+"  年龄:"+s.getAge()+"  职业:");

//                                   System.out.print("Student");

//                  System.out.println("  学校:"+s.getSchool_name());

//            }   else if (o instanceof Worker) {

//                  Worker w=(Worker)o;

//                  System.out.print(" 姓名:"+w.getName()+"  年龄:"+w.getAge()+"  职业:");

//                  System.out.print("Worker");

//                  System.out.println("  公司:"+w.getCompany_name());

//              }else{

//              Person p=(Person)o;

//              System.out.print(" 姓名:"+p.getName()+"  年龄:"+p.getAge()+"  职业:");

//                  System.out.println("什么都不是");

//            }

//        }

                   session.close();//   关闭session

         }

}

 

2 joined-subclass 继承映射 (具体表继承)

采用 joined-subclass 元素的继承映射,每个类映射一个表。(父类映射一个表,每个子类也映射各自的表,子类表字段不是完全的)

对象模型不用变化,存储模型需要变化。

采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。

在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。但如果继承树的深度很深,可能查询一个子类实例时,需要跨越多个表,因为子类的数据一次保存在多个父类中。

子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中

新建数据库表person_table

student_table

worker_table

映射配置:

<class name="Person2"   table="person_table">

        <id   name="personid">

              <generator/>

          </id>

          <property name="name" />

                   <property   name="age" />

          <!--<joined-subclass>标签:继承映射 每个类映射成一个表 -->

          <joined-subclass name="Student2"   table="student_table">

                            <!--   <key>标签:会在相应的表(当前映射的表)里,加入一个外键 ,

                            参照指向当前类的父类(当前Class标签对象的表)-->

            <key column="id"/>

              <property name="school_name"/>

          </joined-subclass>

          <joined-subclass name="Worker2"   table="worker_table">

              <key column="id"/>

              <property name="company_name"/>

          </joined-subclass>

      </class>

实体类1

package com.neusoft.test.entity;

 

public class Person2 {

         private   int personid;

         private   String name;

         private   int age;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

实体类2

package com.neusoft.test.entity;

 

public class Student2 extends Person2 {

         private   String school_name;

 

         public   String getSchool_name() {

                   return   school_name;

         }

         public   void setSchool_name(String schoolName) {

                   school_name   = schoolName;

         }

}

实体类3

package com.neusoft.test.entity;

 

public class Worker2 extends Person2 {

         private   String company_name;

 

         public   String getCompany_name() {

                   return   company_name;

         }

         public   void setCompany_name(String companyName) {

                   company_name   = companyName;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.Iterator;

import java.util.List;

 

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.*;

import com.neusoft.test.utils.HibernateUtil;

 

public class test2 {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                  

                   Person2   person = new Person2();

                   person.setName("小丽");

                   person.setAge(22);

                   Student2   student = new Student2();

                   student.setName("小明");

                   student.setAge(19);

                   student.setSchool_name("清华");

                   Worker2   worker = new Worker2();

                   worker.setName("小王");

                   worker.setAge(26);

                   worker.setCompany_name("neusoft");

                  

                   session.save(person);

                   session.save(student);

                   session.save(worker);

                   tx.commit();//   提交事务

 

                   List   personList = session.createQuery("from Person2").list();

        for   (Iterator iter = personList.iterator(); iter.hasNext();) {

           Person2 a   = (Person2)iter.next();

           System.out.print(" 姓名:"+a.getName()+"  年龄:"+a.getAge()+"  职业:");

            //能够正确鉴别出正直的类型,HQL是支持多态查询的。

            if   (a instanceof Student2) {

                  System.out.print("Student");

                                     Student2   s=(Student2)a;

                  System.out.println("  学校:"+s.getSchool_name());

            }   else if (a instanceof Worker2) {

                  System.out.print("Worker");

                  Worker2 w=(Worker2)a;

                  System.out.println("  公司:"+w.getCompany_name());

              }else

                  System.out.println("什么都不是");

        }

                   session.close();//   关闭session

         }

}

3 union-subclass 继承映射(类表继承)

采用 union-subclass 元素可以实现将每一个实体对象映射到一个独立的表中。(父类映射一个表,每个子类映射各自的表,子类表的字段是完全的)

union-subclass joined-subclass 映射策略类似:子类增加的属性也可以有非空约束 --- 即父类实例的数据保存在父表中,而子类实例的数据保存在子类表中。

joined-subclass 不同的是,子类实例的数据仅保存在子类表中,而在父类表中没有任何记录。

在这种映射策略下,子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段加子类增加属性的总和

在这种映射策略下,既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键.

新建数据库表person_table

student_table

worker_table

映射配置:

<class name="Person3"   table="person_table">

        <id   name="personid">

              <generator/>

          </id>

          <property name="name" />

                   <property   name="age" />

        <!--   使用<union-subclass>标签来映射"每个具体类映射成一张表"的映射关系  -->

          <union-subclass name="Student3"   table="student_table">

              <property name="school_name"/>

          </union-subclass>

          <union-subclass name="Worker3"   table="worker_table">

              <property name="company_name"/>

          </union-subclass>

      </class>

实体类1

package com.neusoft.test.entity;

 

public class Person3 {

         private   int personid;

         private   String name;

         private   int age;

 

         public   int getPersonid() {

                   return   personid;

         }

         public   void setPersonid(int personid) {

                   this.personid   = personid;

         }

         public   String getName() {

                   return   name;

         }

         public   void setName(String name) {

                   this.name   = name;

         }

         public   int getAge() {

                   return   age;

         }

         public   void setAge(int age) {

                   this.age   = age;

         }

}

实体类2

package com.neusoft.test.entity;

 

public class Student3 extends Person3 {

         private   String school_name;

 

         public   String getSchool_name() {

                   return   school_name;

         }

         public   void setSchool_name(String schoolName) {

                   school_name   = schoolName;

         }

}

实体类3

package com.neusoft.test.entity;

 

public class Worker3 extends Person3 {

         private   String company_name;

 

         public   String getCompany_name() {

                   return   company_name;

         }

         public   void setCompany_name(String companyName) {

                   company_name   = companyName;

         }

}

测试类:

package com.neusoft.test.action;

 

import java.util.Iterator;

import java.util.List;

 

import org.hibernate.Session;

import org.hibernate.Transaction;

 

import com.neusoft.test.entity.Person3;

import com.neusoft.test.entity.Student3;

import com.neusoft.test.entity.Worker3;

import com.neusoft.test.utils.HibernateUtil;

 

public class test3 {

         @SuppressWarnings("unchecked")

         public   static void main(String args[]) {

                   Session   session = HibernateUtil.getSession();

                   //   开启事务

                   Transaction   tx = session.beginTransaction();

                  

                   Person3   person = new Person3();

                   person.setName("小丽");

                   person.setAge(22);

                   Student3   student = new Student3();

                   student.setName("小明");

                   student.setAge(19);

                   student.setSchool_name("清华");

                   Worker3   worker = new Worker3();

                   worker.setName("小王");

                   worker.setAge(26);

                   worker.setCompany_name("neusoft");

                  

                   session.save(person);

                   session.save(student);

                   session.save(worker);

                   tx.commit();//   提交事务

 

                   List   personList = session.createQuery("from Person3").list();

        for   (Iterator iter = personList.iterator(); iter.hasNext();) {

           Person3 a   = (Person3)iter.next();

           System.out.print(" 姓名:"+a.getName()+"  年龄:"+a.getAge()+"  职业:");

            //能够正确鉴别出正直的类型,HQL是支持多态查询的。

            if   (a instanceof Student3) {

                  System.out.print("Student");

                                     Student3   s=(Student3)a;

                  System.out.println("  学校:"+s.getSchool_name());

            } else if (a instanceof Worker3) {

                  System.out.print("Worker");

                  Worker3 w=(Worker3)a;

                  System.out.println("  公司:"+w.getCompany_name());

              }else

                  System.out.println("什么都不是");

        }

                   session.close();//   关闭session

         }

}

 

(4)三种继承关联映射的比较:

1、  第一种:它把所有的数据都存入一个表中,优点:效率好(操作的就是一个表);缺点:存在庸于字段,如果将庸于字段设置为非空,则就无法存入数据;

2、  第二种:层次分明,缺点:效率不好(表间存在关联表)

3、  第三种:主键字段不可以设置为自增主键生成策略。

建议使用第一种

 

 


你可能感兴趣的:(Hibernate,继承映射,关联关系映射,使用步骤,集合属性映射)