BaseDAO:封装了针对于数据表的操作,提供通用的方法,完成后续针对具体表的逻辑

CustomerDAO:此接口用于规范 针对customers表的常用操作

CustomerDAOImpl:继承BaseDAO类  实现CustomerDAO接口的方法

文件目录

BaseDAO<T>

package com.aff.dao;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import com.aff.util.JDBCUtils; //封装了针对于数据表的操作
//DAO提供通用的方法,完成后续针对具体表的逻辑
//声明为抽象类,不能用来实例化,不能来造这个对象了
public abstract class BaseDAO<T> {
private Class<T> clazz = null; {
// 获取当前BaseDAO的子类继承的父类中的泛型
// 这个this为子类对象,
Type genericSuperclass = this.getClass().getGenericSuperclass();// 先获取当前对象的类,
// 再获取这个类带泛型的父类
ParameterizedType paramType = (ParameterizedType) genericSuperclass; Type[] typeArguments = paramType.getActualTypeArguments();// 获取了父类的泛型参数
clazz = (Class<T>) typeArguments[0];// 泛型的第一个参数,也就是把Customer拿到了
} // 通用的增删改操作
public int update(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
try {
// 1.预编译sql语句,返回PreparedStatement的实例
ps = conn.prepareStatement(sql);
// 2.填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);// 小心参数声明错误!!
}
// 3.执行
return ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4.资源的关闭,外面传进来的连接 不用关闭,设为null
// 主要针对数据库连接池的使用
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(null, ps);
}
return 0;
} // 通用的查询操作,用于返回数据表中的一条记录 ============================ public T getInstance(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 执行,获取结果集
ps = conn.prepareStatement(sql);
// 填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
// 获取结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
// 获取列数
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
T t = clazz.newInstance(); for (int i = 0; i < columnCount; i++) {
// 获取每个列的列值
Object columnValue = rs.getObject(i + 1); // 获取列的列名,列数 列名为元数据用来修饰ResultSet(结果集)的,
// String columnName = rsmd.getColumnName(i + 1);-- 不推荐使用
// 改为获取列的别名
String ColumnLabel = rsmd.getColumnLabel(i + 1); // 通过反射将对象指定名columnName的属性赋给指定的值columnValue
// 先拿到class
Field field = clazz.getDeclaredField(ColumnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps, rs);
}
return null;
} // 通用查询操作返回数据表中的多条记录构成的集合,泛型集合方法加<T>List<T> ========
public List<T> getForList(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 执行,获取结果集
ps = conn.prepareStatement(sql);
// 填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
// 获取结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
// 获取列数
int columnCount = rsmd.getColumnCount(); // 创建一个集合对象
ArrayList<T> list = new ArrayList<>();
while (rs.next()) {
T t = clazz.newInstance();
// 处理结果集一行数据的每一个列,给t对象指定的属性赋值
for (int i = 0; i < columnCount; i++) {
// 获取每个列的列值
Object columnValue = rs.getObject(i + 1); // 获取列的列名,列数 列名为元数据用来修饰ResultSet(结果集)的,
// 改为获取列的别名
String ColumnLabel = rsmd.getColumnLabel(i + 1); // 通过反射将对象指定名columnName的属性赋给指定的值columnValue
// 先拿到class
Field field = clazz.getDeclaredField(ColumnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
// 理解成每遍历完一行就添加进list集合中
list.add(t);
}
// while循环结束,再把添加过t对象的集合(理解为表中的每一行)返回
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps, rs);
}
return null;
} // 用于查询特殊值的问题============================
public <E> E getValue(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
if (rs.next()) {
return (E) rs.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps, rs);
}
return null;
}
}

CustomerDAO

package com.aff.dao;

import java.sql.Connection;
import java.sql.Date;
import java.util.List; import com.aff.bean.Customer; //此接口用于规范针对customers表的常用操作
public interface CustomerDAO {
// 将customer对象添加到数据库中
void insert(Connection conn, Customer cust); // 针对指定的id删除表中的一条记录
void deleteById(Connection conn, int id); // 针对内存中cust对象, 去修改数据表中指定的记录
void updateById(Connection conn, Customer cust); // 针对指定id查询得到对应的Customer对象
Customer getCustomerById(Connection conn, int id); // 查询表中的所有数据构成的集合
List<Customer> getAll(Connection conn); // 返回数据表中数据的条目数
Long getCount(Connection conn); // 返回数据表中最大的生日
Date getMaxBrith(Connection conn);
}

CustomerDAOImpl

package com.aff.dao;

import java.sql.Connection;
import java.sql.Date;
import java.util.List; import com.aff.bean.Customer;
//指明操作Customer类 BaseDAO<Customer>
public class CustomerDAOImpl extends BaseDAO<Customer> implements CustomerDAO { @Override
public void insert(Connection conn, Customer cust) {
String sql = "insert into customers(name,email, birth ) values(?,?,?)";
update(conn, sql, cust.getName(), cust.getEmail(), cust.getBirth());
} @Override
public void deleteById(Connection conn, int id) {
String sql = "delete from customers where id = ?";
update(conn, sql, id);
} @Override
public void updateById(Connection conn, Customer cust) {
String sql = "update customers set name = ?, email = ?,birth = ? where id = ?";
update(conn, sql, cust.getName(), cust.getEmail(), cust.getBirth(), cust.getId());
} @Override
public Customer getCustomerById(Connection conn, int id) {
String sql = "select id,name, email,birth from customers where id = ? ";
Customer customer = getInstance(conn, sql, id);
return customer;
} @Override
public List<Customer> getAll(Connection conn) {
String sql = "select id,name,email,birth from customers";
List<Customer> list = getForList(conn, sql);// 查所有数据最后一个形参也就不要了
return list;
} // 调用的是getvalue()的方法
// 返回记录数
@Override
public Long getCount(Connection conn) {
String sql = "select count(*) from customers";
long count = getValue(conn, sql);
return count;
} @Override
public Date getMaxBrith(Connection conn) {
String sql = "select max(birth) from customers";
return getValue(conn, sql);
} }

