1. 程式人生 > >Hibernate: 三種狀態和CRUD四種操作

Hibernate: 三種狀態和CRUD四種操作

本篇部落格是初學hibernate時筆記總結,主要總結hibernate的三種狀態和hibernate的CRUD操作。

1. hibernate的三種狀態:

  • Transient State : 瞬時狀態;
  • Persistent State : 持久狀態;
  • Detached State : 離線狀態或託管狀態;
  • Transient State : 瞬時狀態:
    當我們new操作符初始化一個物件時,它處於瞬時態,也就是他沒有任何和資料庫表相關的行為,只要應用程式不再引用這些物件,它們狀態將會丟失,被jvm垃圾回收了。總結,這個物件,Session沒管理,資料庫中沒存。
  • Persistent State : 持久狀態 :
    持久化例項則是具有資料庫標識的例項,它由持久化管理器Session統一管理的,只要它的狀態發生改變,在事務提交時,會同步到資料庫中。
  • Detached State : 離線狀態或託管狀態 : 資料庫中有,但是session不管理了,

具體的分析推薦一篇部落格寫的很詳細,也很容易理解,

2.CRUD操作;

2.1 Bean物件

package com.qian.domain;

import java.util.Date;

public class User2 {
    private String user2Id;
    private String user2Name;
    private Date user2CreateDate;

    public String getUser2Id
() { return user2Id; } public void setUser2Id(String user2Id) { this.user2Id = user2Id; } public String getUser2Name() { return user2Name; } public void setUser2Name(String user2Name) { this.user2Name = user2Name; } public Date getUser2CreateDate
() { return user2CreateDate; } public void setUser2CreateDate(Date user2CreateDate) { this.user2CreateDate = user2CreateDate; } }

User2.hbm.xml檔案

<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ 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">

<hibernate-mapping package="com.qian.domain">

    <class name="User2" table="t_User2">
        <id name="user2Id" column="User2_ID">
            <generator class="uuid"/>
        </id>
        <property name="user2Name"/>
        <property name="user2CreateDate"/>

    </class>


</hibernate-mapping>

hibernate.cfg.xml檔案

<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ 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-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:ORCL</property>
        <property name="connection.username">scott</property>
        <property name="connection.password">qian</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

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

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup 
        <property name="hbm2ddl.auto">create</property>
        -->

        <mapping resource="com/qian/domain/User.hbm.xml"/>
        <mapping resource="com/qian/domain/User2.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

hbm2ddl類

package com.qian.envir;

import java.util.EnumSet;

import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;

/**
 * http://blog.csdn.net/qinshijangshan/article/details/53314230
 * http://bbs.csdn.net/topics/391942178?page=1
 * 參考網頁來分析所在版本的不同SchemaExport變化的集中方式,
 * <property name="hbm2ddl.auto">create</property>
 * @author Administrator
 *
 */
public class ExoprotDB {

    public static void main(String[] args) {

        StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();

        MetadataImplementor metadataImplementor = (MetadataImplementor) new MetadataSources(serviceRegistry)
                .buildMetadata();

        SchemaExport export = new SchemaExport();

        export.create(EnumSet.of(TargetType.DATABASE), metadataImplementor);

    }

}

HibernateUtil類

package com.qian.envir;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    //生成sessionFactory;
    static{
        final StandardServiceRegistry standardServiceRegistry = new
                StandardServiceRegistryBuilder().configure().build();
        try{
            sessionFactory = new MetadataSources(standardServiceRegistry)
                    .buildMetadata().buildSessionFactory();         
        }catch(Exception e){
            StandardServiceRegistryBuilder.destroy(standardServiceRegistry);
        }
    }

    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }

    public static Session getSession(){
        return sessionFactory.openSession();
    }

    public static void freeSession(Session session){
        if(session!=null){
            if(session.isOpen()){
                session.close();
            }
        }
    }
}

CRUD測試類程式碼

package test.qian;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.qian.domain.User2;
import com.qian.envir.HibernateUtil;

import junit.framework.TestCase;

public class CRUDTest extends TestCase {

