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. LeetCode 56,区间合并问题

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第33篇文章,我们一起来看LeetCode的第56题,它的难度是Medium. 题意 这道题的题意也很简单,只有 ...

  2. java基础知识备忘

    1.java内存分配 a.寄存器cup -- 暂不涉及 b.本地方法栈  -- 虚拟机调用windows功能用的,比如创建文件夹 c.方法区  -- 存放 .class文件,负责存放方法 d.栈 -- ...

  3. python操作ansible api示例

    #!/usr/bin/env python # -*- coding:utf-8 -*- import json import shutil from collections import named ...

  4. MySQL命令3

    连接 mysql -u username -p 查看进程 SHOW processlist

  5. 【GISER&&规划】我这二三年

    从从参加工作到现在,已经接近三年了.在这不长不短的时间里,我的职业规划犹如正余弦函数一样变化,一直游离在前端和后端之间. 第一年入职,被安排维护和拓展一套基于JAVA实现的地图瓦片生产工艺程序,不算复 ...

  6. 【Kafka】Stream API

    Stream API Kafka官方文档给了基本格式 http://kafka.apachecn.org/10/javadoc/index.html?org/apache/kafka/streams/ ...

  7. 绝对一个月精通vue

    马上从vue-cli4练手,要不然,学几年,你也不懂组件式开发,不懂VUEX,不懂路由, 也许你会说你懂, 麻烦你花一个月学vue-cli4以一个完整购物商城来练手,   一个月后,如果还觉得我错,我 ...

  8. u-boot 移植(二)创建新平台的板级支持

    u-boot 移植(二)创建新平台的板级支持 soc:s3c2440 board:jz2440 uboot:u-boot-2016.11 toolchain:gcc-linaro-7.4.1-2019 ...

  9. CF #635D Xenia and Colorful Gems 枚举+二分

    Xenia and Colorful Gems 题意 给出三个数组,在每个数组中选择一个数字x,y,z,,使得\((x-y)^2+(y-z)^2+(x-z)^2\)最小. 思路 我们假设x<=y ...

  10. 如何将Altera官方提供的CADENCE.OLB应用于altium Designer中