为了账号安全,请及时绑定邮箱和手机立即绑定

Javaee的Dao层的抽取

标签:
Java

有时候我们在实现不同功能的时候回看到很多的Dao层的增加、修改、删除、查找都很相似,修改我们将他们提取BaseDao

一、提取前

1. 提取前的LinkDao层:

复制代码

public interface LinkManDao {

    Integer findCount(DetachedCriteria detachedCriteria);

    List<LinkMan> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);    void save(LinkMan linkMan);

    LinkMan findById(Long lkm_id);    void update(LinkMan linkMan);    void delete(LinkMan linkMan);

}

复制代码

2. 提取前的LinkDaoImpl:

复制代码

@Repositorypublic class LinkManDaoImpl  implements LinkManDao {
    @Autowired    private HibernateTemplate hibernateTemplate;

    @Override    public Integer findCount(DetachedCriteria detachedCriteria) {        //select count(*) from LinkMan        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria);        if(list != null && list.size() > 0) {            return list.get(0).intValue();
        }        return null;
    }

    @Override    public List<LinkMan> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
        detachedCriteria.setProjection(null);        return (List<LinkMan>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
    }

    @Override    public void save(LinkMan linkMan) {
        hibernateTemplate.save(linkMan);
    }    //Dao层根据id查找联系人    @Override    public LinkMan findById(Long lkm_id) {        return hibernateTemplate.get(LinkMan.class, lkm_id);
    }    //Dao层更新联系人信息    @Override    public void update(LinkMan linkMan) {
        hibernateTemplate.update(linkMan);
    }    //Dao层删除联系人    @Override    public void delete(LinkMan linkMan) {
        hibernateTemplate.delete(linkMan);
    }
}

复制代码

3. 提取前的CustomerDao

复制代码

public interface CustomerDao{    void save(Customer customer);
    Integer findCount(DetachedCriteria detachedCriteria);
    List<Customer> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);
    Customer findById(Long cust_id);    void delete(Customer customer);    void update(Customer customer);
    List<Customer> findAll();
}

复制代码

4.提取前的CustomerDaoImpl

复制代码

@Repositorypublic class CustomerDaoImpl implements CustomerDao {    //注入hibernateTemplate模板    @Autowired    private HibernateTemplate hibernateTemplate;    /**
     * Dao层保存客户信息实现方法
     * <p>Title: CustomerDaoImpl</p>
     * <p>Description: </p>
     * @param customer
     * @see com.sshcrm.dao.CustomerDao#saveCustomer(com.sshcrm.pojo.Customer)     */
    @Override    public void saveCustomer(Customer customer) {
        hibernateTemplate.save(customer);
    }    //根据条件查询结果集的总记录数    @Override    public Integer findCount(DetachedCriteria detachedCriteria) {        //select count(*) from Customer        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria);        if(list != null && list.size() > 0) {            return list.get(0).intValue();
        }        return null;
    }    //根据查询条件查询总页数    @Override    public List<Customer> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {        //由于在统计总记录数的时候已经修改了发送的SQL语句,在此需要需要清空
        detachedCriteria.setProjection(null);        return (List<Customer>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
    }
    @Override    public Customer findById(Long cust_id) {        return hibernateTemplate.get(Customer.class, cust_id);
    }
    @Override    public void delete(Customer customer) {
        hibernateTemplate.delete(customer);
    }
    @Override    public void update(Customer customer) {
        hibernateTemplate.update(customer);
    }
    @Override    public List<Customer> findAll() {        return (List<Customer>) hibernateTemplate.find("from Customer");
    }

}

复制代码

5.可以看到CustomerDaoImpl和LinkManDaoImpl方法很相似,所以需要提取

二、利用在子类中传递真正的Class类型来提取BaseDao,编写泛型

1. BaseDao层

复制代码

public interface BaseDao<T> {    void save(T t);    void update(T t);    void delete(T t);    public T findById(Serializable id);    public List<T> findAll();    public Integer findCount(DetachedCriteria detachedCriteria);    public List<T> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);
}

复制代码

2. BaseDaoImpl层

复制代码

public class BaseDaoImpl<T> implements BaseDao<T> {    private Class clazz;    //提供构造方法,在构造方法中让继承的子类向方法中传入具体类型Class
    public BaseDaoImpl(Class clazz) {        this.clazz = clazz;
    }    //注入HibernateTemplate模板    @Autowired    private HibernateTemplate hibernateTemplate;    //保存信息    @Override    public void save(T t) {
        hibernateTemplate.save(t);
    }    //更新信息    @Override    public void update(T t) {
        hibernateTemplate.update(t);
    }    //删除信息    @Override    public void delete(T t) {
        hibernateTemplate.delete(t);
    }    //根据id查询信息    @Override    public T findById(Serializable id) {        return (T) hibernateTemplate.get(this.clazz, id);
    }    //查询所有信息    @Override    public List<T> findAll() {        return (List<T>) hibernateTemplate.find("from "+ this.clazz.getSimpleName());
    }    //查询Count(*)行记录数    @Override    public Integer findCount(DetachedCriteria detachedCriteria) {
        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria);        if(list != null && list.size() > 0) {            return list.get(0).intValue();
        }        return null;
    }    //分页查询信息    @Override    public List<T> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
        detachedCriteria.setProjection(null);        return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
    }

}

复制代码

3. 提取后的LinkManDao

public interface LinkManDao extends BaseDao<LinkMan>{

}