    public void testCreate(){
        //step one:讀取hibernate.cfg.xml檔案拿到sessionFactory
        //由於sessionFactory相當於DB的映象,並且建立很花時間,我們可以寫一個工具類只建立一次;
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        Session session = null;
        Transaction transaction = null;

        try{
        //stpe two: 通過sessionFactroy拿到session
            session = sessionFactory.openSession();
        //step three: 開啟事務-->提交是否-->捕獲異常事務回滾
            transaction = session.getTransaction();
            transaction.begin();

        //step four: 寫新增使用者的測試程式碼
            User2 user2 = new User2();
            user2.setUser2Id("u2id");
            user2.setUser2Name("userName");
            user2.setUser2CreateDate(new Date());

        //step five: 儲存到資料庫中
            session.save(user2);

            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally{
        //step six: 無論成功與否釋放session
            HibernateUtil.freeSession(session);
        }

    }

    public void testReadByGet(){
        //step one:
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session =null;
        Transaction transaction = null;

        try{
            //step two:
            session = sessionFactory.openSession();
            //step three:
            transaction = session.getTransaction();
            transaction.begin();

            //step four:
            //get方法的第一個引數為 Class物件, 第二個引數為Serializable型別(key),也就是根據id查值
            //get方法獲取的物件是持久化物件,如果沒有找到則返回null,不會報錯。
            //發出get查詢,它就會馬上去資料庫中查詢,因為是持久化物件,如果我們改變了物件的屬性,在最後
            //的commit是,及時沒有update,Hibernate也會對照資料庫中的物件和記憶體中的物件,對資料進行更改;

            User2 user2 = session.get(User2.class, "402880da5e50fc2d015e50fc30b10000");
            if(user2!=null)
                System.out.println(user2.getUser2Name()+" : "+user2.getUser2CreateDate());

            //user2.setUser2Name("如果這裡對屬性操作,會同步到資料庫");

            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally{
            HibernateUtil.freeSession(session);
        }
    }

    public void testReadByLoad(){
        //step one:
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session =null;
        Transaction transaction = null;

        try{
            //step two:
            session = sessionFactory.openSession();
            //step three:
            transaction = session.getTransaction();
            transaction.begin();

            //step four:
            //load方法的第一個引數為 Class物件, 第二個引數為Serializable型別(key),也就是根據id查值
            //load方法獲取的物件是持久化物件,如果沒有找到則丟擲物件沒找到異常。
            //發出load查詢,它不會馬上去資料庫中查詢,而是建立一個User2的代理物件,當真正用的時候才會
            //向資料庫發出查詢語句。也就是load使用CGLIB的動態代理來實現懶載入的。
            //的commit是,及時沒有update,Hibernate也會對照資料庫中的物件和記憶體中的物件,對資料進行更改;

            User2 user2 = session.load(User2.class, "402880da5e50fc2d015e50fc30b10000");

            System.out.println(user2.getUser2Name()+" : "+user2.getUser2CreateDate());

            user2.setUser2Name("如果持久化物件 對屬性操作,會同步到資料庫");

            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally{
            HibernateUtil.freeSession(session);
        }
    }

    public void testUpdate(){
        //step one:
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session =null;
        Transaction transaction = null;

        try{
        //step two:
            session = sessionFactory.openSession();
        //step three:
            transaction = session.getTransaction();
            transaction.begin();

        //step four:
            User2 user2 = session.load(User2.class, "402880da5e50fc2d015e50fc30b10000");
            user2.setUser2Name("zhangSan");
        //step five:
            session.update(user2);

            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally{
            HibernateUtil.freeSession(session);
        }
    }

    public void testDelete(){
        //step one:
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session =null;
        Transaction transaction = null;

        try{
            //step two:
            session = sessionFactory.openSession();
            //step three:
            transaction = session.getTransaction();
            transaction.begin();

            //step four:
            User2 user2 = session.load(User2.class, "402880da5e50fc2d015e50fc30b10000");
            session.delete(user2);
            System.out.println("delete successfully");

            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally{
            HibernateUtil.freeSession(session);
        }
    }
}