当前位置:网站首页>JDBC-DAO层实现
JDBC-DAO层实现
2022-06-25 06:40:00 【Maximize+】
我们先简单的说一下关于DAO层的实现逻辑
首先先创建一个抽象类BaseDAO,在该抽象类中声明增删改查的方法;其次创建一个CustomersDAO的接口,用于书写规范;创建一个实现类,继承BaseDAO抽象类并且引入接口CUstmersDAO接口,进行重写方法;创建一个测试类,创建事务代码并执行。
BaseDAO抽象类
package dao;
import JDBCUtils.JDBCUtils;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
/* 封装了针对数据表的通用操作 */
public abstract class BaseDAO {
//考虑事务的通用增删改操作
//update的方法参数为
/* Connection conn:JDBC连接桥梁 String sql:MySQL执行语句 Object...args:通用类型数组(可变形参语法) 返回int用于查看执行是否成功 */
public int update(Connection conn,String sql,Object...args){
//创建一个PreparedStatement对象暂时赋值为Null语法用于关闭资源时作用域可识别到该对象变量
PreparedStatement ps = null;//PreparedStatement是访问操作SQL语句的接口类
try{
ps = conn.prepareStatement(sql);//进行赋值并且预编译SQL语句
//进行占位符填充遍历 使用传入Object数组长度为遍历次数
for(int i=0;i<args.length;i++){
//进行填充占位符,因为循环变量值是从0开始的,但是MySQL的索引都是1开始的
//所以这里的索引填充必须为i+1,从1开始执行,填充args的i索引内容
ps.setObject(i+1,args[i]);
}
//返回直接结果 返回类型是int 如果执行成功为1+,执行失败为0
//可以通过一个变量获取该返回值进行判断
//int flag = ps.executeUpdate if(ps==0){System.out.println("执行失败")}else{System.out.println("执行成功")}
return ps.executeUpdate();
}catch (Exception ex){
//打印异常日志
ex.printStackTrace();
}finally {
//finally是必定执行的语句,所以不要在这里放return 0或者 return null
JDBCUtils.closeResource(null,ps);//此方法是自定义工具类的关闭资源方法,算法为: if(!=null) close 避免了空指针异常
}
return 0;//如果没有执行或顺利执行上述代码则返回此处 此处为最终结果
}
//考虑事务的通用查询操作
//通用单查询结果比较复杂
/* 首先返回值是一个T泛型 方法签名为: Connection conn:一个JDBC连接桥梁 Class<T>clazz:类泛型 String sql:MySQL执行语句 Object...args:可变形参数组 */
public <T> T getInstance(Connection conn,Class<T>clazz,String sql,Object...args){
//预编译接口
PreparedStatement ps = null;
//rs结果集,查询是有结果的结果集保存了这些数据
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 coulumnCount = rsmd.getColumnCount();//获取元数据行数
if(rs.next()){
//如果rs结果集还有内容
T t = clazz.newInstance();//泛型初始化 这里相当于获取了传入形参对象
for(int i=0;i<coulumnCount;i++){
//进行遍历 遍历行数
//获取列值
Object columnValue = rs.getObject(i+1);//因为索引是从一开始的
String columnLabel = rsmd.getColumnLabel(i+1);//这里调用的是可以识别数据库别名的方法,另一个为 getColumnName
/* 这里建议使用 rsmd.getColumnLabel方法,因为该方法可以识别别名,用于解决关于封装类数据不对接的情况,以及尽管没有使用别名 效果也将和getColumnName效果一致 */
//通过反射赋值
Field field = clazz.getDeclaredField(columnLabel);//这里获取了和封装类对应的字段属性
field.setAccessible(true);//设置权限为true避免权限不够
field.set(t,columnValue);//进行赋值,对象+结果集数据
}
return t;
}
}catch (Exception ex){
ex.printStackTrace();//打印异常日志
}finally {
//必执行语句
JDBCUtils.closeResource(null,ps,rs);//关闭资源,此处conn关闭为null
/* 为null是为了实现事务,事务的连接是相同的,如果关闭连接会导致数据库自动数据提交,则破坏了事务的秩序 此处无须担心传入参数Null会报空指针异常,因为我们的算法判断为 if(conn != null){ conn.close(); } 只有不为空才会进行关闭此资源,否则无变化操作 */
}
return null;//如果从上向下执行不顺利或没有执行则返回此结果,此结果为最终结果
}
//多行查询结果通用方法
//此处的方法签名和上述程序一致
//返回值表示了一个泛型集合 它的声明类型是泛型 保存内容也是泛型
public <T>List<T> getForList(Connection conn,Class<T>clazz,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<T>();//初始化List对象 此处为ArrayList<T>
while (rs.next()){
//使用while判断结果集的下一行
T t = clazz.newInstance();//初始化clazz获取该对象
for(int i =0;i<columnCount;i++){
//进行行数遍历
Object columnValue = rs.getObject(i+1);//初始索引为1 获取数据
String columnLabel = rsmd.getColumnLabel(i+1);//获取对应字段
Field field = clazz.getDeclaredField(columnLabel);//获取类对应字段
field.setAccessible(true);//设置公开权限
field.set(t,columnValue);//执行数据填充注意此处是 for循环里的语句
}
list.add(t);//添加对象,注意此处是while循环语句里的语句
//最常见的就是 while 套 for循环了 while循环比较简单明了 对于简单的单数据遍历的效率和简易程度还是非常好的
}
return list;//最后返回该数组,该数组保存了所有的查询结果
}catch(Exception ex){
ex.printStackTrace();//打印异常日志
}finally {
//必执行语句
JDBCUtils.closeResource(null,ps,rs);//关闭资源,考虑到事务不关闭conn连接桥
}
return null;//最终结果 返回null
}
public <E>E getValue(Connection conn,String sql,Object...args){
PreparedStatement ps = null;
ResultSet rs = null;//获得结果集
try {
//获取PreparedStatement实例预编译SQL语句
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 (Exception throwables) {
throwables.printStackTrace();//打印异常日志
} finally {
JDBCUtils.closeResource(null,ps,rs);//关闭资源
}
return null;
}
}
CustomersDAO接口类
package dao;
import oldJDBCTest.Customer;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
//针对于规范Customer表操作
public interface CustomerDAO {
void insert(Connection conn, Customer cust);
void deleteById(Connection conn,int id);
void update(Connection conn,Customer cust);
Customer getCustomerById(Connection conn,int id);
List<Customer> getAll(Connection conn);
Long getCount(Connection conn);
Date getMaxBirth(Connection conn);
}
CustomerDAOImpl实现类
package dao;
import oldJDBCTest.Customer;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
public class CustomerDAOImpl extends BaseDAO 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 update(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, Customer.class,sql,id);
return customer;
}
@Override
public List<Customer> getAll(Connection conn) {
String sql = "select id,name,email,birth from customers";
List<Customer> forList = getForList(conn, Customer.class, sql);
return forList;
}
@Override
public Long getCount(Connection conn) {
String sql = "select count(*) from customers";
return getValue(conn,sql);
}
@Override
public Date getMaxBirth(Connection conn) {
String sql = "select max(birth) from customers";
return getValue(conn,sql);
}
}
CustomerDAOImplTest测试类
package dao;
import JDBCUtils.JDBCUtils;
import oldJDBCTest.Customer;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
public class CustomerDAOImplTest {
private CustomerDAOImpl dao = new CustomerDAOImpl();
@org.junit.jupiter.api.Test
void insert() {
Connection conn = null;
try{
conn = JDBCUtils.getConnection();
Customer cust = new Customer(1,"于小飞","[email protected]",new Date(1545154455L));
dao.insert(conn,cust);
System.out.println("添加成功");
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void deleteById() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
dao.deleteById(conn,5);
System.out.println("删除成功");
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void update() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Customer cust = new Customer(9,"贝多芬","[email protected]",new Date(453465656L));
dao.update(conn,cust);
System.out.println("修改成功");
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void getCustomerById() {
Connection conn = null;
try{
conn = JDBCUtils.getConnection();
Customer customer = dao.getCustomerById(conn,7);
System.out.println(customer);
}catch (Exception ex) {
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void getAll() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
List<Customer> all = dao.getAll(conn);
all.forEach(System.out::println);
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void getCount() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Long count = dao.getCount(conn);
System.out.println("表中的记录数量:"+count);
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
@org.junit.jupiter.api.Test
void getMaxBirth() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
Date maxBirth = dao.getMaxBirth(conn);
System.out.println("最大的生日为:"+maxBirth);
}catch (Exception ex){
ex.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,null);
}
}
}
边栏推荐
- Unity3D邪门实现之GUI下拉菜单Dropdown设计无重复项
- Storage of Galileo broadcast ephemeris in rtklib-b33
- Sichuan Tuwei ca-if1051 can transceiver has passed aec-q100 grade 1 certification
- Tempest HDMI leak receive 1
- The method of judging whether triode can amplify AC signal
- Access to foreign lead domain name mailbox
- What common APIs are involved in thread state changes
- 國外LEAD域名郵箱獲取途徑
- 基于地面点稀少的LiDAR点云的茂密森林蓄积量估算
- Why "New Year's Eve", the original memory burst!
猜你喜欢

韩信大招:一致性哈希

What is the difference between norflash and nandflash

GUI pull-down menu of unity3d evil door implementation dropdown design has no duplicate items

Elk + filebeat log parsing, log warehousing optimization, logstash filter configuration attribute

My debut is finished!
![不同路径II[针对DFS的动态规划改进]](/img/bb/1e1cee22b9de954de242d299a1a0eb.png)
不同路径II[针对DFS的动态规划改进]

Leetcode daily question - 515 Find the maximum value in each tree row

诸葛亮 VS 庞统,拿下分布式 Paxos

Domestic MCU perfectly replaces STM chip model of Italy France

VectorDraw Developer Framework 10.10
随机推荐
用动图讲解分布式 Raft
Application of point cloud intelligent drawing in intelligent construction site
C#入门教程
Summary of small problems in smartbugs installation
Introduction to Sichuan Tuwei ca-is3082w isolated rs-485/rs-422 transceiver
Audio (V) audio feature extraction
用太极拳讲分布式理论,真舒服!
Static bit rate (CBR) and dynamic bit rate (VBR)
el-input实现尾部加字
VectorDraw Web Library 10.10
npm install 报错 : gyp ERR! configure error
Chuantu microelectronics ca-if1051 can-fd transceiver
FairMOT yolov5s转onnx
[batch dos-cmd command - summary and summary] - file and directory operation commands (MD, RD, xcopy, dir, CD, set, move, copy, del, type, sort)
音频(五)音频特征提取
useMemo模拟useCallback
Notes: [open class] neural network and deep learning -- tensorflow2.0 actual combat [Chinese course]
Chuantuwei ca-is3720lw alternative material No. iso7820fdw
栅格地图(occupancy grid map)构建
Why "New Year's Eve", the original memory burst!