【JAVA高级】——封装JDBC中的DaoUtils工具类(Object类型方法)
创始人
2024-04-12 06:50:57

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:JAVA开发者成长之路
✨特色专栏:国学周更-心性养成之路
🥭本文内容:封装JDBC中的DaoUtils工具类(Object类型方法)

文章目录

    • 一、commonsUpdae方法
    • 二、commonsSelect方法
    • 三、RowMapper类封装resultSet结果集
    • 四、综合案例
      • 1、com.cxyzxc.www.utils包
        • 【1】DaoUtils工具类完整代码
        • 【2】DBUtils工具类完整代码
        • 【3】DateUtils工具类完整代码
      • 2、com.cxyzxc.www.entity包
      • 3、com.cxyzxc.www.advanced包
      • 4、com.cxyzxc.www.advanced.impl包
      • 5、com.cxyzxc.www.dao包
      • 6、com.cxyzxc.www.dao.impl包
      • 7、com.cxyzxc.www.service包
      • 8、com.cxyzxc.www.service.impl包
      • 9、com.cxy.zxc.view包
        • 【1】测试插入数据
        • 【2】测试删除数据
        • 【3】测试修改数据
        • 【4】测试查询一条数据
        • 【5】测试查询所有数据

在Dao层的DaoImpl类中,对数据表进行的增、删、改、查操作方法中存在很多相同的代码,可以将这些相同的代码抽取出来封装到一个类中,形成DaoUtils工具类,实现复用。以查询teacher表为例。

一、commonsUpdae方法

该方法是对数据表进行增、删、改的公共方法。

// 增、删、改三个方法封装成一个方法
public int commonsUpdate(String sql, Object... args) {Connection connection = null;PreparedStatement preparedStatement = null;// 获取数据库连接对象connection = DBUtils.getConnection();try {// 获取SQL语句发送对象preparedStatement = connection.prepareStatement(sql);if (args != null) {// 绑定参数for (int i = 0; i < args.length; i++) {preparedStatement.setObject(i + 1, args[i]);}}// 执行SQL语句int result = preparedStatement.executeUpdate();return result;} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.closeAll(null, preparedStatement, null);}return 0;
}

二、commonsSelect方法

该方法是对数据表进行查询的公共方法,可以查询一条数据,也可以查询多条数据。不管是查询一条数据还是查询多条数据,都将查询到的数据封装到Object类型的集合中。

public List commonsSelect(String sql,RowMapper rowMapper, Object... args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;List objectList = new ArrayList();// 获取数据库连接对象connection = DBUtils.getConnection();try {// 获取SQL语句发送对象preparedStatement = connection.prepareStatement(sql);if (args != null) {// 绑定参数for (int i = 0; i < args.length; i++) {preparedStatement.setObject(i + 1, args[i]);}}// 执行SQL语句resultSet = preparedStatement.executeQuery();while (resultSet.next()) {Object object = rowMapper.getRow(resultSet);objectList.add(object);}return objectList;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(null, preparedStatement, resultSet);}return null;
}
 

三、RowMapper类封装resultSet结果集

使用查询方法从表中查询出来的结果存储在ResultSet结果集中,需要从ResultSet结果集中遍历出数据封装成对应对象,然后将封装出来的对象返回给DaoImpl类使用。这个封装的过程由RowMapper类完成。

