目    录(本篇字数:1858)

介绍

通用Dao

一、Dao泛型接口

二、JavaBean

三、Dao接口实现类

四、单元测试

五、反射工具类


  • 介绍

Dao设计模式(Data Access Object),称为数据访问对象。它是对于数据库操作的一种设计方式,把Dao设计为一个通用接口,提供对数据库进行增、删、改、查的一系列操作数据库的抽象方法。

面向对象编程的核心就是类、对象。数据库中每一张Table可以看作一个Class,而列就可以看作类中的一些属性。这是面向对象的基本思想,通过这种思想我们需要提供的Class就相当于Table的数量。而每次对数据库的操作时,根据查询的Table不同,就会得到不同的Class。

又因为每个Class中操作增、删、改、查的方法都大相近庭,这就造成的代码的冗余、所以就出现Dao的设计思想。利用Dao接口提供的抽象方法对数据库进行操作就大大的降低代码重复,间接地可以提高程序的效率、性能等。

  • 通用Dao

下面我们来编写一个通用的Dao,虽然有许多第三方的开源框架,其内部实现也是万变不离其中。其中用到数据库连接池(c3p0、dbcp)与DBUtils工具包,如果对这几个包的使用不是很清楚的话,推荐我写的上篇文章:数据库连接池(dbcp、c3p0)与DBUtils工具包的使用

一、Dao泛型接口

    下面是我们的Dao接口代码,提供了几种最基本的增、删、改、查的抽象方法。该接口传入一个泛型的实体类(如:UserBean)。

public interface Dao<T> {// 提供查询一个 beanT query(Connection conn, String sql, Object... args) throws SQLException;// 提供查询一个列表,如 beanListList<T> queryAll(Connection conn, String sql, Object... args) throws SQLException;// 提供查询单个值Object queryValue(Connection conn, String sql, Object... args) throws SQLException;// 提供增、删、改的操作void update(Connection conn, String sql, Object... args) throws SQLException;
}

二、JavaBean

UserBean类,该类作为数据库映射到类的基础。

