有时候我们在实现不同功能的时候回看到很多的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:

@Repository
public 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

@Repository
public 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

@Repository
public 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

@Repository
public 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

  

  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

@Repository
public class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao {
//提供构造参数,在构造方法中传入具体的Class
/* public LinkManDaoImpl() {
super(LinkMan.class);
}*/ @Autowired
private HibernateTemplate hibernateTemplate;
}
@Repository
public 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层

Javaee的Dao层的抽取的更多相关文章

  1. 案例50-crm练习dao层的抽取BaseDao

    1 抽取BaseDao 2 BaseDao设计思路 3 BaseDao接口书写 package www.test.dao; import java.io.Serializable; import ja ...

  2. javaEE中关于dao层和services层的理解

    javaEE中关于dao层和services层的理解 入职已经一个多月了,作为刚毕业的新人,除了熟悉公司的项目,学习公司的框架,了解项目的一些业务逻辑之外,也就在没学到什么:因为刚入职, 带我的那个师 ...

  3. 系统管理模块_部门管理_改进_抽取添加与修改JSP页面中的公共代码_在显示层抽取BaseAction_合并Service层与Dao层

    系统管理模块_部门管理_改进1:抽取添加与修改JSP页面中的公共代码 commons.jspf <%@ page language="java" import="j ...

  4. springboot 注册dao层 service 层

    可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...

  5. Java高并发秒杀API之业务分析与DAO层

    根据慕课网上关于java高并发秒杀API的课程讲解用maven+ssm+redis实现的一个秒杀系统 参考了codingXiaxw's blog,很详细:http://codingxiaxw.cn/2 ...

  6. DAO层注入HibernateTemplate的两种方式

    -------------------------siwuxie095                                         DAO 层注入 HibernateTemplat ...

  7. DAO 层实现

    一.实验介绍 1.1 实验内容 本节课程主要利用 MyBatis 框架实现 DAO 层. 1.2 实验知识点 MyBatis 框架 MySQL 1.3 实验环境 JDK1.8 Eclipse Java ...

  8. Mybatis的dao层实现 接口代理方式实现规范+plugins-PageHelper

    Mybatis的dao层实现 接口代理方式实现规范 Mapper接口实现时的相关规范: Mapper接口开发只需要程序员编写Mapper接口而不用具体实现其代码(相当于我们写的Imp实现类) Mapp ...

  9. Mybatis的Dao层实现原理

    1.Mybatis的Dao层实现 1.1 传统开发方式 1.1.1编写UserDao接口 public interface UserDao { List<User> findAll() t ...

随机推荐

  1. “全栈2019”Java第十七章:赋值运算符和算术运算符

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. jquery事件二 -- 选项卡,失去焦点

    以之前的选项卡例子为原版,当选上某一个选项卡的时候,选项卡周围会有一个蓝色的边框影响视觉体验,那么应该怎么去掉这个边框色呢?只需要加一行blur()--失去焦点函数就可以了 <!DOCTYPE ...

  3. React.Children详解

    React.Children提供了处理this.props.children的工具,this.props.children可以任何数据(组件.字符串.函数等等).React.children有5个方法 ...

  4. vue混入函数问题

    vue开发时,遇到个问题, import mxTable from "#mixin/table"; 导入了一个混入mxTable,但是该混入函数中import了其他的js代码,此时 ...

  5. PHP 数组与CSV文件互转

    项目说明 数组导出CSV,ZIP文件,CSV,ZIP文件还原数组(Array export file,file restore array)适用于导入导出会员,商品信息注意:读取中文文件名文件.数据时 ...

  6. UGUI Slider的onValueChanged事件

    在本文,你将学到如何将UGUI Slider的onValueChanged事件进行统一管理. using System; using UnityEngine; using UnityEngine.UI ...

  7. 04-oracle时间函数

    add_months(sysdate,x)x月之后的日期:last_day(sysdate)指定日期所在月份的最后一天:next_day(sysdate,'星期x')当前日期后的下一个星期x: mon ...

  8. Unity QualitySettings.vSyncCount 垂直同步数

    QualitySettings.vSyncCount 垂直同步数 Description 描述 The VSync Count. 垂直同步数. The number of VSyncs that sh ...

  9. java中Map转化为bean

    Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值,在java编程中会经常用到.但是当我们进行业务逻辑的处理或着操作数据库时,往往应用的是我们自己定义的的Bean或VO来传递和 ...

  10. 解决C#中dynamic类型作为泛型参数的反射问题

    C#中dynamic类型作为泛型参数传递过去后,反射出来的对象类型是object,我用老外的这篇博文中的代码跑起来,得出的结果是:Flying using a Object map (a map),将 ...