package com.cxyzxc.www.examples01;/*** 数据封装类,专门用来处理查询返回的resultSet结果集* * 针对每一个实体类,封装一个RowMapper类*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;public class RowMapper {public static Object getRow(ResultSet resultSet){Teacher teacher = null;try {//返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类int tid = resultSet.getInt("tid");String name = resultSet.getString("name");int age = resultSet.getInt("age");Date bornDate = resultSet.getDate("bornDate");String email = resultSet.getString("email");String address = resultSet.getString("address");teacher = new Teacher(tid, name, age, bornDate, email, address);return teacher;} catch (SQLException e) {e.printStackTrace();}return null;}}

四、综合案例

综合案例完全按照三层架构实现,创建不同的包存放不同的接口、实现类、工具类、测试类等代码。使用数据库中的teacher表来完成综合案例。

1、com.cxyzxc.www.utils包

该包用来存放项目开发所需要的数据库连接工具类DBUtils类、日期时间转换工具类DateUtils类,数据库操作工具类DaoUtils类

【1】DaoUtils工具类完整代码

package com.cxyzxc.www.utils;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;import com.cxyzxc.www.advanced.RowMapper;public class DaoUtils {// 增、删、改三个方法封装成一个方法public int commonsUpdate(String sql, Object... args) {Connection connection = null;PreparedStatement preparedStatement = null;// 获取数据库连接对象connection = DBUtils.getConnection();try {// 获取SQL语句发送对象preparedStatement = connection.prepareStatement(sql);if (args != null) {// 绑定参数for (int i = 0; i < args.length; i++) {preparedStatement.setObject(i + 1, args[i]);}}// 执行SQL语句int result = preparedStatement.executeUpdate();return result;} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.closeAll(null, preparedStatement, null);}return 0;}public List commonsSelect(String sql,RowMapper rowMapper, Object... args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;List objectList = new ArrayList();// 获取数据库连接对象connection = DBUtils.getConnection();try {// 获取SQL语句发送对象preparedStatement = connection.prepareStatement(sql);if (args != null) {// 绑定参数for (int i = 0; i < args.length; i++) {preparedStatement.setObject(i + 1, args[i]);}}// 执行SQL语句resultSet = preparedStatement.executeQuery();while (resultSet.next()) {Object object = rowMapper.getRow(resultSet);objectList.add(object);}return objectList;} catch (SQLException e) {e.printStackTrace();}finally {DBUtils.closeAll(null, preparedStatement, resultSet);}return null;}}
 

【2】DBUtils工具类完整代码

package com.cxyzxc.www.utils;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** 跨平台方案 注册驱动 获取连接 释放资源*/
public class DBUtils {// 读取配置文件的Mapprivate static final Properties PROPERTIES = new Properties();// 声明一个ThreadLocal对象用来存储数据库连接对象private static ThreadLocal threadLocal = new ThreadLocal();static {// 通过复用本类自带流,读取配置文件中的数据InputStream is = DBUtils.class.getResourceAsStream("/db.properties");try {// 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合PROPERTIES.load(is);// 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver)Class.forName(PROPERTIES.getProperty("driver"));} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}// 获取连接对象public static Connection getConnection() {// 将当前线程中绑定的Connection对象赋值给connection变量Connection connection = threadLocal.get();try {// 如果连接对象为null,则创建一个连接对象if (connection == null) {connection = DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("username"),PROPERTIES.getProperty("password"));// 将创建的连接对象存储到当前线程中共享threadLocal.set(connection);}} catch (SQLException e) {e.printStackTrace();}return connection;}// 释放所有资源public static void closeAll(Connection connection, Statement statement,ResultSet resultSet) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();// 将connection从threadLocal中移除threadLocal.remove();}} catch (SQLException e) {e.printStackTrace();}}// 3、开启事务public static void startTransaction() {Connection connection = null;try {connection = getConnection();connection.setAutoCommit(false);} catch (SQLException e) {e.printStackTrace();}}// 4、提交事务public static void commitTransaction() {Connection connection = getConnection();try {connection.commit();} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.closeAll(connection, null, null);}}// 5、回滚事务public static void rollbackTransaction() {Connection connection = getConnection();try {connection.rollback();} catch (SQLException e) {e.printStackTrace();} finally {DBUtils.closeAll(connection, null, null);}}
}

【3】DateUtils工具类完整代码