package com.xww;public class User {public String userName;public String password;public String registerTime;public String sex;public String userRole;public String idCard;public User() {super();}public User(String userName, String password, String registerTime, String sex, String userRole, String idCard) {super();this.userName = userName;this.sex = sex;this.userRole = userRole;this.password = password;this.idCard = idCard;this.registerTime = registerTime;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getUserRole() {return userRole;}public void setUserRole(String userRole) {this.userRole = userRole;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getIdCard() {return idCard;}public void setIdCard(String idCard) {this.idCard = idCard;}public String getRegisterTime() {return registerTime;}public void setRegisterTime(String registerTime) {this.registerTime = registerTime;}@Overridepublic String toString() {return "User [userName=" + userName + ", password=" + password + ", registerTime=" + registerTime + ", sex="+ sex + ", userRole=" + userRole + ", idCard=" + idCard + "]\n";}
}

三、Dao接口实现类

接着,我们有了Dao接口和JavaBean就应该编写Dao接口的实现类。

package com.xww;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;public class DaoImpl<T> implements Dao<T> {QueryRunner queryRunner = null;Class<T> type = null;public DaoImpl() {queryRunner = new QueryRunner();System.out.println(this.getClass());type = ReflectionUtils.getSuperGenericType(getClass());}@Overridepublic T query(Connection conn, String sql, Object... args) throws SQLException {return queryRunner.query(conn, sql, new BeanHandler<T>(type), args);}@Overridepublic List<T> queryAll(Connection conn, String sql, Object... args) throws SQLException {return queryRunner.query(conn, sql, new BeanListHandler<T>(type), args);}@Overridepublic Object queryValue(Connection conn, String sql, Object... args) throws SQLException {return queryRunner.query(conn, sql, new ScalarHandler<T>(), args);}@Overridepublic void update(Connection conn, String sql, Object... args) throws SQLException {queryRunner.update(conn, sql, args);}}

该类有一个Class<T> type 类型的变量,那么这个type类型就是我们传入的JavaBean(本例子中就是:User类)。这里涉及到利用Java反射来获取运行时中类的父类中传入的泛型 T 。如果对反射不懂的可以看这篇文章:Java反射机制(Reflection)获取运行时类的结构

还有一个类是UserDao,它继承了DaoImpl类,拥有了父类的方法,同时在需求更改的情况下,可以进行对UserDao的拓展,在本例子中,并没有什么需要拓展的,就可以写为这样,传入一个类型为User的泛型即可。

package com.xww;public class UserDao extends DaoImpl<User> {}

四、单元测试

再接着,是我们的单元测试类,提供对Dao接口设计的测试,在实际运用中也是如此使用。

package com.xww;import static org.junit.Assert.*;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;import org.junit.Test;public class UserDaoTest {UserDao userDao = new UserDao();@Testpublic void testQuery() {Connection conn = null;String sql = "select username,password,registertime,sex,userrole,idcard from user where username=?";conn = JdbcUtils.getConnectionForC3P0();try {User user = (User) userDao.query(conn, sql, "小王");System.out.println(user);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.release(null, conn, null);}}@Testpublic void testQueryAll() {Connection conn = null;String sql = "select username,password,registertime,sex,userrole,idcard from user";conn = JdbcUtils.getConnectionForC3P0();try {List<User> users = (List<User>) userDao.queryAll(conn, sql);System.out.println(users);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.release(null, conn, null);}}@Testpublic void testQueryValue() {Connection conn = null;String sql = "select userrole from user where username=?";conn = JdbcUtils.getConnectionForC3P0();try {Object val = userDao.queryValue(conn, sql, "小王");System.out.println(val);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.release(null, conn, null);}}@Testpublic void testUpdate() {Connection conn = null;String sql = "update user set userrole=? where username=?";conn = JdbcUtils.getConnectionForC3P0();try {userDao.update(conn, sql, "普通用户", "小王");} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.release(null, conn, null);}}
}

这里要注意一下:我们的UserDao继承自UserImpl,所以我们new的一个对象是UserDao的,即在UserImpl中获取的getClass()对象便是UserDao的对象,这里得区别清楚,否则获取父类的泛型会有一个坑。

五、反射工具类

最后,是我们的获取父类的泛型的一个工具类:

package com.xww;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class ReflectionUtils {@SuppressWarnings("unchecked")public static Class getSuperClassGenricType(Class clazz, int index) {Type genType = clazz.getGenericSuperclass();System.out.println(genType);if (!(genType instanceof ParameterizedType)) {return Object.class;}Type[] params = ((ParameterizedType) genType).getActualTypeArguments();if (index >= params.length || index < 0) {return Object.class;}if (!(params[index] instanceof Class)) {return Object.class;}return (Class) params[index];}@SuppressWarnings("unchecked")public static <T> Class<T> getSuperGenericType(Class clazz) {return getSuperClassGenricType(clazz, 0);}public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {// superClass.getMethod(methodName, parameterTypes);return superClass.getDeclaredMethod(methodName, parameterTypes);} catch (NoSuchMethodException e) {e.printStackTrace();}}return null;}public static void makeAccessible(Field field) {if (!Modifier.isPublic(field.getModifiers())) {field.setAccessible(true);}}public static Field getDeclaredField(Object object, String filedName) {for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {return superClass.getDeclaredField(filedName);} catch (NoSuchFieldException e) {e.printStackTrace();}}return null;}public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes, Object[] parameters)throws InvocationTargetException {Method method = getDeclaredMethod(object, methodName, parameterTypes);if (method == null) {throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");}method.setAccessible(true);try {return method.invoke(object, parameters);} catch (IllegalAccessException e) {e.printStackTrace();}return null;}public static void setFieldValue(Object object, String fieldName, Object value) {Field field = getDeclaredField(object, fieldName);if (field == null)throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");makeAccessible(field);try {field.set(object, value);} catch (IllegalAccessException e) {e.printStackTrace();}}public static Object getFieldValue(Object object, String fieldName) {Field field = getDeclaredField(object, fieldName);if (field == null)throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");makeAccessible(field);Object result = null;try {result = field.get(object);} catch (IllegalAccessException e) {e.printStackTrace();}return result;}
}

数据库User Table:

©原文链接:https://blog.csdn.net/smile_Running/article/details/86767924

@作者博客:_Xu2WeI

@更多博文:查看作者的更多博文

转载于:https://www.cnblogs.com/xww0826/p/10359478.html

Dao设计模式(Data Access Object)相关推荐

  1. SAP Hybris和ABAP Netweaver里的DAO(Data access object)

    DAO在Hybris里的定义: A DAO (Data Access Object) is an interface to the storage back end system. DAOs stor ...

  2. DAO数据访问对象(Data Access Object)

    持久化是将程序中数据库在瞬时状态和持久状态间转换的机制JDBC是一种持久化的机制,将程序直接保存成文本文件也是持久化机制的一种实现 JDBC的封装: 原因: JDBC将程序中的数据持久化保存到MySQ ...

  3. Java Data Access Object Pattern(数据访问对象模式)

    数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来.以下是数据访问对象模式的参与者. 数据访问对象接 ...

  4. DAO(Data Access Object ,数据访问对象)设计模式

    DAO开发 DAO开发完全围绕着数据操作进行. (1)下面按照DAO的方式完成后端代码的开发,首行定义VO类,VO类的名称与表的名称一致,但是要注意类的命名的规范---单词首字母大写. package ...

  5. MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)...

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. Java 分层设计(DAO设计模式)

    此文章是本人学习mldn魔乐科技DAO设计模式教学视频后,总结下来,用于复习使用,在这里感谢mldn的学习视频. DAO设计模式? DAO全称是(Data Access Object,数据库访问对象) ...

  7. JavaBean中DAO设计模式介绍

    一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是client,简单的来说就是浏览器. 2.显示层:JSP/ ...

  8. android dao设计模式,DAO设计模式

    1. DAO简介 DAO的全称是:Data Access Object,数据访问对象.使用DAO设计模式来封装数据库持久层所有操作(CRUD) ,使低级的数据逻辑和高级的业务分离,达到解耦合的目的. ...

  9. dao设计模式_DAO设计模式

    dao设计模式 DAO stands for Data Access Object. DAO Design Pattern is used to separate the data persisten ...

最新文章

  1. BS开发中常用的Javascript技术
  2. Ajax请求利用jsonp实现跨域
  3. 升级oracle spu,关于Oracle数据库PSU/SPU/BundlePatch的补丁号变化
  4. oracle与mysql的区别总结(一)
  5. 2018计算机二级c知识,2018全国计算机二级考试C语言常考知识点归纳
  6. 三菱plc控制电动推杆
  7. 手机无线投屏到linux电脑,scrcpy - 手机无线投屏到电脑
  8. vm压缩linux vmdk文件,vmware下vmdk文件越来越大的解决方法探讨
  9. 云服务器免费suse系统,suse系统
  10. 第三届大湾区杯B题思路及代码-基于宏观经济周期的大类资产配置策略构建
  11. plc开关量输入输出模块的选择
  12. javascript英语单词音节拆分_英语连读时拆分中间单词吗?
  13. GPIOB->CRH=0XFFFF0FFF;GPIOB->CRH|=(u32)8<<12;(学习笔记)
  14. iOS开发基础-常用组件(上)
  15. AudioUnit录制音频+耳返(四)
  16. pythonif多个条件同时满足_Python if有多个条件怎么办
  17. 我的世界是一款自由度非常高的游戏,你玩过吗?
  18. 精益生产中的标准化研究
  19. vue.js自定义LCD字体及字体压缩
  20. mac电脑解决Error: command failed: npm install --loglevel error --legacy-peer-deps

热门文章

  1. 用python画花瓣-Python:绘制樱花树
  2. cmd切换python版本-cmd 切换python版本
  3. python基础语法第10关作业-Python基础语法习题
  4. 自学python需要什么配置的电脑-入门学python需要什么配置的电脑?
  5. python语言培训班-学python培训班需要多久?深圳Python培训
  6. python中国大学排名爬虫写明详细步骤-Python爬虫--2019大学排名数据抓取
  7. 遗传算法介绍和遗传算法的python实现
  8. spring中的Aware
  9. ubuntu17.04下mysql5.7.18源码安装
  10. 题目1154:Jungle Roads