Heibernate学习

Heibernate学习

Hibernate 映射类型

映射类型

当你准备一个 Hibernate 映射文件时,我们已经看到你把 Java 数据类型映射到了 RDBMS 数据格式。在映射文件中已经声明被使用的 types 不是 Java 数据类型;它们也不是 SQL 数据库类型。这种类型被称为 Hibernate 映射类型,可以从 Java 翻译成 SQL,反之亦然。

在这一章中列举出所有的基础,日期和时间,大型数据对象,和其它内嵌的映射数据类型。

原始类型

映射类型 Java 类型 ANSI SQL 类型
integer int 或 java.lang.Integer INTEGER
long long 或 java.lang.Long BIGINT
short short 或 java.lang.Short SMALLINT
float float 或 java.lang.Float FLOAT
double double 或 java.lang.Double DOUBLE
big_decimal java.math.BigDecimal NUMERIC
character java.lang.String CHAR(1)
string java.lang.String VARCHAR
byte byte 或 java.lang.Byte TINYINT
boolean boolean 或 java.lang.Boolean BIT
yes/no boolean 或 java.lang.Boolean CHAR(1) ('Y' or 'N')
true/false boolean 或 java.lang.Boolean CHAR(1) ('T' or 'F')

日期和时间类型

映射类型 Java 类型 ANSI SQL 类型
date java.util.Date 或 java.sql.Date DATE
time java.util.Date 或 java.sql.Time TIME
timestamp java.util.Date 或 java.sql.Timestamp TIMESTAMP
calendar java.util.Calendar TIMESTAMP
calendar_date java.util.Calendar DATE

二进制和大型数据对象

映射类型 Java 类型 ANSI SQL 类型
binary byte[] VARBINARY (or BLOB)
text java.lang.String CLOB
serializable any Java class that implements java.io.Serializable VARBINARY (or BLOB)
clob java.sql.Clob CLOB
blob java.sql.Blob BLOB

JDK 相关类型

映射类型 Java 类型 ANSI SQL 类型
class java.lang.Class VARCHAR
locale java.util.Locale VARCHAR
timezone java.util.TimeZone VARCHAR
currency java.util.Currency VARCHAR

haibernate Mapping.hbm.xml 配置

<?xml version="1.0"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!--
    This mapping demonstrates the use of Hibernate with all-handwritten SQL!
     
    NOTE: this version is for SQLServer
