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. 【Hadoop离线基础总结】Hue与Mysql集成

    Hue与Mysql集成 1.修改hue.ini配置文件 这里要去掉#,打开mysql注释,大概在1547行 [[[mysql]]] nice_name="My SQL DB" en ...

  2. Linux共享库简单总结

    库 静态库 编译的二进制会重新包含一份静态库的副本 共享库 编译 gcc -shared -o file.c -fPIC 链接 ld ld-linux.so.2 可执行程序–>动态依赖表 流程: ...

  3. Mybatis-入门演示

    MyBatis:持久层框架 前言 之前有看过和学习一些mybatis的文章和内容,但是没有去写过文章记录下,现在借鉴b站的狂神视频和官方文档看来重新撸一遍入门.有错误请多指教. 内容 数据访问层-相当 ...

  4. Git管理修改、撤销修改、删除文件

    什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改. a.管理修改 对于提交修改, ...

  5. [hdu4358]树状数组

    思路:用一个数组记录最近k次的出现位置,然后在其附近更新答案.具体见代码: #pragma comment(linker, "/STACK:10240000,10240000") ...

  6. Pytorch使用分布式训练,单机多卡

    pytorch的并行分为模型并行.数据并行 左侧模型并行:是网络太大,一张卡存不了,那么拆分,然后进行模型并行训练. 右侧数据并行:多个显卡同时采用数据训练网络的副本. 一.模型并行 二.数据并行 数 ...

  7. Python内置函数列表

    函数 用途 abs() 返回数字绝对值 all() 判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False any() 判断给定的可迭代参数 ...

  8. docker 容器核心技术

    容器的数据卷(volume)也是占用磁盘空间,可以通过以下命令删除失效的volume: [root@localhost]# sudo docker volume rm $(docker volume ...

  9. React:Lifting State Up

    在学习React的组件的时候,我也好奇组件间需要共享状态或通信的时候,React是如何处理的.在文档的QUICK START的提到Lifting State Up(状态提升),并不是什么新鲜东西.只是 ...

  10. 【python深度学习】KS,KL,JS散度 衡量两组数据是否同分布

    目录 KS(不需要两组数据相同shape) JS散度(需要两组数据同shape) KS(不需要两组数据相同shape) 奇怪之处:有的地方也叫KL KS距离,相对熵,KS散度 当P(x)和Q(x)的相 ...