<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    注銷

    注銷

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      112 隨筆 :: 7 文章 :: 18 評(píng)論 :: 0 Trackbacks
    一、首先學(xué)習(xí)hibernate.cfg.xml配置文件的具體配置
    <?xml version="1.0" encoding="UTF-8"?>

    <!--指定該文件的官方dtd-->
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
    <hibernate-configuration>
      <session-factory>
        <!-- 顯示sql語(yǔ)言 -->
        <property name="show_sql">true</property>
        <!-- sql語(yǔ)言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- jdbc驅(qū)動(dòng)程式 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- jdbc url -->
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <!-- 數(shù)據(jù)庫(kù)用戶名 -->
        <property name="connection.username">root</property>
        <!-- 數(shù)據(jù)庫(kù)密碼 -->
        <property name="connection.password">wyq</property>
        <!-- C3P0連接池設(shè)定 -->
        <!--最小連接數(shù)-->
        <property name="c3p0.min_size">5</property>
        <!--最大連接數(shù)-->
        <property name="c3p0.max_size">20</property>
       <!--延遲所允許的時(shí)間-->
        <property name="c3p0.timeout">1800</property>
       <!--緩存所允許的最大連接數(shù)-->
        <property name="c3p0.max_statements">50</property>
        <!-- 每隔100筆資料送入資料庫(kù),清除緩存(定期清除緩存,減小壓力) -->
        <property name="hibernate.jdbc.batch_size">100</property>
        <!-- 設(shè)定事務(wù)管理的工廠類 -->
        <property name="hibernate.transaction.factiory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
       <mapping resource="com/wyq/hibernate/pojo/User.hbm.xml"/>
       <mapping resource="com/wyq/hibernate/pojo/TUser.hbm.xml"/>
       <mapping resource="com/wyq/hibernate/pojo/Room.hbm.xml"/>
      </session-factory>
    </hibernate-configuration>
    需要的jar包有c3p0.jar,hibernate3.jar,數(shù)據(jù)庫(kù).jar,log4j.jar


    ------------------------------------------------------------------------------------------------------------------------

    1、讀取配置文件獲得連接
       讀取hibernate.cfg.xml配置文件,hibernate.cfg.xml文件放在Classpath下,使用下面的方式讀入該文件
          //Configuration 負(fù)責(zé)管理hibernate配置信息
          Configuration config=new Configuration().configure();
          //根據(jù)config建立SessionFactory
          //SessionFactory用于建立Session
          SessionFactory sessionFactory=config.buildSessionFactory();
          //開啟session,相當(dāng)于jdbc的Connection
          session = sessionFactory.openSession();

    2、Criteria 基本資料查詢
    (1)標(biāo)準(zhǔn)查詢:
          //創(chuàng)建查詢標(biāo)準(zhǔn)
          Criteria criteria=session.creteCriteria(User.class);
          //查詢條件
          criteria.add(Expression.eq("name","caterpillar"));
    ************************************************************************************
    Expression.eq(String s1,String s2)---------->相等s1=s2
    Expression.allEq(Map map)    --------------->多個(gè)屬性-值對(duì)應(yīng)關(guān)系,多個(gè)Expression.eq疊加
    Expression.gt(String s1,String s2)----------->大于s1>s2
    Expression.ge(String s1,String s2)----------->大于等于s1>=s2
    Expression.lt(String s1,String s2)------------>小于s1<s2
    Expression.le(String s1,String s2)------------>小于等于s1<=s2
    Expression.between(String s1,int s2,int s3)--->s2<s1<s3
    Expression.like(String s1,String s2)------------>s1 like s2
    比較2個(gè)屬性
    Expression.eqProperty(String s1,String s2)--->s1=s2
    Expression.gtProperty(String s1,String s2)---->s1>s2
    Expression.geProperty(String s1,String s2)---->s1>=s2
    Expression.ltProperty(String s1,String s2)----->s1<s2
    Expression.leProperty(String s1,String s2)----->s1<=s2
    Expression.and()----->Expression.and(Expression.eq("String s1,String s2"),Expression.eq(String s3,String s4))
    Expression.or()
    ************************************************************************************
    (2)高級(jí)查詢
    一、可以使用Criteria進(jìn)行查詢,并用order對(duì)結(jié)果進(jìn)行排序。
    //設(shè)置從第幾條開始取的記錄
    criteria.setFirstResult(100);
    //最多取的幾條記錄
    criteria.setMaxResults(20);
    //對(duì)結(jié)果進(jìn)行排序
    criteria.addOrder(Order.asc(String s1));
    criteria.addOrder(Order.desc(String s2));

    二、可以對(duì)查詢結(jié)果進(jìn)行統(tǒng)計(jì)操作,使用Projections的rowCount(),count(),max(),min(),countDistinct()等方法:
    例如:criteria.setProjection(Projections.max("age"));

    三、還可以用Projections的groupProperty()來(lái)對(duì)結(jié)果進(jìn)行分組
    例如:criteria.setProjection(Projections.groupProperty("age"));

    (***)四、結(jié)合統(tǒng)計(jì)與分組的功能,可以用ProjectionList
    例如:ProjectionList projectionList =Projections.projectionList();
                projectionList.add(Projections.groupProperty("age"));
                projectionList.add(Projections.rowCount());
                criteria.setProjection(projectionList);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          //查詢所有記錄
          List users=criteria.list();
          Iterator iterator=users.iterator();
          while(iterator.hasNext()){
             User user=(User)iterator.next();
             System.out.println(user.getId()+"\t"+user.getName()+"/"+user.getAge());
    }
    3、criteria的增、刪、改(還不完善)
    在用到增、刪、改時(shí),必須先聲明事務(wù)
    增加:
      Transaction tx = session.beginTransaction();//Transaction表示一組會(huì)話操作
      session.save(user);//將事物映射到數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)
      tx.commit();
      session.close();
    刪除:
      Session session=this.getSession();
      User user=(User)session.get(User.class, new Integer(1));
      Transaction tx = session.beginTransaction();//Transaction表示一組會(huì)話操作
      session.delete(user);//將事物映射到數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)
      tx.commit();
      session.close();

    修改:
      Session session=this.getSession();
      User user =(User)session.get(User.class,new Integer(2));//創(chuàng)建持久化的事物
      user.setName("wyqqqqqqqqqq");
      user.setAge(new Integer(30));
      Transaction tx = session.beginTransaction();//Transaction表示一組會(huì)話操作
      session.update(user);//將事物映射到數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ)
      tx.commit();
      session.close();
    ----------------------------------------------------------------------------------------------------------------------
    一、Query查詢可以先設(shè)定查詢參數(shù),之后通過set等方法,將指定的參數(shù)值添入.還可以使用命名參數(shù)
    Session session = sessionFactory.openSession();
    Query query = session.createQuery("select user.name from User as user where user.age>?(
    :minAge )");
    query.setInteger(0,25);
    query.setInteger("minAge",25);
    List names=query.list();
    Iterator iterator = names.iterator();
    while(iterator.hasNext()){
          System.out.println(iterator.next());
    }
    session.close();

    二、如果查詢整個(gè)表直接使用from User如果針對(duì)某個(gè)屬性使用select user.name from User as user
    使用hql可以更接近我們平時(shí)的jdbc編程,和把sql語(yǔ)句寫在程序中差不多,另外,也可以將sql語(yǔ)句寫在配置文件中。



    --------------------------------------------------------------------------------------------------------------------------
       多表關(guān)聯(lián)
    一、多對(duì)一進(jìn)行關(guān)聯(lián)(多個(gè)學(xué)生對(duì)應(yīng)同一間宿舍)---學(xué)生是主體,宿舍是附體,關(guān)聯(lián)關(guān)系<many-to-one>在主體學(xué)生中設(shè)置,在學(xué)生類中設(shè)置宿舍類,由于宿舍類只有一個(gè)可以直接用類來(lái)設(shè)置,在映射學(xué)生類(User)中包含宿舍這個(gè)類(Room),在映射配置文件(User.hbm.xml)中定義

    <many-to-one name="room" column="room_id" cascade="save-update" class="com.wyq.hibernate2.Room"></many-to-one>

    哪個(gè)是主體類就在哪個(gè)配置文件定義關(guān)聯(lián)關(guān)系.

    cascade屬性:表示關(guān)聯(lián)對(duì)象的持久化,該屬性也要設(shè)置在主體中,作用就是當(dāng)主控方執(zhí)行操作時(shí),關(guān)聯(lián)對(duì)象(被動(dòng)方)是否同步執(zhí)行同一操作.
    cascade的值:all:表示所有情況下都進(jìn)行級(jí)聯(lián)操作.
                            none:所有情況下都不進(jìn)行級(jí)聯(lián)操作
                            save-update:在執(zhí)行save-update時(shí)進(jìn)行級(jí)聯(lián)操作.
                            delete:在執(zhí)行delete時(shí)進(jìn)行級(jí)聯(lián)操作.

    注意:使用cascade自動(dòng)持久化時(shí),會(huì)先檢查被關(guān)聯(lián)物件的id屬性,未被持久化的物件之id屬性是由unsaved-value決定,預(yù)設(shè)是null,如果您使用long這樣的原生型態(tài)(primitive type)時(shí),則必須自行指定預(yù)設(shè)值.

    例如:<id name="id" column="ROOM_ID" unsaved-value="0">
                <generator class="increment"/>
            </id>

    如果您不想額外設(shè)定unsaved-value資訊,則可以將long改為L(zhǎng)ong,這可以符合預(yù)設(shè)的unsaved-value為null的設(shè)定 .

    二、一對(duì)多進(jìn)行關(guān)聯(lián)(一間宿舍對(duì)應(yīng)多個(gè)學(xué)生)---宿舍是主體,學(xué)生是附體,關(guān)聯(lián)關(guān)系<one-to-many>在主體宿舍中設(shè)置,由于要在宿舍類中設(shè)置學(xué)生類,一個(gè)宿舍包含多個(gè)學(xué)生,所以在宿舍類中要用Set類來(lái)進(jìn)行設(shè)置,用set類(private Set users = new HashSet();)來(lái)存儲(chǔ)多個(gè)學(xué)生類,在映射宿舍類(Room)中要包含<set>這個(gè)節(jié)點(diǎn),用來(lái)與user相關(guān)聯(lián)

    例如:<set name="users" table="USER">
                <key column="ROOM_ID"/>
                <one-to-many class="onlyfun.caterpillar.User"/>
            </set>

    name:表示屬性,table:表示關(guān)聯(lián)的表名,key:表示通過什么字段進(jìn)行關(guān)聯(lián),<one-to-many>:表示關(guān)聯(lián)類。這里也可以使用cascade屬性。

    三、在表關(guān)聯(lián)的設(shè)計(jì)中,不論是一對(duì)多還是多對(duì)一,都要將關(guān)聯(lián)字段設(shè)置在多的那一方。
    例如:user表格和room表格,要將關(guān)聯(lián)字段room_id設(shè)置在user表格中。

    四、一對(duì)一進(jìn)行關(guān)聯(lián)(一個(gè)人只有一個(gè)房間,一個(gè)房間也只有一個(gè)人)。
    可以通過2中方式進(jìn)行關(guān)聯(lián):

    (1)、通過外鍵進(jìn)行關(guān)聯(lián):在多對(duì)一的例子中就是通過外鍵進(jìn)行關(guān)聯(lián)的.
    在user-room的設(shè)置中(user.hbm.xml):
    <many-to-one name="room"
                         column="ROOM_ID"
                         class="onlyfun.caterpillar.Room"
                         cascade="all"
                         unique="true"/>

    其中unique表示限制一個(gè)User有一獨(dú)有的 Room,這只是單向的,說(shuō)明一個(gè)user只有一個(gè)room.
    在room-user的設(shè)置中(room.hbm.xml):
    <one-to-one name="user"
                        class="onlyfun.caterpillar.User"
                        property-ref="room"/>
    這樣就完成了雙向的一對(duì)一關(guān)聯(lián),property-ref告訴hibernate,查詢出user并將其參考至room。
    (2)、通過主鍵進(jìn)行關(guān)聯(lián):限制兩個(gè)資料表的主鍵使用相同的值,如此一個(gè)User與Room就是一對(duì)一關(guān)係
    user.hbm.xml:
    <one-to-one name="room"
                        class="onlyfun.caterpillar.Room"
                        cascade="all"/>
    room.hbm.xml:
    <one-to-one name="user"
                        class="onlyfun.caterpillar.User"
                        constrained="true"/>

    使用constrained="true"告訴Hibernate參考至User的主鍵

    五、雙向關(guān)聯(lián),就是將一和二結(jié)合起來(lái),如果將關(guān)聯(lián)的維護(hù)交給User的話會(huì)比較容易,因?yàn)槊總€(gè)User都對(duì)應(yīng)至一個(gè)Room,在儲(chǔ)存時(shí)並用像Room一樣必須對(duì)Set中的每個(gè)物件作檢查,為了將關(guān)聯(lián)的維護(hù)交給User,我們可以在Room.hbm.xml中的<set>修改,加上inverse="true",表示將關(guān)聯(lián)的維護(hù)「反過來(lái)」交給User作

     例如:<set name="users" table="users" iinverse="true" cascade="all">
                  <key  column="room_id"/>
                  <one-to-many class="onlyfun.caterpillar.User"/>

    在設(shè)立雙向關(guān)聯(lián)時(shí),關(guān)聯(lián)由多對(duì)一中「多」的哪一方維護(hù),會(huì)比由「一」的哪一方維護(hù)來(lái)的方便,在Hibernate可以藉由inverse來(lái)設(shè)定,不設(shè)定inverse基本上也可以運(yùn)行,但是效能會(huì)較差。


    ------------------------------------------------------------------------------------------------------------------------
          在Hibernate中,集合類的映射可以延遲初始(Lazy Initialization),在多對(duì)一或者一對(duì)多中,都可以使用延遲初始,例如:一個(gè)用戶(user對(duì)應(yīng)user表)有多個(gè)email地址(address對(duì)應(yīng)address表),也就是在真正索取該物件的資料時(shí),才向資料庫(kù)查詢,就上次例子來(lái)說(shuō),就是我們?cè)谧x取User時(shí),先不取得其中的 addrs屬性中之物件資料,由於只需要讀取User的name屬性,此時(shí)我們只要執(zhí)行一次select即可,真正需要addrs的資料時(shí),才向資料庫(kù)要求。在含有集合類的user.hbm.xml中要如下設(shè)置:

      <set name="addrs" table="ADDRS" lazy="true">
                <key column="USER_ID"/>
                <element type="string" column="ADDRESS" not-null="true"/>
            </set>

    --------------------------------------------------------------------------------------------------------------------------
          session是hibernate運(yùn)做的核心,是有SessionFactory所創(chuàng)建,sessionFactory是線程安全的,你可以讓多個(gè)線程同時(shí)存取SessionFactory,而不會(huì)有資源共用的問題,然而session不是設(shè)計(jì)為線程安全的,所以讓多個(gè)線程共用一個(gè)session,將發(fā)生資料共用而發(fā)生混亂的問題.下面是一個(gè)標(biāo)準(zhǔn)類.

    import java.io.Serializable;
    import net.sf.hibernate.HibernateException;
    import net.sf.hibernate.Session;
    import net.sf.hibernate.SessionFactory;
    import net.sf.hibernate.Transaction;
    public class HibernateSessionUtil implements Serializable
    {
         //創(chuàng)建線程局部變量 tLocalsess 
        public static final ThreadLocal tLocalsess = new ThreadLocal();
       //創(chuàng)建線程局部變量 tLocaltx
    public static final ThreadLocal tLocaltx = new ThreadLocal();
          //取得session
        public static Session currentSession(){
             //從線程變量tLocalsess中,取得當(dāng)前session
    Session session = (Session) tLocalsess.get();
    //判斷session是否為空,如果為空,將創(chuàng)建一個(gè)session,并付給線程變量tLocalsess
        try{
    if (session == null){
    session = openSession();
    tLocalsess.set(session);
    }
    }catch (HibernateException e){
    throw new InfrastructureException(e);
    }
    return session;
    }
    //關(guān)閉當(dāng)前session
        public static void closeSession(){
    
             //從線程變量tLocalsess中,取得當(dāng)前session
    Session session = (Session) tLocalsess.get();
             //設(shè)置線程變量tLocalsess為空
    tLocalsess.set(null);
    try{
                //關(guān)閉session
    if (session != null && session.isOpen()){
    session.close();
    }
    }catch (HibernateException e){
    throw new InfrastructureException(e);
    }
    }
    //事物處理
        public static void beginTransaction(){
          //從線程變量tLocaltx中取得事物管理對(duì)象Transaction
            Transaction tx = (Transaction) tLocaltx.get();
    try{
                //如果為空就從session中創(chuàng)建一個(gè)tx
    if (tx == null){
    tx = currentSession().beginTransaction();
    tLocaltx.set(tx);
    }
    }catch (HibernateException e){
    throw new InfrastructureException(e);
    }
    }
    //提交事物
        public static void commitTransaction(){
          //取得事物
    Transaction tx = (Transaction) tLocaltx.get();
    try{
                //如果不為空就提交
    if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())
    tx.commit();
    tLocaltx.set(null);
    }catch (HibernateException e){
    throw new InfrastructureException(e);
    }
    }
        //事物回滾    
        public static void rollbackTransaction(){
             //取得tx事物
    Transaction tx = (Transaction) tLocaltx.get();
    try{
                //將變量清空
    tLocaltx.set(null);
    if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
                    //事物回滾
    tx.rollback();
    }
    }catch (HibernateException e){
    throw new InfrastructureException(e);
    }
    }
    
       //取得session
    private static Session openSession() throws HibernateException{
    return getSessionFactory().openSession();
    }
    
       //取得sessionFactory
    private static SessionFactory getSessionFactory() throws HibernateException{
    return SingletonSessionFactory.getInstance();
    }
    }
    filter的代碼:
    public class HibernateSessionCloser implements Filter{
    protected FilterConfig filterConfig = null;
    public void init(FilterConfig filterConfig)throws ServletException{
    this.filterConfig = filterConfig;
    }
    public void destroy(){
    this.filterConfig = null;
    }
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain)
    throws IOException, ServletException {
    try{
    chain.doFilter(request, response);
    }
    finally{
    try{
    HibernateSessionUtil.commitTransaction();
    }catch (InfrastructureException e){
    HibernateSessionUtil.rollbackTransaction();
    }finally{
    HibernateSessionUtil.closeSession();
    }
    }
    }
    }
    ---------------------------------------------------------------------------------------
    
          (1)、悲觀鎖定(Pessimistic Locking)一如其名稱所示,悲觀的認(rèn)定每次資料存取時(shí),其它的客戶端也會(huì)存取同一筆資料,因此對(duì)該筆資料進(jìn)行鎖定,直到自己操作完成後解除鎖定。 

          悲觀鎖定通常透過系統(tǒng)或資料庫(kù)本身的功能來(lái)實(shí)現(xiàn),依賴系統(tǒng)或資料庫(kù)本身提供的鎖定機(jī)制,Hibernate即是如此,可以利用Query或 Criteria的setLockMode()方法來(lái)設(shè)定要鎖定的表或列(Row)及其鎖定模式,可設(shè)定的鎖定模式有以下的幾個(gè):
  • LockMode.WRITE:在insert或update時(shí)進(jìn)行鎖定,Hibernate會(huì)在save()方法時(shí)自動(dòng)獲得鎖定。
  • LockMode.UPGRADE:利用SELECT ... FOR UPDATE進(jìn)行鎖定。
  • LockMode.UPGRADE_NOWAIT:利用SELECT ... FOR UPDATE NOWAIT進(jìn)行鎖定,在Oracle環(huán)境下使用。
  • LockMode.READ:在讀取記錄時(shí)Hibernate會(huì)自動(dòng)獲得鎖定。
  • LockMode.NONE:沒有鎖定。

          (2)、樂觀鎖定(Optimistic locking)則樂觀的認(rèn)為資料的存取很少發(fā)生同時(shí)存取的問題,因而不作資料庫(kù)層次上的鎖定,為了維護(hù)正確的資料,樂觀鎖定使用應(yīng)用程式上的邏輯實(shí)現(xiàn)版本控制的解決。 

          在不實(shí)行悲觀鎖定策略的情況下,資料不一致的情況一但發(fā)生,有幾個(gè)解決的方法,一種是先更新為主,一種是後更新的為主,比較複雜的就是檢查發(fā)生變動(dòng)的資料來(lái)實(shí)現(xiàn),或是檢查所有屬性來(lái)實(shí)現(xiàn)樂觀鎖定。
          要注意的是,由於樂觀鎖定是使用系統(tǒng)中的程式來(lái)控制,而不是使用資料庫(kù)中的鎖定機(jī)制,因而如果有人特意自行更新版本訊息來(lái)越過檢查,則鎖定機(jī)制就會(huì)無(wú)效,例如在上例中自行更改userV2的version屬性,使之與資料庫(kù)中的版本號(hào)相同的話就不會(huì)有錯(cuò)誤,像這樣版本號(hào)被更改,或是由於資料是由外部系統(tǒng)而來(lái),因而版本資訊不受控制時(shí),鎖定機(jī)制將會(huì)有問題,設(shè)計(jì)時(shí)必須注意。

  • posted on 2007-05-30 14:20 注銷..... 閱讀(417) 評(píng)論(0)  編輯  收藏 所屬分類: 閱讀摘要
    主站蜘蛛池模板: 国产日韩成人亚洲丁香婷婷| jizz免费在线观看| 亚洲国产精品无码av| 日韩在线看片免费人成视频播放| 国产成人AV免费观看| 特级毛片免费播放| 亚洲综合av一区二区三区| 亚洲国产综合精品中文第一区| 亚洲精品tv久久久久| 国内一级一级毛片a免费| 18禁无遮挡无码国产免费网站| 中文在线免费看视频| 日日躁狠狠躁狠狠爱免费视频| 日本亚洲色大成网站www久久| 亚洲黄色在线视频| 亚洲AV区无码字幕中文色| 国产亚洲精品无码专区| 免费在线观看理论片| 国产女高清在线看免费观看| 免费无码黄十八禁网站在线观看| 青青草无码免费一二三区| 国产一级婬片A视频免费观看| 一边摸一边爽一边叫床免费视频| 日韩欧美亚洲国产精品字幕久久久 | 国产精品99久久免费| 最近免费中文字幕大全视频| 67194成手机免费观看| 免费无码毛片一区二区APP| 中国一级特黄的片子免费| 亚洲精品视频免费| 和老外3p爽粗大免费视频 | 亚洲国产精品成人| 少妇亚洲免费精品| 午夜亚洲av永久无码精品| 一区二区三区亚洲视频| 免费在线观看理论片| 国产成人亚洲影院在线观看| 久久久久亚洲精品无码网址 | 日韩在线一区二区三区免费视频| 老司机午夜精品视频在线观看免费| 色综合久久精品亚洲国产|