-->
<hibernate-mapping package="com.hx.entity" default-access="field">

    <class name="Regions" table="regions">
        <id name="regionId" column="region_id">
            <generator class="native"/>
        </id>
        <set name="countries" table="countries"  inverse="true"><!--设置外键的表-->
            <key>
                <column name="region_id" ></column><!--本表外键的字段-->
            </key>
            <one-to-many class="Countries"></one-to-many><!--外键的类型-->

        </set>


        <property name="regionName" column="region_name"/>
    </class>
    <class name="Jobs" table="jobs">
        <id name="jobId"  column="Job_id">
            <generator class="native"></generator>
        </id>
        <property name="jobTitle" column="job_title"></property>
        <property name="maxSalary" column="max_salary"></property>
        <property name="minSalary" column="min_salary"></property>
    </class>
    <class name="Cups" table="cups">
        <id name="CupId" column="cup_Id" >
            <generator  class="native"/>
        </id>

        <property name="CupName"  column="Cup_Name"/>
    </class>
    <class name="Countries" table="countries">
        <id name="countryId" column="country_id">
            <generator class="native"></generator>
        </id>
        <property name="countryName" column="country_name"></property>
        <property name="regionId" column="region_id"></property>

        <many-to-one name="regions" class="Regions" column="region_Id" entity-name="Regions" ></many-to-one>
    </class>

    <!--
    <class name="Person" table="PERSON">
        <id name="id" unsaved-value="0" column="PERID">
            <generator class="increment"/>
        </id>
        <property name="name" not-null="true" column="NAME"/>
        <loader query-ref="person"/>
        <sql-insert>INSERT INTO PERSON (NAME, PERID) VALUES ( UPPER(?), ? )</sql-insert>
        <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE PERID=?</sql-update>
        <sql-delete>DELETE FROM PERSON WHERE PERID=?</sql-delete>
    </class>
    
    <class name="Employment" table="EMPLOYMENT">
        <id name="employmentId" unsaved-value="0" column="EMPID">
            <generator class="increment"/>
        </id>
        <many-to-one name="employee" column="EMPLOYEE" not-null="true" update="false"/>
        <many-to-one name="employer" column="EMPLOYER" not-null="true" update="false"/>
        <property name="startDate" column="STARTDATE" not-null="true" update="false" insert="false"/>
        <property name="endDate" column="ENDDATE" insert="false"/>
        <property name="regionCode" column="REGIONCODE" update="false"/>
        <property name="salary" type="org.hibernate.test.sql.hand.MonetaryAmountUserType">
            <column name="VALUE" sql-type="float"/>
            <column name="CURRENCY"/>           
        </property>
        <loader query-ref="employment"/>
        <sql-insert>
            INSERT INTO EMPLOYMENT 
                (EMPLOYEE, EMPLOYER, STARTDATE, REGIONCODE, VALUE, CURRENCY, EMPID) 
                VALUES (?, ?, getdate(), UPPER(?), ?, ?, ?)
        </sql-insert>
        <sql-update>UPDATE EMPLOYMENT SET ENDDATE=?, VALUE=?, CURRENCY=? WHERE EMPID=?</sql-update> 
        <sql-delete>DELETE FROM EMPLOYMENT WHERE EMPID=?</sql-delete> 
    </class>

    <class name="TextHolder">
        <id name="id" column="id">
            <generator class="increment"/>
        </id>
        <property name="description" type="text" length="15000"/>
        <loader query-ref="textholder"/>
        <sql-insert>
            INSERT INTO TEXTHOLDER
            (DESCRIPTION, ID)
            VALUES (?, ?)
        </sql-insert>
        <sql-update>UPDATE TEXTHOLDER SET DESCRIPTION=? WHERE ID=?</sql-update>
        <sql-delete>DELETE FROM TEXTHOLDER WHERE ID=?</sql-delete>
    </class>

    <class name="ImageHolder">
        <id name="id" column="id">
            <generator class="increment"/>
        </id>
        <property name="photo" type="image" length="15000"/>
        <loader query-ref="imageholder"/>
        <sql-insert>
            INSERT INTO IMAGEHOLDER
            (PHOTO, ID)
            VALUES (?, ?)
        </sql-insert>
        <sql-update>UPDATE IMAGEHOLDER SET PHOTO=? WHERE ID=?</sql-update>
        <sql-delete>DELETE FROM IMAGEHOLDER WHERE ID=?</sql-delete>
    </class>

    <resultset name="org-emp-regionCode">
        <return-scalar column="regionCode" type="string"/>
        <return alias="org" class="Organization"/>
        <return-join alias="emp" property="org.employments"/>
    </resultset>

    <resultset name="org-emp-person">
        <return alias="org" class="Organization"/>
        <return-join alias="emp" property="org.employments"/>
        <return-join alias="pers" property="emp.employee"/>
    </resultset>
    
    <sql-query name="person">
        <return alias="p" class="Person" lock-mode="upgrade"/>
        SELECT NAME AS {p.name}, PERID AS {p.id} FROM PERSON WHERE PERID=? /*FOR UPDATE*/
    </sql-query>

    <sql-query name="organization">
        <return alias="org" class="Organization"/>
        <return-join alias="emp" property="org.employments"/>
        SELECT {org.*}, {emp.*}
        FROM ORGANIZATION org
            LEFT OUTER JOIN EMPLOYMENT emp ON org.ORGID = emp.EMPLOYER
        WHERE org.ORGID=?
    </sql-query>


    &lt;!&ndash;sql-query name="organization">
        <return alias="org" class="Organization"/>
        SELECT NAME AS {org.name}, ORGID AS {org.id} FROM ORGANIZATION
        WHERE ORGID=?
    </sql-query&ndash;&gt;
    
    <sql-query name="allOrganizationsWithEmployees" flush-mode="never">
        <return alias="org" class="Organization"/>
        SELECT DISTINCT org.NAME AS {org.name}, org.ORGID AS {org.id} 
        FROM ORGANIZATION org
        INNER JOIN EMPLOYMENT e ON e.EMPLOYER = org.ORGID
    </sql-query>
    
    
    

    
    <sql-query name="employment">
        <return alias="emp" class="Employment"/>
        SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, 
            STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
            REGIONCODE as {emp.regionCode}, EMPID AS {emp.id}
        FROM EMPLOYMENT
        WHERE EMPID = ?
    </sql-query>

    <sql-query name="organizationEmployments">
        <load-collection alias="empcol" role="Organization.employments"/>
        SELECT {empcol.*}
        FROM EMPLOYMENT empcol
        WHERE EMPLOYER = :id
        ORDER BY STARTDATE ASC, EMPLOYEE ASC
    </sql-query>


    <sql-query name="organizationCurrentEmployments">
        <return alias="emp" class="Employment">         
            <return-property name="salary"> 
              &lt;!&ndash; as multi column properties are not supported via the
              {}-syntax, we need to provide an explicit column list for salary via <return-property> &ndash;&gt;
              <return-column name="`VALUE`"/>
              <return-column name="CURRENCY"/>          
            </return-property>
            &lt;!&ndash; Here we are remapping endDate. Notice that we can still use {emp.endDate} in the SQL. &ndash;&gt;
            <return-property name="endDate" column="myEndDate"/>
        </return>
        <synchronize table="EMPLOYMENT"/>
        SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, 
            STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
            REGIONCODE as {emp.regionCode}, EMPID AS {emp.id}, VALUE, CURRENCY
        FROM EMPLOYMENT
        WHERE EMPLOYER = :id AND ENDDATE IS NULL
        ORDER BY STARTDATE ASC
    </sql-query>

    <sql-query name="simpleScalar" callable="true">
        <return-scalar column="name" type="string"/>
        <return-scalar column="`value`" type="long"/>
        { call simpleScalar(:number) }
    </sql-query>

    <sql-query name="paramhandling" callable="true">
        <return-scalar column="`value`" type="long"/>
        <return-scalar column="value2" type="long"/>
        { call paramHandling(?,?) }
    </sql-query>

    <sql-query name="paramhandling_mixed" callable="true">
        <return-scalar column="`value`" type="long" />
        <return-scalar column="value2" type="long" />
        { call paramHandling(?,:second) }
    </sql-query>
    
    <sql-query name="selectAllEmployments" callable="true">
        <return alias="" class="Employment">
            <return-property name="employee" column="EMPLOYEE"/>
            <return-property name="employer" column="EMPLOYER"/>            
            <return-property name="startDate" column="STARTDATE"/>
            <return-property name="endDate" column="ENDDATE"/>          
            <return-property name="regionCode" column="REGIONCODE"/>            
            <return-property name="id" column="EMPID"/>                     
            <return-property name="salary"> 
                &lt;!&ndash; as multi column properties are not supported via the
                {}-syntax, we need to provide an explicit column list for salary via <return-property> &ndash;&gt;
                <return-column name="`VALUE`"/>
                <return-column name="CURRENCY"/>            
            </return-property>
        </return>
        { call selectAllEmployments() }
    </sql-query>

    <sql-query name="textholder">
        <return alias="h" class="TextHolder" lock-mode="upgrade"/>
        SELECT ID AS {h.id}, DESCRIPTION AS {h.description} FROM TEXTHOLDER WHERE ID=? /*FOR UPDATE*/
    </sql-query>

    <sql-query name="imageholder">
        <return alias="h" class="ImageHolder" lock-mode="upgrade"/>
        SELECT ID AS {h.id}, PHOTO AS {h.photo} FROM IMAGEHOLDER WHERE ID=? /*FOR UPDATE*/
    </sql-query>
    
    <database-object>
        <create>
        CREATE PROCEDURE selectAllEmployments AS
            SELECT EMPLOYEE, EMPLOYER, STARTDATE, ENDDATE, 
            REGIONCODE, EMPID, VALUE, CURRENCY
            FROM EMPLOYMENT
        </create>
        <drop>
        DROP PROCEDURE selectAllEmployments
        </drop>
    </database-object>

    &lt;!&ndash; The following is a workaround for HHH-3685 so that SchemaExport &ndash;&gt;
    &lt;!&ndash; changes the transaction mode of selectAllEmployments to "chained" &ndash;&gt;
    <database-object>
        <create>
        sp_procxmode selectAllEmployments, 'chained'
        </create>
        &lt;!&ndash; no drop command corresponding to "sp_procxmode ..." &ndash;&gt;
        <drop/>
    </database-object>

    <database-object>
        <create>
        CREATE PROCEDURE paramHandling @j int, @i int AS
            SELECT @j as value, @i as value2
        </create>
        <drop>
        DROP PROCEDURE paramHandling
        </drop>
    </database-object>
    
    &lt;!&ndash; The following is a workaround for HHH-3685 so that SchemaExport &ndash;&gt;
    &lt;!&ndash; changes the transaction mode of paramHandling to "chained" &ndash;&gt;
    <database-object>
        <create>
        sp_procxmode paramHandling, 'chained'
        </create>
        &lt;!&ndash; no drop command corresponding to "sp_procxmode ..." &ndash;&gt;
    <drop/>
    </database-object>

    <database-object>
        <create>
        CREATE PROCEDURE simpleScalar @number int AS
            SELECT @number as value, 'getAll' as name
        </create>
        <drop>
        DROP PROCEDURE simpleScalar
        </drop>
    </database-object>
    
    &lt;!&ndash; The following is a workaround for HHH-3685 so that SchemaExport &ndash;&gt;
    &lt;!&ndash; changes the transaction mode of simpleScalar to "chained" &ndash;&gt;
    <database-object>
        <create>
        sp_procxmode simpleScalar, 'chained'
        </create>
        &lt;!&ndash; no drop command corresponding to "sp_procxmode ..." &ndash;&gt;
        <drop/>
    </database-object>
