CustomerDAO及CustomerImpl的实现 & CustomerImpl的单元测试
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的单元测试的更多相关文章
- Intellij idea添加单元测试工具
1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...
- Python的单元测试(二)
title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...
- Python的单元测试(一)
title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...
- javascript单元测试框架mochajs详解
关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...
- 使用NUnit为游戏项目编写高质量单元测试的思考
0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...
- 我这么玩Web Api(二):数据验证,全局数据验证与单元测试
目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试 一.模型状态 - ModelState 我理解 ...
- ABAP单元测试最佳实践
本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...
- python_单元测试unittest
Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...
- .Net中的AOP系列之《单元测试切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...
随机推荐
- Java——接口相关知识
1.接口用interface来声明 //定义一个动物接口 public interface Animal{ public void eat(); public void travel(); } 2.接 ...
- Spring Cloud Alibaba系列(二)nacos作为服务配置中心
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...
- Android下拉刷新SwipeRefreshLayout简单用法
之前一直都想用下拉刷新,感觉上是庞大的工程,所以搁置了.现在学习了一下其实真的超级简单. 看了<第一行代码>以及 https://www.jianshu.com/p/3c402a9e4b7 ...
- 使用Pandas读取CSV文件
使用Pandas读取CSV文件 import pandas as pd csv_data = pd.read_csv('birth_weight.csv') # 读取训练数据 print(csv_da ...
- Spring Boot Admin简介及实践
问题 在若干年前的单体应用时代,我们可以相对轻松地对整个业务项目进行健康检查.指标监控.配置管理等等项目治理.如今随着微服务的发展,我们将大型单体应用按业务模型进行划分,以此形成众多小而自治的微服务, ...
- 爬虫系列 一次采集.NET WebForm网站的坎坷历程
今天接到一个活,需要统计人员的工号信息,由于种种原因不能直接连数据库 [无奈].[无奈].[无奈].采取迂回方案,写个工具自动登录网站,采集用户信息. 这也不是第一次采集ASP.NET网站,以前采集的 ...
- JS实现手机号码中间4位变星号
这个问题,我们可以用截取字符串解决,以下我列出2种方法,小伙伴们可以根据自己的需要选择哦: ● 1,substring()方法用于提取字符串中介于两个指定下标之间的字符. '; //该号码是乱打出来的 ...
- 深度学习中的序列模型演变及学习笔记(含RNN/LSTM/GRU/Seq2Seq/Attention机制)
[说在前面]本人博客新手一枚,象牙塔的老白,职业场的小白.以下内容仅为个人见解,欢迎批评指正,不喜勿喷![认真看图][认真看图] [补充说明]深度学习中的序列模型已经广泛应用于自然语言处理(例如机器翻 ...
- 👋嗨,你有一份微信好友报告待查收~
全部代码都已上传至我的KLab-
- Shiro+Mybatis实现登录认证、授权功能
Shiro+Mybatis实现登录认证.授权功能 一.实现登录认证功能 1.流程: 跟据用户提交表单的账号,经Mybatis框架在数据库中查出User对象: 如果User为空,则会抛出异常:Unkno ...