最近碰到一个以前没有想过的问题,觉得应该跟论坛的朋友们讨论一下:在DAO的实现上,以前常用Spring的依赖注入来生成Dao对象,然后在对象中通过继承或者实现更抽象的接口,调用公共的代码来获得数据库的Connection连接,由于Spring默认情况下都是单例模式,所以每个Dao对象也就只有一个实例。习惯上好像就这样了!那么如果我把Dao对象的CRUD相关方法全部变成静态的呢?
例如:
public class UserDao{
  public Session getHibernateSession(){...}  public static User getUserByID(String id){
    User user = getHibernateSession().get(id);
    //close session...
    return user;
  }  public static void addUser(User user){
    getHibernateSession().save(user);
    //close session...
  }
}理论上来说,这样的话甚至节约了new一个UserDao的实例来完成任务,只需要UserDao class实例就可以了,但总觉得这样用不是很放心,希望大家都来讨论一下,用静态方法来完成数据库操作是否有隐藏的危害呢?如果没有,又到底是静态还是Spring注入调用实例的非静态更好一些呢?

解决方案 »

  1.   

    感觉没什么问题,我一直认为只要不对本身对象进行操作就可以使用static方法,
    不知道多线程安全性方面是不是需要考虑,期待高手解答
      

  2.   

    我也看到过 用static的  应该没什么问题吧 
      

  3.   

    我觉得还是不能static方法为好,如果需要我宁可这样做:
     Spring注入Dao,得到static 的bean就行了。
     private static ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
     private staitc UserDao = (UserDao) ac.getBean("UserDao");
     
    new 一个对象也节约不了多少空间,如多个Dao共用一个Session可能出错。
      

  4.   

    public class UserDao{
      public static Session getHibernateSession(){...}

      public static User getUserByID(String id){
        User user = getHibernateSession().get(id);
        //close session...
        return user;
      }  public static void addUser(User user){
        getHibernateSession().save(user);
        //close session...
      }
    } dao层多数操作都是比较底层、比较原子性的,可以用static。如果用到spring的话,由于getTemplate()不是statsic的,所以就不能用static了。个人意见
      

  5.   

    个人觉得如果方法要调用的对象只要都是局部范围的,多线程访问就应该没有问题,大家都是用自己局部作用域的变量,互相不冲突这样考虑的话,static岂不是更好用一些,连Spring对象注入都不用了,只要类在classpath里能找到,用到的时候自然被ClassLoader加载进来不知道各位还有没有别的意见
      

  6.   

    DAO 采用静态方法的话有好处,也有坏处。好处的话,楼主肯定已经察觉到了,这里也不多说了。我来谈一下不好之处:做成静态方法的话,完全把 DAO 想成一个工具类了。一般来说工具类是与具体的业务性质无关的,
    存放的是一些工具方法,在任何程序中都有可能用到的东西。做成静态方法的话,让业务层与 DAO 层完全耦合起来了,如果 DAO 在技术更新后需要采用其他的
    ORM 工具重新实现的话,这样一来根本就不可能另外再实现一个 DAO 类,只能在原始的 DAO 类中
    更改,要么就需要更改业务类中的代码,如果项目很大的话,这个工作量是非常惊人的。静态 DAO 方法,在事务上下文中会存在问题,没办采用声明式事务进行管理(比如:Spring 中或
    者是 EJB 中的),因为声明式事务处理需要采用动态代理方式进行事务上下文的切入,由于不存在
    DAO 对象,因此也不存在代理对象,也没办法使用声明式事务,只能手工处理。如果一个业务逻辑调用多个 DAO 方法的话,在这种事务上下文环境中,如果靠手工处理事务那会是
    非常繁锁,而且将事务逻辑侵入到了业务层中。上面这些是个人观点,仅供参考,基本上就想到这些了,等以后想到了再来补充。
      

  7.   

     个人认为还是不要设置位static
      我以前看过一篇文章,在web开发中,最好别用static,99%都会出错,因为太容易出问题了。有些问题还是未知性的错误啊
      当然一些字符串常量是可以用的
      

  8.   

    我觉得还是不要用静态的比较好,因为dao还要依赖一些外部的资源,比如dataSource,比如SessionFactory。做成静态的不利于这些依赖的注入,如果连这些也都写成静态的,就不容易测试了。还是用spring之类的ioc容器管理一下比较好。
      

  9.   

    在我作的项目中,这方面很少用到静态的,我更习惯用spring直接生成
      

  10.   

    http://blog.sina.com.cn/s/blog_502042020100921i.html
      

  11.   

    忽忽  火龙果前辈真的太厉害了 学习了 以后记得少用static
      

  12.   

    写个类, 每个service只要new一次, 通过SprintUtil在任何地方可获取public class SpringUtil {

    private static ApplicationContext _ctx;

    private SpringUtil(){

    }

    static{
    _ctx = new ClassPathXmlApplicationContext(
       "classpath:/spring-context-db.xml");
    }

    public static Object getBean(String beanName){
    return _ctx.getBean(beanName);
    }

    }
      

  13.   

    public class HibernateUtil
    {
    static SessionFactory sessionFactory = null;
    static
    {
    final Configuration cfg = new Configuration();
    cfg.configure();
    sessionFactory = cfg.buildSessionFactory();
    } public static SessionFactory getSessionFactory()
    {
    return sessionFactory;
    } public static Session getSeesion()
    {
    return sessionFactory.openSession();
    }
    }
      

  14.   

    靠,,更糊涂了。。怎么就不能统一一下呢?有的说能用,有的说不能用。。火龙果前辈说的又没怎么看懂。。
    还没学Spring..
      

  15.   

    我都没考虑过用静态的 我觉得既然有spring了 大家也别考虑那么多了。