-->
</hibernate-mapping>

hibernate 注解的使用

Hibernate 检测到 @Id 注释字段并且认定它应该在运行时通过字段直接访问一个对象上的属性。如果你将 @Id 注释放在 getId() 方法中,你可以通过默认的 getter 和 setter 方法来访问属性。因此,所有其它注释也放在字段或是 getter 方法中,决定于选择的策略。下一节将解释上面的类中使用的注释。

@Entity 注释

EJB 3 标准的注释包含在 javax.persistence 包,所以我们第一步需要导入这个包。第二步我们对 Employee 类使用 @Entity 注释,标志着这个类为一个实体 bean,所以它必须含有一个没有参数的构造函数并且在可保护范围是可见的。

@Table 注释

@table 注释允许您明确表的详细信息保证实体在数据库中持续存在。

@table 注释提供了四个属性,允许您覆盖的表的名称,目录及其模式,在表中可以对列制定独特的约束。现在我们使用的是表名为 EMPLOYEE。

@Id 和 @GeneratedValue 注释

每一个实体 bean 都有一个主键,你在类中可以用 @Id 来进行注释。主键可以是一个字段或者是多个字段的组合,这取决于你的表的结构。

默认情况下,@Id 注释将自动确定最合适的主键生成策略,但是你可以通过使用 @GeneratedValue 注释来覆盖掉它。strategygenerator 这两个参数我不打算在这里讨论,所以我们只使用默认键生成策略。让 Hibernate 确定使用哪些生成器类型来使代码移植于不同的数据库之间。