package com.cxyzxc.www.utils;import java.text.ParseException;
import java.text.SimpleDateFormat;/*** 日期时间工具类DateUtils*/
public class DateUtils {private static final SimpleDateFormat SIMPLEDATEFORMAT = new SimpleDateFormat("yyyy-MM-dd");// 字符串转换为java.util.Date类型日期时间public static java.util.Date strDateToUtilDate(String strDate) {try {return SIMPLEDATEFORMAT.parse(strDate);} catch (ParseException e) {e.printStackTrace();}return null;}// java.util.Date类型日期时间转换为java.sql.Date类型日期时间public static java.sql.Date utilDateToSqlDate(java.util.Date date) {// long date.getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT以来此 Date对象表示的毫秒数return new java.sql.Date(date.getTime());}// java.util.Date类转换为字符串类型public static String utilDateToString(java.util.Date date) {return SIMPLEDATEFORMAT.format(date);}}

2、com.cxyzxc.www.entity包

该包用来存储实体类,根据teacher表创建实体类Teacher类

package com.cxyzxc.www.entity;import java.util.Date;public class Teacher {/** 教师编号 */private int tid;/** 姓名 */private String name;/** 年龄 */private int age;/** 出生日期 */private Date bornDate;/** 邮箱 */private String email;/** 住址 */private String address;// 无参构造方法public Teacher() {super();}// 有参构造方法public Teacher(String name, int age, Date bornDate, String email,String address) {super();this.name = name;this.age = age;this.bornDate = bornDate;this.email = email;this.address = address;}public Teacher(int tid, String name, int age, Date bornDate, String email,String address) {super();this.tid = tid;this.name = name;this.age = age;this.bornDate = bornDate;this.email = email;this.address = address;}// getXxx()/setXxx()方法public int getTid() {return tid;}public void setTid(int tid) {this.tid = tid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Date getBornDate() {return bornDate;}public void setBornDate(Date bornDate) {this.bornDate = bornDate;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}// 重写Object类中的toString()方法@Overridepublic String toString() {return "tid=" + tid + ", name=" + name + ", age=" + age + ", bornDate="+ bornDate + ", email=" + email + ", address=" + address;}}

3、com.cxyzxc.www.advanced包

该包中存放RowMapper接口,用来约束封装对象的ORM

package com.cxyzxc.www.advanced;import java.sql.ResultSet;/*** 该接口用来约束封装对象的ORM*/
public interface RowMapper {Object getRow(ResultSet resultSet);}

4、com.cxyzxc.www.advanced.impl包

package com.cxyzxc.www.advanced.impl;/*** 数据封装类,专门用来处理查询返回的resultSet结果集* * 针对每一个实体类,封装一个RowMapper类*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;import com.cxyzxc.www.advanced.RowMapper;
import com.cxyzxc.www.entity.Teacher;public class TeacherRowMapper implements RowMapper {@Overridepublic Object getRow(ResultSet resultSet) {Teacher teacher = null;try {// 返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类int tid = resultSet.getInt("tid");String name = resultSet.getString("name");int age = resultSet.getInt("age");Date bornDate = resultSet.getDate("bornDate");String email = resultSet.getString("email");String address = resultSet.getString("address");teacher = new Teacher(tid, name, age, bornDate, email, address);return teacher;} catch (SQLException e) {e.printStackTrace();}return null;}}

5、com.cxyzxc.www.dao包

该包用来存放操作数据库的接口

package com.cxyzxc.www.dao;import java.util.List;import com.cxyzxc.www.entity.Teacher;public interface TeacherDao {//增int insert(Teacher teacher);//删int delete(int tid);//改int update(Teacher teacher);//查单个Teacher selectOne(int tid);//查所有List selectAll();}

6、com.cxyzxc.www.dao.impl包

该包用来存放数据库操作接口的实现类

package com.cxyzxc.www.dao.impl;import java.util.ArrayList;
import java.util.List;import com.cxyzxc.www.advanced.RowMapper;
import com.cxyzxc.www.advanced.impl.TeacherRowMapper;
import com.cxyzxc.www.dao.TeacherDao;
import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.utils.DaoUtils;public class TeacherDaoImpl implements TeacherDao {/** (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。* * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。* * (3)该类只对数据库一张表进行操作,从而实现复用*/DaoUtils daoUtils = new DaoUtils();RowMapper rowMapper = new TeacherRowMapper();// 新增:向teacher表中插入一条数据(一条数据对应一个Teacher对象),插入成功,返回一个受影响行数值(int类型)@Overridepublic int insert(Teacher teacher) {String sql = "insert into `teacher`(name,age,bornDate,email,address) values(?,?,?,?,?);";// 赋值Object[] args = { teacher.getName(), teacher.getAge(),teacher.getBornDate(), teacher.getEmail(), teacher.getAddress() };return daoUtils.commonsUpdate(sql, args);}// 删除:根据教师tid删除一条数据,删除成功,返回一个受影响行数值(int类型)@Overridepublic int delete(int tid) {String sql = "delete from teacher where tid = ?;";return daoUtils.commonsUpdate(sql, tid);}// 修改:修改teacher表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型)@Overridepublic int update(Teacher teacher) {String sql = "update teacher set name = ?,age = ?,bornDate = ?,email = ?,address = ? where tid = ?;";Object[] args = { teacher.getName(), teacher.getAge(),teacher.getBornDate(), teacher.getEmail(),teacher.getAddress(), teacher.getTid() };return daoUtils.commonsUpdate(sql, args);}// 查询单个:根据教师tid查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Teacher对象,将该对象返回@Overridepublic Teacher selectOne(int tid) {String sql = "select * from teacher where tid = ?;";List objectList = daoUtils.commonsSelect(sql, rowMapper, tid);if (objectList.size() == 1) {Teacher teacher = (Teacher) objectList.get(0);return teacher;} else {return null;}}// 查询所有:将teacher表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Teacher对象,将多个对象存储在集合中,返回这个集合@Overridepublic List selectAll() {List teacherList = new ArrayList();String sql = "select * from teacher;";DaoUtils daoUtils = new DaoUtils();Object[] args = null;List objectList = daoUtils.commonsSelect(sql, rowMapper, args);for (int i = 0; i < objectList.size(); i++) {teacherList.add((Teacher) objectList.get(i));}return teacherList;}}
 

7、com.cxyzxc.www.service包

该包用来存储业务层接口代码

package com.cxyzxc.www.service;import java.util.List;import com.cxyzxc.www.entity.Teacher;public interface TeacherService {//添加老师int addTeacher(Teacher teacher);//删除老师int deleteTeacher(int tid);//修改老师int updateTeacher(Teacher teacher);//查询一个老师Teacher selectOne(int tid);//查询所有老师List selectAll();}

8、com.cxyzxc.www.service.impl包

该包用来存储service层实现类代码

package com.cxyzxc.www.service.impl;import java.util.List;import com.cxyzxc.www.dao.impl.TeacherDaoImpl;
import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;public class TeacherServiceImpl implements TeacherService {@Overridepublic int addTeacher(Teacher teacher) {TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid());if (teacher2 == null) {return teacherDaoImpl.insert(teacher);} else {System.out.println("老师已存在");}return 0;}@Overridepublic int deleteTeacher(int tid) {TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();Teacher teacher2 = teacherDaoImpl.selectOne(tid);if (teacher2 == null) {System.out.println("你要删除的老师不存在,无法删除");} else {return teacherDaoImpl.delete(tid);}return 0;}@Overridepublic int updateTeacher(Teacher teacher) {TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid());if (teacher2 == null) {System.out.println("你要修改的老师不存在,无法修改");} else {return teacherDaoImpl.update(teacher);}return 0;}@Overridepublic Teacher selectOne(int tid){TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();Teacher teacher =teacherDaoImpl.selectOne(tid);return teacher;}@Overridepublic List selectAll(){TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl();return teacherDaoImpl.selectAll();}}

9、com.cxy.zxc.view包

该包用来存储测试类

【1】测试插入数据

package com.cxyzxc.www.view;import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;
import com.cxyzxc.www.utils.DateUtils;public class TestTeacherServiceImpl01Insert {public static void main(String[] args) {TeacherService teacherService = new TeacherServiceImpl();Teacher teacher = new Teacher(1004, "王五", 30, DateUtils.strDateToUtilDate("1992-10-07"), "13645678912@qq.com", "安徽合肥庐阳区");int result =teacherService.addTeacher(teacher);if(result!=0){System.out.println("老师添加成功");}}}

【2】测试删除数据

package com.cxyzxc.www.view;import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;public class TestTeacherServiceImpl02Delete {public static void main(String[] args) {TeacherService teacherService = new TeacherServiceImpl();int result =teacherService.deleteTeacher(1004);if(result!=0){System.out.println("删除成功");}}}

【3】测试修改数据

package com.cxyzxc.www.view;import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;
import com.cxyzxc.www.utils.DateUtils;public class TestTeacherServiceImpl03Update {public static void main(String[] args) {TeacherService teacherService = new TeacherServiceImpl();Teacher teacher = new Teacher(1003, "王五", 30,DateUtils.strDateToUtilDate("1992-08-07"),"13677881122@qq.com", "安徽合肥政务区");int result = teacherService.updateTeacher(teacher);if(result!=0){System.out.println("修改成功");}}}

【4】测试查询一条数据

package com.cxyzxc.www.view;import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;public class TestTeacherServiceImpl04SelectOne {public static void main(String[] args) {TeacherService teacherService = new TeacherServiceImpl();Teacher teacher = teacherService.selectOne(1002);if (teacher != null) {System.out.println(teacher);} else {System.out.println("你查询的老师不存在");}}}

【5】测试查询所有数据

package com.cxyzxc.www.view;import java.util.List;import com.cxyzxc.www.entity.Teacher;
import com.cxyzxc.www.service.TeacherService;
import com.cxyzxc.www.service.impl.TeacherServiceImpl;public class TestTeacherServiceImpl05SelectAll {public static void main(String[] args) {TeacherService teacherService = new TeacherServiceImpl();List listTeacher = teacherService.selectAll();for (int i = 0; i < listTeacher.size(); i++) {System.out.println(listTeacher.get(i));}}}

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...