Hibernate框架简介

2018-03-30  本文已影响265人  01_小小鱼_01

Hibernate 是由 Gavin King 于 2001 年创建的开放源代码的对象关系框架。它强大且高效的构建具有关系对象持久性和查询服务的 Java 应用程序。Hibernate 将Java类映射到数据表中从Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95%的公共数据持续性编程工作中解放出来。

Hibernate 优势

Hibernate 应用程序架构视图

image

下面是一个详细的 Hibernate 应用程序体系结构视图以及一些重要的类。


image
  1. 配置对象
    配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化期间创造。它代表了 Hibernate 所需一个配置或属性文件。配置对象提供了两种基础组件。
  1. SessionFactory 对象
    配置对象被用于创造一个 SessionFactory 对象,使用提供的配置文件为应用程序依次配置 Hibernate,并允许实例化一个会话对象。SessionFactory 是一个线程安全对象并由应用程序所有的线程所使用。
    SessionFactory 是一个重量级对象所以通常它都是在应用程序启动时创造然后留存为以后使用。每个数据库需要一个 SessionFactory 对象使用一个单独的配置文件。所以如果你使用多种数据库那么你要创造多种 SessionFactory 对象。

  2. Session 对象
    一个会话被用于与数据库的物理连接。Session 对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。持久对象通过 Session 对象保存和检索。
    Session 对象不应该长时间保持开启状态因为它们通常情况下并非线程安全,并且它们应该按照所需创造和销毁。

  3. Transaction 对象
    一个事务代表了与数据库工作的一个单元并且大部分 RDBMS 支持事务功能。在 Hibernate 中事务由底层事务管理器和事务(来自 JDBC 或者 JTA)处理。
    这是一个选择性对象,Hibernate 应用程序可能不选择使用这个接口,而是在自己应用程序代码中管理事务。

  4. Query 对象
    Query 对象使用 SQL 或者 Hibernate 查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。

  5. Criteria 对象
    Criteria 对象被用于创造和执行面向规则查询的对象来检索对象。

会话

Session 用于获取与数据库的物理连接。 Session 对象是轻量级的,并且设计为在每次需要与数据库进行交互时被实例化。持久态对象被保存,并通过 Session 对象检索找回。

该 Session 对象不应该长时间保持开放状态,因为它们通常不能保证线程安全,而应该根据需求被创建和销毁。Session 的主要功能是为映射实体类的实例提供创建,读取和删除操作。这些实例可能在给定时间点时存在于以下三种状态之一:

image
Session session = factory.openSession();
Transaction tx = null;
try {
   tx = session.beginTransaction();
   // do some work
   ...
   tx.commit();
}
catch (Exception e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
}finally {
   session.close();
}

持久化类

在 Hibernate 中,其对象或实例将会被存储在数据库表单中的 Java 类被称为持久化类。

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

映射文件

一个对象/关系型映射一般定义在 XML 文件中。映射文件指示 Hibernate 如何将已经定义的类或类组与数据库中的表对应起来。
Employee.hbm.xml

create table EMPLOYEE (
    id INT NOT NULL auto_increment,
    first_name VARCHAR(20) default NULL,
    last_name  VARCHAR(20) default NULL,
    salary     INT  default NULL,
    PRIMARY KEY (id)
);

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
      <property name="salary" column="salary" type="int"/>
   </class>
</hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping resource="com/hibernate/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