@Column Annotation

@Column 注释用于指定某一列与某一个字段或是属性映射的细节信息。您可以使用下列注释的最常用的属性:

  • name 属性允许显式地指定列的名称。
  • length 属性为用于映射一个值,特别为一个字符串值的列的大小。
  • nullable 属性允许当生成模式时,一个列可以被标记为非空。
  • unique 属性允许列中只能含有唯一的内容

在java类中的使用

@Entity
public class Employees {
    @Id
    @Column(name = "EMPLOYEE_ID")
    private Integer employeeId;
    @Column(name = "FIRST_NAME")
    private String fristName;
    @Column(name = "LAST_NAME")
    private String lastName;
    @Column(name = "EMAIL")
    private String emall;
    @Column(name = "PHONE_NUMBER")
    private String phineNumber;
    @Column(name = "HIRE_DATE")
    private Timestamp hireDate;
    @ManyToOne(targetEntity = Jobs.class,fetch = FetchType.LAZY)//设置映射
    @JoinColumn(name = "job_id")
    private  Jobs job;
    @Column(name = "SALARY")
    private BigDecimal salary;
    @Column(name = "COMMISSION_PCT")
    private BigDecimal commissionPct;
    @Column(name = "MANAGER_ID")
    private Integer managerId;
    @Column(name = "DEPARTMENT_ID")
    private Integer departmentId;
    
    @Entity
public class Jobs {
    @Id
    @Column(name = "JOB_ID")
    private String jobId;
    @Column(name = "JOB_TITLE")
    private String jobTitle;
    @Column(name = "MIN_SALARY")
    private BigDecimal minSalary;
    @Column(name = "MAX_SALARY")
    private BigDecimal maxSalaty;

Hibernate 拦截器

由 北公爵无欢 创建, 最后一次修改 2016-08-12

拦截器

你已经学到,在 Hibernate 中,一个对象将被创建和保持。一旦对象已经被修改,它必须被保存到数据库里。这个过程持续直到下一次对象被需要,它将被从持久的存储中加载。

因此一个对象通过它生命周期中的不同阶段,并且 Interceptor 接口提供了在不同阶段能被调用来进行一些所需要的任务的方法。这些方法是从会话到应用程序的回调函数,允许应用程序检查或操作一个持续对象的属性,在它被保存,更新,删除或上传之前。以下是在 Interceptor 接口中可用的所有方法的列表。

S.N. 方法和描述
1 findDirty() 这个方法在当 flush() 方法在一个 Session 对象上被调用时被调用。
2 instantiate() 这个方法在一个持续的类被实例化时被调用。
3 isUnsaved() 这个方法在当一个对象被传到 saveOrUpdate() 方法时被调用。
4 onDelete() 这个方法在一个对象被删除前被调用。
5 onFlushDirty() 这个方法在当 Hibernate 探测到一个对象在一次 flush(例如,更新操作)中是脏的(例如,被修改)时被调用。
6 onLoad() 这个方法在一个对象被初始化之前被调用。
7 onSave() 这个方法在一个对象被保存前被调用。
8 postFlush() 这个方法在一次 flush 已经发生并且一个对象已经在内存中被更新后被调用。
9 preFlush() 这个方法在一次 flush 前被调用。

Hibernate 拦截器给予了我们一个对象如何应用到应用程序和数据库的总控制。

如何使用拦截器?

为了创建一个拦截器你可以直接实现 Interceptor 类或者继承 EmptyInterceptor 类。以下是简单的使用 Hibernate 拦截器功能的步骤。

创建拦截器

我们将在例子中继承 EmptyInterceptor,当 Employee 对象被创建和更新时拦截器的方法将自动被调用。你可以根据你的需求实现更多的方法。

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class MyInterceptor extends EmptyInterceptor {
   private int updates;
   private int creates;
   private int loads;

   public void onDelete(Object entity,
                     Serializable id,
                     Object[] state,
                     String[] propertyNames,
                     Type[] types) {
       // do nothing
   }

   // This method is called when Employee object gets updated.
   public boolean onFlushDirty(Object entity,
                     Serializable id,
                     Object[] currentState,
                     Object[] previousState,
                     String[] propertyNames,
                     Type[] types) {
       if ( entity instanceof Employee ) {
          System.out.println("Update Operation");
          return true; 
       }
       return false;
   }
   public boolean onLoad(Object entity,
                    Serializable id,
                    Object[] state,
                    String[] propertyNames,
                    Type[] types) {
       // do nothing
       return true;
   }
   // This method is called when Employee object gets created.
   public boolean onSave(Object entity,
                    Serializable id,
                    Object[] state,
                    String[] propertyNames,
                    Type[] types) {
       if ( entity instanceof Employee ) {
          System.out.println("Create Operation");
          return true; 
       }
       return false;
   }
   //called before commit into database
   public void preFlush(Iterator iterator) {
      System.out.println("preFlush");
   }
   //called after committed into database
   public void postFlush(Iterator iterator) {
      System.out.println("postFlush");
   }
}

创建 POJO 类

现在让我们稍微修改我们的第一个例子,我们使用 EMPLOYEE 表单和 Employee 类:

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;
   }
}

创建数据库表

第二步将是在你的数据库中创建表。一张表对应每个你提供持久性的对象。考虑以上的对象需要被存储和检索到以下的 RDBM 表中:

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)
);

创建 Mapping 配置文件

这个步骤是来创建一个指导 Hibernate 如何将定义的类或者多个类映射到数据库表单中的映射文件。

<?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>

创建 Application 类

最后,我们将用 main() 创建 application 类来运行应用程序。这里应该注意当创建 session 对象时我们使用 Interceptor 类作为参数。

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 

import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.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( new MyInterceptor() );
      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( new MyInterceptor() );
      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( new MyInterceptor() );
      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( new MyInterceptor() );
      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(); 
      }
   }
}

编译和执行

这里是编译和运行上面提及的应用程序的步骤。确保你已经在处理编译和执行前正确设置了 PATH 和 CLASSPATH。

  • 创建在 configuration 章节中解释的 hibernate.cfg.xml 配置文件。
  • 创建如上所示的 Employee.hbm.xml 映射文件。
  • 创建如上所示的 Employee.java 源文件并编译。
  • 创建如上所示的 MyInterceptor.java 源文件并编译。
  • 创建如上所示的 ManageEmployee.java 源文件并编译。
  • 执行 ManageEmployee 来运行程序。

你将得到以下结果,而且记录将在 EMPLOYEE 表单中被创建。

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush
preFlush
Update Operation
postFlush
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush

如果你检查你的 EMPLOYEE 表单,它应该有如下结果:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
mysql>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persi...
    大同若鱼阅读 4,258评论 4 27
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,287评论 0 4
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,618评论 0 10
  • 立秋了。 似乎真的气温降了下来,秋高气爽,湛蓝的天,清透的,火红的云,燃烧着夏天最后的热度,云渐渐的灰了下去,月亮...
    听雷雷说阅读 151评论 0 0