CustomerDAOImplTest

package com.aff.dao.junit;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
import org.junit.Test;
import com.aff.bean.Customer;
import com.aff.dao.CustomerDAOImpl;
import com.aff.util.JDBCUtils; public class CustomerDAOImplTest { private CustomerDAOImpl dao = new CustomerDAOImpl(); @Test
public void testInsert() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Customer cust = new Customer(1, "雨洁", "yujie@163.com", new Date(465134648L));
dao.insert(conn, cust);
System.out.println("添加成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} @Test
public void testDeleteById() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
dao.deleteById(conn, 22);
System.out.println("删除成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} // 测试修改的
@Test
public void testUpdateById() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Customer cust = new Customer(3, "雨洁", "yujie@163.com", new Date(232354354L));
dao.updateById(conn, cust);
System.out.println("修改成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} @Test
public void testGetCustomerById() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Customer customer = dao.getCustomerById(conn, 20);
System.out.println(customer);
System.out.println("获取成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} @Test
public void testGetAll() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
List<Customer> list = dao.getAll(conn);
list.forEach(System.out::println);
// System.out.println(list);//获取的是上面的集合,没有遍历,
// 所以会一行显示集合中的数据
System.out.println("获取成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} @Test
public void testGetCount() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Long count = dao.getCount(conn);
System.out.println(count);
System.out.println("获取成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
} @Test
public void testGetMaxBrith() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Date maxBrith = dao.getMaxBrith(conn);
System.out.println(maxBrith);
System.out.println("获取成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(conn, null);
}
}
}

CustomerDAO及CustomerImpl的实现 & CustomerImpl的单元测试的更多相关文章

  1. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  2. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  3. Python的单元测试(一)

    title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...

  4. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  5. 使用NUnit为游戏项目编写高质量单元测试的思考

    0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...

  6. 我这么玩Web Api(二):数据验证,全局数据验证与单元测试

    目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解 ...

  7. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...

  8. python_单元测试unittest

    Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...

  9. .Net中的AOP系列之《单元测试切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...

随机推荐

  1. mybatis传递参数的方法

    一.传递一个参数 例:根据员工编号查询员工的基本信息 1.在dao接口中声明一个方法 2.在mapper中实现该方法 3.测试 /** * 传递一个参数 */ public class Test02 ...

  2. CC2530串口通信

    任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX). RX:接收数据串行输入.通过采样技术来区别数据和噪音,从而恢复数据. TX :发送数据输出.当发送器被禁止时,输出引 ...

  3. CC2530入门

    一.简介 单片机(MCU)就是一个将微型计算机系统制作到里面的集成电路芯片. 微控制器的基本结构:内核+外设.内核通过寄存器控制外设:外设通过中断系统通知内核:内核与外设之间通过总线传输数据.地址及控 ...

  4. Qt保持窗口在最上方

    原文:https://blog.csdn.net/hl1hl/article/details/85244451 前言 在Qt开发桌面软件的过程中,根据开发的需求不同,我们经常需要将弹出窗口,一般常见的 ...

  5. 【Kafka】Kafka集群环境搭建

    目录 一.初始环境准备 二.下载安装包并上传解压 三.修改配置文件 四.启动ZooKeeper 五.启动Kafka集群 一.初始环境准备 必须安装了JDK和ZooKeeper,并保证Zookeeper ...

  6. js console一些常用的功能

    前言 很多时候我们在调试的时候经常用console.log,我感觉其实一个就够了,但是有时候你不可能写一步就去调试下,所以呢,经常用几个console.log,有时候挺难找的,后面翻了翻console ...

  7. org.springframework.web.bind.annotation不存在 site:blog.csdn.net(IDEA中运行springboot时报错)

    原因:MAVEN版本与IDEA版本不兼容问题, maven虽然更新比较慢,但是最新的3.6.6在与IDEA2019版本及以下版本兼容时会出现以上问题 解决办法:重新配置一个3.6低级别版本的maven ...

  8. 【雕爷学编程】Arduino动手做(49)---有源蜂鸣器模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...

  9. 学习Echarts:(一)静态图表

    Echarts是现在比较火的js图表库,官网有丰富的实例和友好的入门教程.但是图表的种类很多,配置项的参数也很多,一开始我根据图表类型翻看配置项,发现这样学效率太低了,决定先制定一个简单的学习步骤,按 ...

  10. 【遗传编程/基因规划】Genetic Programming

    目录 背景介绍 程序表示 初始化 (Initialization) Depth定义 Grow方法 Full方法 Ramped half-and-half方法 适应度(Fitness)与选择(Selec ...