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. python-os.rmdir与shutil.rmtree的区别和用法

    每次写脚本的时候,pycharm都会自动生成缓存文件__pycache__文件,在提交代码的时候还得挨个删除,于是自己写一小段代码自动循环删除此目录及下面的文件. 思路: 先将目录及其下的文件读取出来 ...

  2. 简单搜索 kuangbin C D

    C - Catch That Cow POJ - 3278 我心态崩了,现在来回顾很早之前写的简单搜索,好难啊,我怎么写不出来. 我开始把这个写成了dfs,还写搓了... 慢慢来吧. 这个题目很明显是 ...

  3. thinkphp操作phpexcel问题

    一.thinkphp引入PHPExcel到/Thinkphp/Library/Vendor/ 二.在控制器中引用 public function get_detail() { Vendor(" ...

  4. java读源码 之 list源码分析(LinkedList)

    文章目录 LinkedList: 继承关系分析: 字段分析: 构造函数分析: 方法分析: LinkedList: 继承关系分析: public class LinkedList<E> ex ...

  5. 【Scala】利用Akka的actor编程模型,实现2个进程间的通信

    文章目录 步骤 一.创建maven工程,导入jar包 二.master进程代码开发 三.worker进程代码开发 四.控制台结果 步骤 一.创建maven工程,导入jar包 <propertie ...

  6. IDEA打包JavaWeb项目

    IDEA打包JavaWeb项目 步骤: 1.配置项目->2.Build Artifacts->3.找到.war文件 具体操作: 首先,单击顶部工具栏的“File”选项,在弹出选项中选择“P ...

  7. LabVIEW(数据库自动编号)

    数据库如果字段是自动编号,则在插入数据时,可以不考虑.

  8. 1005 Spell It Right (20分)

    1005 Spell It Right (20分) 题目: Given a non-negative integer N, your task is to compute the sum of all ...

  9. java经典问题 byte b=1、b=b+1、b+=1

    直接问题: 首先 byte的范围 [-128,127] byte 类型可以自动转为int类型 int类型不能自动转为byte类型. 超过byte的范围,就会变成int类型了 byte b=1:正确, ...

  10. 【原创】Linux信号量机制分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...