随笔 - 303  文章 - 883  trackbacks - 0
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

欢迎光临! 
闲聊 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 小寻 阅读(9945) 评论(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
外键约束  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: