BaseDao接口的过人之处在于:一般是提供从数据库 增加、删除、修改记录、查询所有记录、查询符合某个条件记录、取得某条记录等方法的底层数据操作自定义类。
由于我们可能操作多个数据库表,这样就需要为每个表提供一个操作他的类 xxDAO, 这些DAO继承BaseDAO 就可以省略很多重复代码(从数据库 增加、删除、修改记录、查询所有记录、查询符合某个条件记录、取得某条记录等方法的代码)。

其次对于泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
 Java语言引入泛型的好处是安全简单。
  在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
  泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
  泛型在使用中还有一些规则和限制:
  1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
  2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
  3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。
  5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(java.lang.String);

一般在涉及DAO开发时,常用到的增删改查方法会封装到一个基类(BaseDAO),对于各个数据表的基本维护业务都需要用到增删改查等方法。

若对每张表都编写一套增删改差方法未必有些麻烦,并且不符合编码的基本准则。一般,我们可以将这些功能的所公用的部分封装为一个对象,或者是类,此类是所有DAO的基类,可以称为:BaseDAO。

由于此类接收到不同的操作对象,故需泛型的支持。

下面,我通过以下实例代码,为此知识进行展示,供大家参考

此例是基于ssh2的环境中进行搭建:

 

相关类:涉及到BaseDAO接口,接口实现类:BaseDAOImpl、两个数据表的操作对象及相应的接口:DAOA、DAOB、DAOAImpl、DAOBImpl

BaseDAO:接口代码,公共方法的接口类

  1. package base;
  2. import java.util.List;
  3. public interface BaseDao<T> {
  4. /**
  5. * 保存实体
  6. *
  7. * @param entity
  8. */
  9. void save(T entity);
  10. /**
  11. * 删除实体
  12. *
  13. * @param id
  14. */
  15. void delete(Long id);
  16. /**
  17. * 更新实体
  18. *
  19. * @param entity
  20. */
  21. void update(T entity);
  22. /**
  23. * 按id查询
  24. *
  25. * @param id
  26. * @return
  27. */
  28. T getById(Long id);
  29. /**
  30. * 按id查询
  31. *
  32. * @param ids
  33. * @return
  34. */
  35. List<T> getByIds(Long[] ids);
  36. /**
  37. * 查询所有
  38. *
  39. * @return
  40. */
  41. List<T> findAll();
  42. }

BaseDAOImpl:公共方法的实现类

  1. package base;
  2. import java.lang.reflect.ParameterizedType;
  3. import java.util.List;
  4. import javax.annotation.Resource;
  5. import org.hibernate.Session;
  6. import org.hibernate.SessionFactory;
  7. @SuppressWarnings("unchecked")
  8. public abstract class BaseDaoImpl<T> implements BaseDao<T> {
  9. @Resource
  10. private SessionFactory sessionFactory;
  11. private Class<T> clazz;
  12. public BaseDaoImpl() {
  13. // 使用反射技术得到T的真实类型
  14. ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型
  15. this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型
  16. System.out.println("clazz ---> " + clazz);
  17. }
  18. /**
  19. * 获取当前可用的Session
  20. *
  21. * @return
  22. */
  23. protected Session getSession() {
  24. return sessionFactory.getCurrentSession();
  25. }
  26. public void save(T entity) {
  27. getSession().save(entity);
  28. }
  29. public void update(T entity) {
  30. getSession().update(entity);
  31. }
  32. public void delete(Long id) {
  33. Object obj = getById(id);
  34. if (obj != null) {
  35. getSession().delete(obj);
  36. }
  37. }
  38. public T getById(Long id) {
  39. return (T) getSession().get(clazz, id);
  40. }
  41. public List<T> getByIds(Long[] ids) {
  42. return getSession().createQuery(//
  43. "FROM User WHERE id IN (:ids)")//
  44. .setParameterList("ids", ids)//
  45. .list();
  46. }
  47. public List<T> findAll() {
  48. return getSession().createQuery(//
  49. "FROM " + clazz.getSimpleName())//
  50. .list();
  51. }
  52. }

DAOA:vo A的DAO接口类,此类需要继承BaseDAO接口,实现公共类,另外在此可以声明自己特有的方法

  1. package dao;
  2. import pojo.A;
  3. import base.BaseDao;
  4. public interface DAOA extends BaseDao<A>{
  5. //...
  6. }

DAOAImpl:vo A的DAO实现类,实现DAOA中声明的方法和BaseDAO的所以基本方法,为实现基本方法,故继承了BaseDaoImpl类

  1. package dao.impls;
  2. import org.springframework.stereotype.Repository;
  3. import pojo.A;
  4. import base.BaseDaoImpl;
  5. import dao.DAOA;
  6. @Repository
  7. public class DAOAImpl extends BaseDaoImpl<A> implements DAOA {     //具体的实现类什么都不用去写  只需要实现dao(有了声明)继承daoImpl(有了实现   这样的话   无论后面有多少不要的dao及其实现都只需要继承实现一个共同的BaseDao及其Impl即可     把公共的操作封装的十分Good)
  8. }

同理,DAOB同上

以此,便完成了公共方法的继承与实现机制。

当中用到了泛型机制,通过继承父类来实现泛型的数据转换:

  1. public class DAOAImpl extends BaseDaoImpl<A>{}  A为vo的模型类,以此在父类中可调用实现!!

通过使用泛型T减少Dao的冗余代码,当T继承某个对象时(T extends EntityDao)限制了参数类型必须继承该对象(EntityDao),并且ClassT必须要有泛型参数(De

BaseDAO使用的更多相关文章

  1. 【01-05】hibernate BaseDao

    BaseDao接口定义 package org.alohaworld.util.dao; import java.io.Serializable; import java.util.List; imp ...

  2. orm映射 封装baseDao

    是用orm映射封装自己封装dao层 思路:通过映射获得实体类的属性拼接sql语句 import java.lang.reflect.Field; import java.lang.reflect.In ...

  3. BaseDao代码,用于连接数据库实行增删改查等操作

    在学习JavaWeb时会用到此代码,用于实行增删改查操作 1 package com.bdqn.dao; import java.sql.Connection; import java.sql.Dri ...

  4. java项目常用 BaseDao BaseService

    java项目常用 BaseDao BaseService IBaseDao 1 package com.glht.sim.dao; 2 3  import java.util.List; 4 5 6 ...

  5. BaseDao

    public class BaseDao { private static Log logger = LogFactory.getLog(BaseDao.class); // 查询数据 public ...

  6. ssh注解basedao简单的实现

    @Repository public class BaseDao extends HibernateDaoSupport{ protected Class objectClass; protected ...

  7. baseDao 使用spring3+hibernate4方式

    启动异常: java.lang.ClassCastException: org.springframework.orm.hibernate4.SessionHolder cannot be cast  ...

  8. baseDao 使用spring3+hibernate3方式

    package cn.zk.pic.service.dao; import java.io.Serializable; import java.util.List; import java.util. ...

  9. 一种好的持久层开发方法——建立BaseDao和BaseDaoImpl

    使用hibernate开发持久层时,我们会发现:虽然entity类的含义和需求不同,其对应的Dao层类对应的方法也是不同的.但是有许多方法操作确实相同的.比如实体的增加,删除,修改更新,以及许多常用的 ...

  10. Hibernate的BaseDao辅助类

    1.BaseDao接口类,该类封装了一些hibernate操作数据库的一些常用的方法,包括分页查询,使用该类极大的简化了hibernate的开发 BaseDao.java package com.kj ...

随机推荐

  1. python 全栈开发,Day79(Django的用户认证组件,分页器)

    一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...

  2. Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)

    a:数据库的相关知识: (1):一个表能否有多个主键:不能: (2):为什么要设置主键:数据库存储的数据都是有效的,必须保持唯一性: (3)为什么id作为主键:因为表中通常找不到合适的列作为唯一列,即 ...

  3. 《Java程序性能优化》之设计优化

    豆瓣读书:http://book.douban.com/subject/19969386/ 第一章 Java性能调优概述 1.性能的参考指标 执行时间: CPU时间: 内存分配: 磁盘吞吐量: 网络吞 ...

  4. bzoj4184

    题解: 按时间分治线段树 然后线性基维护一下就好了 尝试了一下循环展开并没有什么效果 代码: #include <bits/stdc++.h> using namespace std; ; ...

  5. In Action HDU3339

    这是最短路问题和01背包问题的相结合 第一次用01背包 把j打成了i检查了半个小时  下次要注意! 使用的油耗相当于容量  而power相当于价值 先用dijkstra把从基地到所有路的最短情况算出来 ...

  6. Spring MVC 注解 @RequestParam解析

    在Spring MVC 后台控制层获取参数的方式主要有两种,一种是requset.getParameter(“name”),另一种是用注解@Resquest.Param直接获取. 一.基本使用获取提交 ...

  7. SQL Server中查找包含某个文本的存储过程

    SELECT name,text from sysobjects o,syscomments s where o.id=s.id and text LIKE '%text%' and o.xtype= ...

  8. BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演

    https://www.lydsy.com/JudgeOnline/problem.php?id=3994 https://blog.csdn.net/qq_36808030/article/deta ...

  9. Vijos.lxhgww的奇思妙想(k级祖先 长链剖分)

    题目链接 https://blog.bill.moe/long-chain-subdivision-notes/ http://www.cnblogs.com/zzqsblog/p/6700133.h ...

  10. BZOJ.3757.苹果树(树上莫队)

    题面链接 /* 代码正确性不保证..(不过交了SPOJ没WA T了最后一个点) 在DFS序做莫队 当一个点不是另一个点的LCA时,需要加上它们LCA的贡献 */ #include <cmath& ...