隨筆 - 303  文章 - 883  trackbacks - 0
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          歡迎光臨! 
          閑聊 QQ:1074961813

          隨筆分類(357)

          我管理的群

          公共blog

          • n維空間
          • Email : java3d@126.com 群 : 12999758

          參與管理的論壇

          好友的blog

          我的其他blog

          朋友的網站

          搜索

          •  

          最新評論

          該想法來自群中‘姠佑赱』 初始代碼由他提供 最初只能實現查詢,且效率較低

          經過one-to-one和one-to-many測試沒有問題,看直接復制到任何需要DAO的工程中使用
          代碼
          強烈建議在實際使用中加個接口

          BaseDAO.JAVA


          package com.lusm.HibernateSessionFactory;

          import java.io.Serializable;
          import java.util.List;

          import org.hibernate.Query;
          import org.hibernate.Session;

          public class BaseDAO {
              
          /**
               * 添加實體
               * 
          @param obj,要添加的實體對象
               * 
          @throws Exception
               
          */

              
          public void add(Object obj) throws Exception{
                  Session session 
          = null;
                  
          try {
                      session 
          = HibernateSessionFactory.getSession();
                      session.save(obj);
                      session.beginTransaction().commit();
                      
          if(session!=null){
                            session.close();
                      }

                  }
           catch (RuntimeException e) {
                      session.beginTransaction().rollback();
                      
          if(session!=null){
                            session.close();
                      }

                      
          throw e;
                  }

              }

              
              
          /**
               * 刪除實體
               * 
          @param obj,要刪除的實體
               * 
          @throws Exception
               
          */

              
          public void delete(Object obj) throws Exception{
                  Session session 
          = null;
                  
          try {
                      
          //取得session對象
                      session =HibernateSessionFactory.getSession();
                      
          //刪除實體
                      session.delete(obj);
                      
          //提交事務
                      session.beginTransaction().commit();
                      
          if(session!=null){
                            session.close();
                      }

                  }
           catch (Exception e) {
                      session.beginTransaction().rollback();
          //事務回滾
                      if(session!=null){
                            session.close();
                      }

                      
          throw e;
                  }

              }


              
          /**
               * 更新實體
               * 
          @param obj,要更新的實體
               * 
          @throws Exception
               
          */

              
          public void update(Object obj) throws Exception{
                  Session session
          =null;
                  
          try {
                      
          //取得session對象
                      session=HibernateSessionFactory.getSession();
                      
          //刪除實體
                      session.update(obj);
                      
          //提交事務
                      session.beginTransaction().commit();
                      
          if(session!=null){
                            session.close();
                      }

                  }
           catch (Exception e) {
                      session.beginTransaction().rollback();
          //事務回滾
                      if(session!=null){
                        session.close();
                      }

                      
          throw e;
                  }

              }

              
              
          /**
               * 根據指定的hql進行查詢,并返回查詢結果
               * 
          @param hql,hql語句
               * 
          @return 查詢結果
               * 
          @throws Exception
               
          */

              
          public List<?> findByHQL(String hql) throws Exception{
                  
          try {
                      Query queryObject 
          =HibernateSessionFactory.getSession().createQuery(hql);
                      
          return queryObject.list();
                  }
           catch (Exception e) {
                      
          throw e;
                  }

              }

              
          /**
               * 根據指定的實體類型和主鍵的值,查找實體對象
               * 
          @param cls,實體的類
               * 
          @param key,主鍵的值
               * 
          @return,查找的實體對象
               * 
          @throws Exception
               
          */

              
          public Object findById(String cls,Serializable key)
                  
          throws Exception
              
          {
                  
          try {
                      Object instance 
          = (Object) HibernateSessionFactory.getSession().get(cls, key);
                      
          return instance;
                  }
           catch (Exception e) {
                      
          throw e;
                  }

                  
              }

          }

          HibernateSessionFactory.java 我就不發了,每個工程里都有

          值得注意到是:
                 寫代碼是必須考慮到效率,資源利用,第一,不要創建無謂的實例,第二,不要寫沒有必要的返回語句,第三,close是有目的的,不可以濫用,第四,必須考慮到哪一步出錯的概率高,必須在下一步先做判斷。

          如下代碼就是很有問題的:
                
              /**
               * 添加實體
               * 
          @param obj,要添加的實體對象
               * 
          @throws Exception
               
          */

              
          public void add(Object obj) throws Exception{
                  Session ses
          =null;
                  Transaction tx
          =null;
                  
          try {
                      
          //取得session對象
                      ses=HibernateSessionFactory.getSession();
                      
          //開始事務
                      tx=ses.beginTransaction();
                      
          //保存實體
                      ses.save(obj);
                      
          //提交事務
                      tx.commit();
                  }
           catch (Exception e) {
                      tx.rollback();
          //事務回滾
                      throw e;
                  }
          finally{
                      
          //關閉session
                      HibernateSessionFactory.closeSession();
                  }

              }

          使用one-to-many中執行刪除時, 你可能會遇到這樣的錯誤

          Exception in thread "main" org.hibernate.TransientObjectException: the detached instance passed to delete() had a null identifier
            .........
          或者
          Exception in thread "main" org.hibernate.TransientObjectException: the detached instance passed to delete() had a null identifier
              at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:63)
              at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:761)
              at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:739)
              at com.lusm.HibernateSessionFactory.BaseDAO.delete(BaseDAO.java:44)
              at com.lusm.main.Del.main(Del.java:19)

          Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
              at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
              at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
              at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
              at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
              at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
              at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
              at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
              at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
              at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
              at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
              at com.lusm.HibernateSessionFactory.BaseDAO.delete(BaseDAO.java:46)
              at com.lusm.main.Del.main(Del.java:18)
          Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`lusm/test1`, CONSTRAINT `test1_ibfk_1` FOREIGN KEY (`id`) REFERENCES `test` (`id`))
              at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1669)
              at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1085)
              at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
              at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
               9 more

          原因是你的xml配置和數據庫創建有問題
          下面給出一個成功的例子

          many
          xml config
          <?xml version="1.0" encoding="utf-8"?>
          <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
          >
          <!-- 
              Mapping file autogenerated by MyEclipse Persistence Tools
          -->
          <hibernate-mapping>
              
          <class name="com.lusm.test.Test1" table="test1" catalog="lusm">
                  
          <id name="sid" type="java.lang.Integer">
                      
          <column name="sid" />
                      
          <generator class="increment" />
                  
          </id>
                  
          <many-to-one name="test"  class="com.lusm.test.Test" fetch="select"  cascade="save-update" >
                      
          <column name="id" not-null="true" />
                  
          </many-to-one>
                  
          <property name="sname" type="java.lang.String">
                      
          <column name="sname" length="20" />
                  
          </property>
              
          </class>
          </hibernate-mapping>

          code
          package com.lusm.test;

          /**
           * Test1 generated by MyEclipse Persistence Tools
           
          */


          public class Test1 implements java.io.Serializable {

              
          // Fields

              
          private Integer sid;
              
          private Test test;
              
          private String sname;

              
          // Constructors

              
          /** default constructor */
              
          public Test1() {
              }


              
          /** minimal constructor */
              
          public Test1(Test test) {
                  
          this.test = test;
              }


              
          /** full constructor */
              
          public Test1(Test test, String sname) {
                  
          this.test = test;
                  
          this.sname = sname;
              }


              
          // Property accessors

              
          public Integer getSid() {
                  
          return this.sid;
              }


              
          public void setSid(Integer sid) {
                  
          this.sid = sid;
              }


              
          public Test getTest() {
                  
          return this.test;
              }


              
          public void setTest(Test test) {
                  
          this.test = test;
              }


              
          public String getSname() {
                  
          return this.sname;
              }


              
          public void setSname(String sname) {
                  
          this.sname = sname;
              }


          }

          one

          xml config
          <?xml version="1.0" encoding="utf-8"?>
          <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
          >
          <!-- 
              Mapping file autogenerated by MyEclipse Persistence Tools
          -->
          <hibernate-mapping>
              
          <class name="com.lusm.test.Test" table="test" catalog="lusm">
                  
          <id name="id" type="java.lang.Integer">
                      
          <column name="id" />
                      
          <generator class="increment" />
                  
          </id>
                  
          <property name="name" type="java.lang.String">
                      
          <column name="name" length="20" />
                  
          </property>
                  
          <set name="test1s" inverse="true">
                      
          <key>
                          
          <column name="id" not-null="true" />
                      
          </key>
                      
          <one-to-many class="com.lusm.test.Test1"/>
                  
          </set>
              
          </class>
          </hibernate-mapping>

          code
          package com.lusm.test;

          import java.util.HashSet;
          import java.util.Set;

          /**
           * Test generated by MyEclipse Persistence Tools
           
          */


          public class Test implements java.io.Serializable {

              
          // Fields

              
          private Integer id;
              
          private String name;
              
          private Set test1s = new HashSet(0);

              
          // Constructors

              
          /** default constructor */
              
          public Test() {
              }


              
          /** full constructor */
              
          public Test(String name, Set test1s) {
                  
          this.name = name;
                  
          this.test1s = test1s;
              }


              
          // Property accessors

              
          public Integer getId() {
                  
          return this.id;
              }


              
          public void setId(Integer id) {
                  
          this.id = id;
              }


              
          public String getName() {
                  
          return this.name;
              }


              
          public void setName(String name) {
                  
          this.name = name;
              }


              
          public Set getTest1s() {
                  
          return this.test1s;
              }


              
          public void setTest1s(Set test1s) {
                  
          this.test1s = test1s;
              }


          }

          db sql
          create table `lusm`.`test1`(
          `sid` 
          INT not null auto_increment,
          `id` 
          INT not null,
          `sname` 
          varchar(20),
          primary key (`sid`),
          index(sid),
          foreign key(id) references test(id)  ON DELETE CASCADE ON UPDATE CASCADE 
          );
              
          create table `lusm`.`test`(
                  `id` 
          INT not null auto_increment,
                 `name` 
          VARCHAR(20),
                  
          primary key (`id`)
              );

          下面給出 該示例的兩個測試類

          insert
          package com.lusm.main;

          import com.lusm.HibernateSessionFactory.BaseDAO;
          import com.lusm.test.Test;
          import com.lusm.test.Test1;


          public class Main {

              
          /**
               * 
          @param args
               * 
          @throws Exception 
               
          */

              
          public static void main(String[] args) throws Exception {
                  Test test 
          = new Test();
            
                  test.setName(
          "nihao");
                  BaseDAO td 
          = new BaseDAO();
                  td.add(test);
                  
                  Test1 t1 
          = new Test1(test);
                  Test1 t2 
          = new Test1(test);
                  Test1 t3 
          = new Test1(test);
                  t1.setSid(
          1);
                  t2.setSid(
          2);
                  t3.setSid(
          3);
                  t1.setSname(
          "nihao");
                  t2.setSname(
          "mfafs");
                  t3.setSname(
          "acncs");
                  
                  BaseDAO td1 
          = new BaseDAO();
                  td1.add(t1);
                  td1.add(t2);
                  td1.add(t3);
                         
              }

          }

          delete
          package com.lusm.main;

          import com.lusm.HibernateSessionFactory.BaseDAO;
          import com.lusm.test.Test;

          public class Del {

              
          /**
               * 
          @param args
               * 
          @throws Exception 
               
          */

              
          public static void main(String[] args) throws Exception {
                  Test test 
          = new Test();
                  test.setId(
          1);
                  BaseDAO bd 
          = new BaseDAO();
                  bd.delete(test);
              }

          }


          地震讓大伙知道:居安思危,才是生存之道。
          posted on 2008-01-08 17:21 小尋 閱讀(9962) 評論(4)  編輯  收藏 所屬分類: j2se/j2ee/j2me

          FeedBack:
          # re: 一個通用的Hibernate DAO 2008-07-07 21:55 jrg9522
          但是我不同意用級聯更新和級聯刪除。
          用戶一不小心點了刪除或更新。
          也不好。

          應該級聯更新或級聯刪除,executeUpdate時應該提示。

            回復  更多評論
            
          # re: 一個通用的Hibernate DAO[未登錄] 2008-07-07 23:24 小尋
          hehe  回復  更多評論
            
          # re: 一個通用的Hibernate DAO[未登錄] 2013-08-14 00:19 fe
          id 鏈了其他表!不給你刪  回復  更多評論
            
          # re: 一個通用的Hibernate DAO[未登錄] 2013-08-14 00:20 fe
          外鍵約束  回復  更多評論
            
          主站蜘蛛池模板: 丰镇市| 固阳县| 松潘县| 滦南县| 苍山县| 肥城市| 长沙市| 泽普县| 新田县| 云龙县| 宜宾市| 黔西| 荆门市| 福州市| 淄博市| 资兴市| 蒙自县| 邢台市| 兰溪市| 紫金县| 彝良县| 精河县| 奇台县| 琼结县| 湘阴县| 淮滨县| 蒙城县| 河北区| 和田市| 普定县| 吉木乃县| 江达县| 铁力市| 重庆市| 民权县| 太白县| 逊克县| 莱芜市| 秦安县| 右玉县| 会昌县|