操作数据库

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      try{
         factory = new Configuration().configure().buildSessionFactory();
      }catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      try{
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
      return employeeID;
   }
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = 
                           employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee = 
                    (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
         session.update(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee = 
                   (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
}

注释

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

   public Employee() {}
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

创建应用类

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      try{
         factory = new AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   buildSessionFactory();
      }catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      try{
         tx = session.beginTransaction();
         Employee employee = new Employee();
         employee.setFirstName(fname);
         employee.setLastName(lname);
         employee.setSalary(salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
      return employeeID;
   }
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = 
                           employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee = 
                    (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
         session.update(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Employee employee = 
                   (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
}

缓存

关联关系

//开发人员信息  
public class Developer {  
    private Integer d_id;//开发人员编号  
    private String d_name;//开发人员姓名  
    //开发人员参与的多个项目  
    private Set<Project> projects=new HashSet<Project>();  
    public Integer getD_id() {  
        return d_id;  
    }  
    public void setD_id(Integer d_id) {  
        this.d_id = d_id;  
    }  
    public String getD_name() {  
        return d_name;  
    }  
    public void setD_name(String d_name) {  
        this.d_name = d_name;  
    }  
    public Set<Project> getProjects() {  
        return projects;  
    }  
    public void setProjects(Set<Project> projects) {  
        this.projects = projects;  
    }
}

public class Project {  
    private Integer prj_id;//项目编号  
    private String prj_name;//项目名称  
    //项目下的多个员工  
    private Set<Developer> developers=new HashSet<Developer>();  
    public Integer getPrj_id() {  
        return prj_id;  
    }  
    public void setPrj_id(Integer prj_id) {  
        this.prj_id = prj_id;  
    }  
    public String getPrj_name() {  
        return prj_name;  
    }  
    public void setPrj_name(String prj_name) {  
        this.prj_name = prj_name;  
    }  
    public Set<Developer> getDevelopers() {  
        return developers;  
    }  
    public void setDevelopers(Set<Developer> developers) {  
        this.developers = developers;  
    }
}

<!-- Developer.hbm.xml -->
<hibernate-mapping package="cn.itcast.c_many2many">  
    <class name="Developer" table="t_developer">  
        <id name="d_id">  
           <generator class="native"></generator>  
        </id>  
        <property name="d_name"></property>  
         
        <set name="projects" table="t_relation">  
           <key column="did"></key>  
           <many-to-many column="prjId" class="Project"></many-to-many>  
        </set>
    </class>  
</hibernate-mapping>  

<!-- Project.hbm.xml -->
<hibernate-mapping package="cn.itcast.c_many2many">  
    <class name="Project" table="t_project">  
        <id name="prj_id">  
           <generator class="native"></generator>  
        </id>  
        <property name="prj_name"></property>  
          
         <!-- 多对多映射:  
             1.映射的集合属性:developers  
             2.集合属性:对应的中间表,t_relation  
             3.外键字段:prjid  
             4.外键字段:对应的中间表字段,did  
             5.集合属性元素的类型 -->  
        <set name="developers" table="t_relation">  
            <key column="prjId"></key>  
            <many-to-many column="did" class="Developer"></many-to-many>  
        </set> 
    </class>  
</hibernate-mapping>  

查询语言

Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。

// FROM 语句
String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

// AS 语句
String hql = "FROM Employee AS E";
// String hql = "FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

// SELECT 语句
String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

// WHERE 语句
String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

//ORDER BY 语句
String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
//String hql = "FROM Employee E WHERE E.id > 10 " +
             "ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();

// GROUP BY 语句
String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " + "GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

// 使用命名参数
String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

// UPDATE 语句
String hql = "UPDATE Employee set salary = :salary "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

// DELETE 语句
String hql = "DELETE FROM Employee "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

// INSERT 语句
String hql = "INSERT INTO Employee(firstName, lastName, salary)"  + 
             "SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

//聚合方法
方法  描述
avg(property name)  属性的平均值
count(property name or *)   属性在结果中出现的次数
max(property name)  属性值的最大值
min(property name)  属性值的最小值
sum(property name)  属性值的总和

// distinct 关键字表示只计算行集中的唯一值。下面的查询只计算唯一的值:
String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

// 使用分页查询
String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();

批处理

为了使用批处理这个特性,首先设置 hibernate.jdbc.batch_size 作为批处理的尺寸,取一个依赖于对象尺寸的值 20 或 50。这将告诉 hibernate 容器每 X 行为一批插入。

<property name="hibernate.jdbc.batch_size">50</property>

更多内容

1. Hibernate实体关系映射
2. Hibernate延迟加载
3. Hibernate配置文件详解-1
4. Hibernate配置文件详解-2
5. Hibernate HQL详解

上一篇 下一篇

猜你喜欢

热点阅读