4. 提取后的LinkManDaoImpl

复制代码

@Repositorypublic class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao {    
  //提供构造参数,在构造方法中传入具体类型的Class
  public LinkManDaoImpl() {        super(LinkMan.class);
    }

    @Autowired    private HibernateTemplate hibernateTemplate;
}

复制代码

4.提取后的CustomerDao

public interface CustomerDao extends BaseDao<Customer> {

}

5. 提取后的CustomerDaoImpl

复制代码

@Repositorypublic class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {    
  //提供构造参数,在构造方法中传入具体的Class
  public CustomerDaoImpl() {        super(Customer.class);        // TODO Auto-generated constructor stub    }    //注入hibernateTemplate模板    @Autowired    private HibernateTemplate hibernateTemplate;
}

复制代码

6.  如果这样抽取完成以后,那么在编写DAO的时候如果里面都是一些CRUD的操作,在DAO中只需要提供构造方法即可。

三、如果将通用的DAO编写的更好,连构造方法都不想要了!!!需要怎么做???  泛型反射

1 解决方案二:通过泛型的反射抽取通用的DAO

l  如果现在将DAO中的构造方法去掉,将父类的通用的DAO中提供无参数的构造即可,但是需要在无参数的构造中需要获得具体类型的Class才可以-----涉及到泛型的反射了。

l  回顾一下泛型:

  泛型         :通用的类型。

  <>             :念为  typeof

  List<E>     :E称为类型参数变量

  ArrayList<Integer>  :Integer称为是实际类型参数

  ArrayList<Integer>  :ArrayList<Integer>称为参数化类型

  需要做的时候在父类的构造方法中获得子类继承父类上的参数化类型中的实际类型参数

  泛型反射的步骤:

  第一步:获得代表子类对象的Class

    第二步:查看API

  https://img1.sycdn.imooc.com//5b5b22b80001a79210970117.jpg

  Type[] getGenericInterfaces();        :获得带有泛型的接口,可以实现多个接口。

  Type getGenericSuperclass();          :获得带有泛型的父类,继承一个类。

  第三步:获得带有泛型的父类

  第四步:将带有泛型的父类的类型转成具体参数化的类型

  第五步:通过参数化类型的方法获得实际类型参数

2. 代码实现

  2.1 修改BaseDaoImpl里面的无参构造方法:

复制代码

public class BaseDaoImpl<T> implements BaseDao<T> {    private Class clazz;    //提供构造方法,在构造方法中让继承的子类向方法中传入具体类型Class
    /**
     * 不想子类上有构造方法,必须在父类中提供无参的构造,在无参构造中获取具体的类型Class
     * 具体类型中的Class是参数类型中的实际类型 参数     */
    public BaseDaoImpl() {        //反射:第一步获得Class
        Class clazz = this.getClass();//正在被调用的那个类的Class,CustomerDaoImpl或LinkManDaoImpl        //具体查看JDK的API
        Type type = clazz.getGenericSuperclass();//参数化类型BaseDaoImpl<Customer>,BaseDaoImpl<LinkMan>        //得到的type就是一个参数化类型,将type强转为参数化类型
        ParameterizedType pType = (ParameterizedType) type;        //通过参数化类型获得实际类型参数,得到一个实际类型参数的数组
        Type[] types = pType.getActualTypeArguments();        //只获得第一参数类型即可
        this.clazz = (Class) types[0];//得到Customer,LinkMan    }    //注入HibernateTemplate模板    @Autowired    private HibernateTemplate hibernateTemplate;    //保存信息    @Override    public void save(T t) {
        hibernateTemplate.save(t);
    }    //更新信息    @Override    public void update(T t) {
        hibernateTemplate.update(t);
    }    //删除信息    @Override    public void delete(T t) {
        hibernateTemplate.delete(t);
    }    //根据id查询信息    @Override    public T findById(Serializable id) {        return (T) hibernateTemplate.get(this.clazz, id);
    }    //查询所有信息    @Override    public List<T> findAll() {        return (List<T>) hibernateTemplate.find("from "+ this.clazz.getSimpleName());
    }    //查询Count(*)行记录数    @Override    public Integer findCount(DetachedCriteria detachedCriteria) {
        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) hibernateTemplate.findByCriteria(detachedCriteria);        if(list != null && list.size() > 0) {            return list.get(0).intValue();
        }        return null;
    }    //分页查询信息    @Override    public List<T> findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {
        detachedCriteria.setProjection(null);        return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);
    }

}

复制代码

  2.2 现在LinkDao和CustomerDao不用改变,修改LinkDaoImpl和CustomerDaoImpl

复制代码

@Repositorypublic class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao {    //提供构造参数,在构造方法中传入具体的Class/*    public LinkManDaoImpl() {
        super(LinkMan.class);
    }*/

    @Autowired    private HibernateTemplate hibernateTemplate;
}

复制代码

复制代码

@Repositorypublic class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {    //提供构造参数,在构造方法中传入具体的Class
    /*public CustomerDaoImpl() {
        super(Customer.class);
        // TODO Auto-generated constructor stub
    }*/

    //注入hibernateTemplate模板    @Autowired    private HibernateTemplate hibernateTemplate;
}

复制代码

  2.3 后面如果Dao层有特殊方法是可以在比如CustomerDaoImpl中去实现,相似的就不需要了,以此来到达抽取Dao层

原文出处:https://www.cnblogs.com/ya-qiang/p/9377053.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消