个位大虾 看看小弟写的 使用Hibernate有没有什么问题 或是需要规范的 谢谢。
先声明个Session
private static Session session;
这个是获得数据库中某个表的所有数据
public List getByAll(String hql){
try{
session = HibernateSessionFactory.getSession();
Query query = session.createQuery(hql);
List list = query.list();
return list;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
这个是获得数据库中单个列的数据
public Object getById(Object o,int id) {
session = HibernateSessionFactory.getSession();
Object obj;
try{
obj = session.get(o.getClass(),new Integer(id));
}catch(Exception e){
obj = new Object();
e.printStackTrace();
}finally{
}
return obj;
}
这个是存入数据库中的方法
public void saveExecuteQuery(Object o) {
session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
try{
session.save(o);
tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
}finally{
}
}
这个是修改数据库中某个列的值
public void updateExcuteUpdate(String hql) {
session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
try{
Query query = session.createQuery(hql);
query.executeUpdate();
tx.commit();
}catch(Exception e){
tx.rollback();
e.printStackTrace();
}finally{
}
}
删除某条数据
public void deleteExcuteUpdate(String hql) {
session = HibernateSessionFactory.getSession();
Query query = session.createQuery(hql);
Transaction tx = session.beginTransaction();
try{
query.executeUpdate();
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}finally{
}
}
手动关闭Session
public void closeSession(){
session.close();
}
[b]问题补充:[/b]
哦,我已经跑起来了。我给了10分吖
还逮也给说说如何改进。
[b]问题补充:[/b]
我对于静态的理解不是很透彻
在这里我写的private static Session session;
开始的时候写的是 private Session session。 但想想了 怕出错
就用static。能不能给我详解一下 为什么不用static 我想的就是用个单列
最好是一个用户一个session 不必每次都实例化一个session
最好能给举例说明一下好处。
[b]问题补充:[/b]
呵呵,我昨天买了本设计模式方面的书,正在努力的研究中... ...
[b]问题补充:[/b]
再弱弱的问一句
session这个时候应该用什么关闭
是session.colse还是HibernateSessionFactory.closeSession()
我准备在所有的方法的
try{
..
..
代码中
..
..
}catch(Exception e){
HibernateSessionFactory.closeSession()
e.printStackTrace();
}
有没有问题
还是这两种关闭的不同
Dao
[code="java"]package com.test;
import java.util.List;
import org.hibernate.Session;
public class TestDao {
private Session session;
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public List getByAll(String hql) {
return session.createQuery(hql).list();
}
public Object getById(Object o, int id) {
return session.get(o.getClass(), new Integer(id));
}
public void saveExecuteQuery(Object o) {
session.save(o);
}
public void updateExcuteUpdate(String hql) {
session.createQuery(hql).executeUpdate();
}
public void deleteExcuteUpdate(String hql) {
session.createQuery(hql).executeUpdate();
}
}[/code]
Service
[code="java"]package com.test;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.flyy.util.HibernateSessionFactory;
public class TestService {
private TestDao dao = new TestDao();
private Session session = HibernateSessionFactory.getSession();
public TestService() {
dao.setSession(session);
}
public List getByAll(String hql) {
return dao.getByAll(hql);
}
public Object getById(Object o, int id) {
return dao.getById(o, id);
}
public void saveExecuteQuery(Object o) {
Transaction tx = session.getTransaction();
try {
tx.begin();
dao.saveExecuteQuery(o);
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
tx.rollback();
}
}
public void updateExcuteUpdate(String hql) {
Transaction tx = session.getTransaction();
try {
tx.begin();
session.createQuery(hql).executeUpdate();
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
tx.rollback();
}
}
public void deleteExcuteUpdate(String hql) {
Transaction tx = session.getTransaction();
try {
tx.begin();
session.createQuery(hql).executeUpdate();
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
tx.rollback();
}
}
}[/code]
这样来说,事务管理和日志管理也统一了,不会显得那么混乱了,session绝对不能设置为类变量,除非你能保证这个程序永远只有一个人用。
挑BUG?
1.session被声明为了类变量,也就是说在并发时,不管理谁拿到的session都是同一个会话,肯定得出问题。
2.在每个方法里面都进行了getSession()操作,代码累赘了。
当然,这段代码应该能跑就是了!
关于BUG,蔡华江同学说得很对,其实项目中完全不是这么写代码的,所以没什么改进建议可言,去看看springside给的DAO实现吧,能使你一下升好几级。并不期望这几句话拿你的分,因为你的这些代码就像一间能住人的毛草房,我没法一下给你改建成摩天大楼,这里要走的路很长,只能告诉你方向。
也不能设置为成员变量,因为DAO一般是单例的
稍微给点意见哦 个人意见 首先你的finally里应该关掉不用的东西 session是轻量的 打开和关闭都不浪费什么内存 在标准的JAVA规范里 不用的对象都指向空 上面用完的对象 在finally里都指向null 再就是功能是实现了 最好你的代码能规范一下 写成模版形式的 你的每个方法里都有公用的 开启session和关闭session 你应该把这些东西提取出来 横切进代码里:
给你个示例
public class Dao {
private interface Callback {
Object doIt(Connection conn) throws SQLException;
}
private Object execute(Callback callback) throws SQLException {
Session session = openSession(); // 开启session
try { return callback.doIt(conn); } // 执行具体操作并返回操作结果
finally { closeSession(session); } // 关闭session
}
public Object sqlQuery(final String hql) throws SQLException {
return execute(
new Callback() {
public Object doIt(Session session) throws SQLException {
return session.createQuery (hql).executeUpdate(); }
}
);
}
public Connection openSession() throws SQLException {
return HibernateSessionFactory.getSession();
}
public void closeSession(Session session) throws SQLException {
if(session != null && !session.isClosed()) {
session.close();
}
}
}
这样不是更好些? 呵呵
Sorry 第一个doit里应该是(Session session)
lgdlgd朋友 您说的不对吧 dao是单例的? 多个客户端同时调用服务端的方法时 会有并发访问数据库的情况 这个时候dao还是单例的比较好? 一个DAO里一个session 只是打开了一个conn ! 如果dao是单例的 那么数据库连接池就没用了吧 个人见解而已 欢迎一起讨论
HibernateSessionFactory.getSession(); 这个方法里 每调用一次都应该返回一个新的session而不应该是那一个session;hibernate里是有缓存机制的 session里的是一级缓存 也就是说 它会缓存数据的 若果多个用户都用这一个session会造成混乱的 为了解决共享数据的问题 hibernate在sessionfactory里设置了二级缓存 如果要多个用户共享资源可以从sessionfactory里存取 这里说明的是sessionfactory是个重量级对象 所以它应该是单例的 (因为每次创建它的代价很大,很占内存)
建议楼主多看看设计模式方面的书籍 这样可以少走两年弯路 呵呵 。。建议而已
有问题啊 你不能在catch里关闭session 应该在finally{}里 如果放在catch里 当没发生异常的时候 就关闭不了了 finally里是在程序最后必须执行的 所以一定会执行到 至于 关闭session还是用你的是HibernateSessionFactory.closeSession() ,只是这个方法里用到的是 session.colse()都一样只是封装了一层 这样有助于松散耦合。
我建议你还是用我给你的例子那样横切进去session的开启和事务的开启 这样有助于代码的复用性和松散耦合 现在可能你接触的少 等你研究段时间后 就明白我这话了 加油 多看书 多编程 慢慢积累就好了
[quote]lgdlgd朋友 您说的不对吧 dao是单例的? 多个客户端同时调用服务端的方法时 会有并发访问数据库的情况 这个时候dao还是单例的比较好? 一个DAO里一个session 只是打开了一个conn ! 如果dao是单例的 那么数据库连接池就没用了吧 个人见解而已 欢迎一起讨论 [/quote]
wocsok朋友,DAO的单例与使是否使用数据库连接池没有什么联系,只是不要把SESSION作为一个成员变量就好,推荐的是使用SPRING的FILTER来开启和关闭SESSION,如果不会用,那就每次用HibernateSessionFactory.getSession(); 用完了再关闭。
wocsok朋友很热心,本来我也不想说什么,被你感染了,如果wocsok朋友也只是用上面的代码写DAO,那也推荐去看看SPRINGSIDE的DAO,我纯粹针对问题,如果不喜欢,当我没说。
程序代码好不好有很多因素,除了代码精简可复用和松散耦合外,还有个最重要的因素就是代码的运行效率。
在dao中进行session的获取,SQL的操作,连接的释放,事务的控制,当然没问题,但是有很多操作是可以重复使用的。所以通常大家喜欢将session的获取和释放、事务的控制都交给service层来控制,而使得dao层的功能单一也更明确,尤其是多个dao可以重复利用相同的session来进行操作,这无疑是效率远超过在每个SQL中进行连接管理的。
将相同的功能提取出去,交给专门的类来做,这也有利于代码的松散耦合,大家都不用管理session是如何控制的,只需要从service中取得session就行,代码阅读起来当然方便多了。