java dao层和base层_详解Javaee Dao层的抽取

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

一、提取前

1. 提取前的LinkDao层:

public interface LinkManDao {

Integer findCount(DetachedCriteria detachedCriteria);

List 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 list = (List) hibernateTemplate.findByCriteria(detachedCriteria);

if(list != null && list.size() > 0) {

return list.get(0).intValue();

}

return null;

}

@Override

public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {

detachedCriteria.setProjection(null);

return (List) 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 findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);

Customer findById(Long cust_id);

void delete(Customer customer);

void update(Customer customer);

List findAll();

}

4.提取前的CustomerDaoImpl

@Repository

public class CustomerDaoImpl implements CustomerDao {

//注入hibernateTemplate模板

@Autowired

private HibernateTemplate hibernateTemplate;

/**

* Dao层保存客户信息实现方法

*

Title: CustomerDaoImpl

*

Description:

* @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 list = (List) hibernateTemplate.findByCriteria(detachedCriteria);

if(list != null && list.size() > 0) {

return list.get(0).intValue();

}

return null;

}

//根据查询条件查询总页数

@Override

public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {

//由于在统计总记录数的时候已经修改了发送的SQL语句,在此需要需要清空

detachedCriteria.setProjection(null);

return (List) 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 findAll() {

return (List) hibernateTemplate.find("from Customer");

}

}

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

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

1. BaseDao层

public interface BaseDao {

void save(T t);

void update(T t);

void delete(T t);

public T findById(Serializable id);

public List findAll();

public Integer findCount(DetachedCriteria detachedCriteria);

public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize);

}

2. BaseDaoImpl层

public class BaseDaoImpl implements BaseDao {

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 findAll() {

return (List) hibernateTemplate.find("from "+ this.clazz.getSimpleName());

}

//查询Count(*)行记录数

@Override

public Integer findCount(DetachedCriteria detachedCriteria) {

detachedCriteria.setProjection(Projections.rowCount());

List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);

if(list != null && list.size() > 0) {

return list.get(0).intValue();

}

return null;

}

//分页查询信息

@Override

public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {

detachedCriteria.setProjection(null);

return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);

}

}

3. 提取后的LinkManDao

public interface LinkManDao extends BaseDao{

}

4. 提取后的LinkManDaoImpl

@Repository

public class LinkManDaoImpl extends BaseDaoImpl implements LinkManDao {

//提供构造参数,在构造方法中传入具体类型的Class

public LinkManDaoImpl() {

super(LinkMan.class);

}

@Autowired

private HibernateTemplate hibernateTemplate;

}

5.提取后的CustomerDao

public interface CustomerDao extends BaseDao {

}

6. 提取后的CustomerDaoImpl

@Repository

public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao {

//提供构造参数,在构造方法中传入具体的Class

public CustomerDaoImpl() {

super(Customer.class);

// TODO Auto-generated constructor stub

}

//注入hibernateTemplate模板

@Autowired

private HibernateTemplate hibernateTemplate;

}

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

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

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

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

l  回顾一下泛型:

泛型         :通用的类型。

<>             :念为  typeof

List     :E称为类型参数变量

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

ArrayList  :ArrayList称为参数化类型

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

泛型反射的步骤:

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

第二步:查看API

973a034643d414ca1a584388b917cf89.png

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

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

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

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

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

2. 代码实现

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

public class BaseDaoImpl implements BaseDao {

private Class clazz;

//提供构造方法,在构造方法中让继承的子类向方法中传入具体类型Class

/**

* 不想子类上有构造方法,必须在父类中提供无参的构造,在无参构造中获取具体的类型Class

* 具体类型中的Class是参数类型中的实际类型 参数

*/

public BaseDaoImpl() {

//反射:第一步获得Class

Class clazz = this.getClass();//正在被调用的那个类的Class,CustomerDaoImpl或LinkManDaoImpl

//具体查看JDK的API

Type type = clazz.getGenericSuperclass();//参数化类型BaseDaoImpl,BaseDaoImpl

//得到的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 findAll() {

return (List) hibernateTemplate.find("from "+ this.clazz.getSimpleName());

}

//查询Count(*)行记录数

@Override

public Integer findCount(DetachedCriteria detachedCriteria) {

detachedCriteria.setProjection(Projections.rowCount());

List list = (List) hibernateTemplate.findByCriteria(detachedCriteria);

if(list != null && list.size() > 0) {

return list.get(0).intValue();

}

return null;

}

//分页查询信息

@Override

public List findByPage(DetachedCriteria detachedCriteria, Integer startIndex, Integer pageSize) {

detachedCriteria.setProjection(null);

return (List) hibernateTemplate.findByCriteria(detachedCriteria, startIndex, pageSize);

}

}

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

@Repository

public class LinkManDaoImpl extends BaseDaoImpl implements LinkManDao {

//提供构造参数,在构造方法中传入具体的Class

/* public LinkManDaoImpl() {

super(LinkMan.class);

}*/

@Autowired

private HibernateTemplate hibernateTemplate;

}

@Repository

public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao {

//提供构造参数,在构造方法中传入具体的Class

/*public CustomerDaoImpl() {

super(Customer.class);

// TODO Auto-generated constructor stub

}*/

//注入hibernateTemplate模板

@Autowired

private HibernateTemplate hibernateTemplate;

}

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

畅销书《深入浅出Vue.js》作者,在阿里淘系1年的收获成长

大家好&#xff0c;我是若川。今天推荐一篇95年的博文的文章。他的故事应该挺多人知道。如果不知道可以看他的博客 https://github.com/berwin/blog点击下方卡片关注我、加个星标时间好快&#xff0c;眨眼间&#xff0c;加入阿里已经一年了。这一年发生了很多事&#xff0c;整体…

插图 引用 同一行两个插图_将图标变成插图的五个简单步骤

插图 引用 同一行两个插图Every creative person has probably already been in this situation: A project, be it a website, an app — or as far as I am concerned: often a news story would benefit from an appealing side visual. But neither budget nor time makes …

web登录界面设计_出色的Web界面设计的7条规则

web登录界面设计When you work on a website or on the design of web pages, remember that their success is not determined by the beauty of their visual style. In fact, in his article “10 Principles Of Good Website Design”, Vitaly Friedman stated:当您在网站或…

关于为什么我推荐大家看vue代码的随想

大家好&#xff0c;我是若川。今天给大家推荐一篇大圣老师在知乎的回答&#xff0c;很快能看完。我也曾经回答过这个问题。若川知乎高赞&#xff1a;有哪些必看的 JS 库&#xff1f;不要为了读源码而读源码&#xff0c;但要学会看源码。自己常用的熟悉的库的源码值得读读。点击…

算法 - 最好、最坏、平均复杂度

注&#xff1a;本文仅为笔记。 原文 极客时间 - 数据结构与算法之美 - 04 | 复杂度分析&#xff08;下&#xff09;&#xff1a;浅析最好、最坏、平均、均摊时间复杂度 最好、最坏时间复杂度 略&#xff0c;比较容易分析。 平均时间复杂度 需考虑概率来计算。 概率论中的加权平…

555的传说

郑昀 20101118 昨天听1039电台才知道&#xff0c;北美电影里常出现的555开头号码是行规惯例&#xff0c;因为当年贝尔系统为测试链路中所有交换机的基本功能&#xff0c;全部由5组成的号码&#xff08;555–5555&#xff09;作为特别的测试号码被保留&#xff0c;时至今日只剩下…

没想到你是这样的npm install

大家好&#xff0c;我是若川。今天给大家推荐一篇关于 npm install 的好文。很快能看完。点击下方卡片关注我、加个星标学习源码整体架构系列、年度总结、JS基础系列前言项目中执行npm install发生了什么&#xff0c;众所周知&#xff0c;执行npm install时会在当前项目目录的n…

Django——Model

一、 ORM 在 MVC 或者说 MTV 设计模式中&#xff0c;模型&#xff08;M&#xff09;代表对数据库的操作。那么如何操作数据库呢&#xff1f; 我们可以在 Python 代码中嵌入 SQL 语句。 但是问题又来了&#xff0c;Python 怎么连接数据库呢&#xff1f;可以使用类似 pymysql 这一…

大理石在哪儿_如何创建用户体验写作课程而又不失大理石

大理石在哪儿I’m a UX Writer. It’s a designated human on the software development team who writes words for interfaces. All the words. From the tiniest tooltips to navigation, to buttons, to errors, and so on, ad infinitum. UX writing is less writing and …

Vuex 源码还有一些缺陷?

我看了vuex3和vuex4的源码也输出了文章&#xff0c;看到这篇时&#xff0c;vuex还有缺陷&#xff1f;看了看确实是好文&#xff0c;不愧是大佬写的。文章不算长&#xff0c;推荐给大家看看。点击下方卡片关注我、加个星标学习源码整体架构系列、年度总结、JS基础系列众所周知&a…

三级菜单页面布局_三级菜单的最快导航布局

三级菜单页面布局重点 (Top highlight)When users navigate an interface, there’s a need for speed. The faster it is for them to find what they’re looking for, the more time they’ll save on their task.用户导航界面时&#xff0c;需要提高速度。 他们找到所需内容…

ux体验网站 英国_定义网站图像时的UX注意事项

ux体验网站 英国As the saying goes —俗话说 - “A picture is worth a thousand words.”“一张图片胜过千言万语。” When creating content on the web, it’s often recommended to be using high-quality imageries and making sure that the images serve its purpose …

iconfont 支持全新的彩色字体图标

大家好&#xff0c;我是若川。iconfont我相信大家都用过&#xff0c;而现在支持全新的彩色字体图标了。这是第二次转载&#xff0c;上一次的好文是2020 前端技术发展回顾。点击下方卡片关注我、加个星标学习源码整体架构系列、年度总结、JS基础系列一直以来&#xff0c;Web 中想…

出色的社区网站_《最后的我们》中出色的制作系统

出色的社区网站游戏设计分析 (GAME DESIGN ANALYSIS) The Last of Us became an instant classic the day it was released, back in 2013. At the sunset of the sixth console generation, it felt like Naughty Dog managed to raise the bar in all critical areas of game…

入坑 Electron 开发跨平台桌面应用

‍作为一个跨平台的桌面应用开发框架&#xff0c;Electron 的迷人之处在于&#xff0c;它是建立在 Chromium 和 Node.js 之上的 —— 二位分工明确&#xff0c;一个负责界面&#xff0c;一个负责背后的逻辑&#xff0c;典型的「你负责貌美如花&#xff0c;我负责赚钱养家」。上…

java 接口编程_JAVA面向接口编程

一、什么是面向接口编程要正确地使用Java语言进行面向对象的编程&#xff0c;从而提高程序的复用性&#xff0c;增加程序的可维护性、可扩展性&#xff0c;就必须是面向接口的编程。面向接口的编程就意味着&#xff1a;开发系统时&#xff0c;主体构架使用接口&#xff0c;接口…

小程序 显示细线_精心设计:高密度显示器上的细线

小程序 显示细线Despite the many benefits of Retina displays, there is one clear drawback that must be considered when designing for high-density screens:尽管Retina显示器具有许多优点&#xff0c;但在设计高密度屏幕时仍必须考虑一个明显的缺点&#xff1a; 必须避…

React 入门手册

大家好&#xff0c;我是若川。推荐这篇可收藏的React入门手册。也推荐之前一篇类似的文章《如何使用 React 和 React Hooks 创建一个天气应用》。点击下方卡片关注我、加个星标React 是目前为止最受欢迎的 JavaScript 框架之一&#xff0c;而且我相信它也是目前最好用的开发工具…

根号 巴比伦_建立巴比伦卫生设计系统

根号 巴比伦重点 (Top highlight)In this post I’ll explain the first phase of creating our Babylon DNA, the design system for Babylon Health, and how we moved the Babylon design team from Sketch to Figma.在这篇文章中&#xff0c;我将解释创建巴比伦DNA的第一阶…

《Migrating to Cloud-Native Application Architectures》学习笔记之Chapter 2. Changes Needed

2019独角兽企业重金招聘Python工程师标准>>> Cultural Change 文化变革 A great deal of the changes necessary for enterprise IT shops to adopt cloud-native architectures will not be technical at all. They will be cultural and organizational changes t…