JDBC数据库连接---附通用的CRUD类

news/2024/12/23 5:24:46/

文章目录

  • JDBC数据库连接
    • 1 导包
    • 2 编写配置文件
    • 3 编写连接数据库代码
    • 4 测试工具类
    • 5 附加
      • 1 通用的CRUD类
      • 2 测试CURD类
      • 3 测试

JDBC数据库连接

本篇文章以 MySQL 数据库为例,若要切换其他数据库,只需修改 resource文件夹中的 jdbc.properties 配置文件即可。
项目架构展示:
在这里插入图片描述

1 导包

将MySQL驱动包导入到 lib 目录下,导入之后右键 AS library 将驱动包添加到项目中。否则运行时会报 Class not found 异常。

驱动包下载地址汇总:https://blog.csdn.net/weixin_43671437/article/details/134141851?spm=1001.2014.3001.5501

2 编写配置文件

在Resource 目录下创建 jdbc.properties 配置文件。

## MySQL 8.x
user=root
password=root
url=jdbc:mysql://localhost:3306/jdbc_learn?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
driverClass=com.mysql.cj.jdbc.Driver ## SQLServer 连接属性
#url=jdbc:sqlserver://localhost:1433;DatabaseName=SqlMatch2005_5;encrypt=true;trustServerCertificate=true
#driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
#user=sa
#password=root

3 编写连接数据库代码

在 java --> util 包内创建一个 JDBCUtil.java 工具类

/*** ClassName: JDBCUtil* Description: 操作数据库的工具类** @Create 2023/10/29 14:35* @Version 1.0*/
public class JDBCUtil {/*获取数据库连接*/public static Connection getConnection() throws Exception {// 1 读取配置文件中的4个信息InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");Properties pros = new Properties();pros.load(is);String user = pros.getProperty("user");String password = pros.getProperty("password");String url = pros.getProperty("url");String driverClass = pros.getProperty("driverClass");// 2 加载驱动Class.forName(driverClass);// 3 获取连接Connection conn = DriverManager.getConnection(url, user, password);return conn;}/*** 关闭资源操作,增删改时使用* @param conn* @param ps*/public static void closeResource(Connection conn, Statement ps){// 7 资源关闭try {if (ps != null)ps.close();} catch (SQLException e) {e.printStackTrace();}try {if (conn != null)conn.close();} catch (SQLException e) {e.printStackTrace();}}/*** 关闭资源的操作,查询时使用* @param conn* @param ps* @param rs*/public static void closeResource(Connection conn, Statement ps, ResultSet rs){// 7 资源关闭try {if (ps != null)ps.close();} catch (SQLException e) {e.printStackTrace();}try {if (conn != null)conn.close();} catch (SQLException e) {e.printStackTrace();}try {if (rs != null) {rs.close();}} catch (SQLException e) {e.printStackTrace();}}}

4 测试工具类

测试成功,可以返回一个连接。

    @Testpublic void testConnection6() throws Exception {Connection conn = JDBCUtil.getConnection();System.out.println(conn);	// com.mysql.cj.jdbc.ConnectionImpl@1cbbffcdJDBCUtil.closeResource(conn,null);}

5 附加

1 通用的CRUD类

创建 BaseDao.java 类,可直接继承baseDao 来实现对数据库的增删改查。

/*** ClassName: BaseDao* Description: DAO: data(base) access object 数据库访问对象* 封装了针对于数据表的增删改查操作** @Create 2023/11/1 13:46* @Version 1.0*/
public abstract class BaseDao<T> {private Class<T> clazz = null;{// 获取当前BaseDao的子类继承父类的泛型Type genericSuperclass = this.getClass().getGenericSuperclass();ParameterizedType paramType = (ParameterizedType)genericSuperclass; // 获取了父类的泛型参数Type[] typeArguments = paramType.getActualTypeArguments();clazz = (Class<T>) typeArguments[0]; // 泛型的第一个参数}/*** 通用表的查询方法,但仅能查询条数据** @param conn* @param sql* @param args* @return 返回一个对象*/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[0]);}// 获取结果集rs = ps.executeQuery();// 获取结果集的元数据:ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 通过ResultSetMetaData获取结果集中的列数int columnCount = rsmd.getColumnCount();if (rs.next()) {T t = clazz.newInstance();// 处理结果集中的每一列for (int i = 0; i < columnCount; i++) {// 获取每一列的列值 通过 ResultSetObject columnValue = rs.getObject(i + 1);// 获取每一列的列名 通过 ResultSetMetaData// 获取列的列名 getColumnName() -- 不推荐使用// 获取列的别名 getColumnLabel() 没有别名时返回列名String columnLabel = rsmd.getColumnLabel(i + 1);// 给T对象指定columnName属性,赋值为columnValue,通过反射// 通俗点说:将customer中的属性与 列名 对应起来 并为属性赋值// 注意;若属性为orderID 列名order_id 此时需要为列名起别名使与属性名一致Field field = clazz.getDeclaredField(columnLabel);field.setAccessible(true);field.set(t, columnValue); // 赋值}return t;}} catch (Exception e) {e.printStackTrace();} finally {// 资源关闭JDBCUtil.closeResource(null, ps, rs);}return null;}/*** 通用表的查询操作,可返回多条数据。** @param conn* @param sql* @param args* @return 返回一个对象集合*/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[0]);}// 获取结果集rs = ps.executeQuery();// 获取结果集的元数据:ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 通过ResultSetMetaData获取结果集中的列数int columnCount = rsmd.getColumnCount();// 创建集合对象 存储查询的结果ArrayList<T> list = new ArrayList<>();// 循环遍历每一行数据while (rs.next()) {T t = clazz.newInstance();// 处理结果集中的每一列for (int i = 0; i < columnCount; i++) {// 获取每一列的列值 通过 ResultSetObject columnValue = rs.getObject(i + 1);// 获取每一列的列名 通过 ResultSetMetaData// 获取列的列名 getColumnName() -- 不推荐使用// 获取列的别名 getColumnLabel() 没有别名时返回列名String columnLabel = rsmd.getColumnLabel(i + 1);// 给T对象指定columnName属性,赋值为columnValue,通过反射// 通俗点说:将customer中的属性与 列名 对应起来 并为属性赋值// 注意;若属性为orderID 列名order_id 此时需要为列名起别名使与属性名一致Field field = clazz.getDeclaredField(columnLabel);field.setAccessible(true);field.set(t, columnValue); // 赋值}list.add(t);}// 返回数据集合return list;} catch (Exception e) {e.printStackTrace();} finally {// 资源关闭JDBCUtil.closeResource(null, ps, rs);}return null;}/*** 通用的 增删改 操作-- version 2.0 增加事务** @param conn* @param sql* @param args* @return*/public int updateTable(Connection conn, String sql, Object... args) { // sql中占位符的个数与可变形参的个数相同PreparedStatement ps = null;try {// 2 预编译sql语句,返回PreparedStatement的实例ps = conn.prepareStatement(sql);// 3 填充占位符for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]); // 注意参数错误,sql中是从1 开始 数组从0开始}// 4 执行sql语句// boolean execute = ps.execute();// if (!execute) System.out.println("执行成功!!!");// 返回影响了几行数据return ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {// 修改起为自动提交// 主要针对于使用数据库连接池的使用try {conn.setAutoCommit(true);} catch (SQLException e) {throw new RuntimeException(e);}// 5 资源关闭JDBCUtil.closeResource(null, ps);}return 0;}/***  用于查询特殊值的通用方法* @param conn* @param sql* @param args* @return* @param <E>*/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) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(null, ps, rs);}return null;}}

2 测试CURD类

在Dao层实现对 Customers 类的增删改查以及特殊值的查询
1 创建 CustomersDao.java 接口

/*** ClassName: CustomersDao* Description: 此接口用于规范 Customers 表的常用操作** @Create 2023/11/1 14:06* @Version 1.0**/
public interface CustomersDao {/***  将cust对象添加到数据库中* @param conn* @param cust*/void insert(Connection conn, Customer cust);/*** 针对指定的id,删除表中的一条记录* @param conn* @param id*/void deleteById(Connection conn, int id);/*** 针对内存中的cust对象,去修改数据表中指定的记录* @param conn* @param cust*/void update(Connection conn, Customer cust);/*** 根据指定 ID 查询到对象的Customer对象* @param conn* @param id* @return*/Customer getCustomerById(Connection conn,int id);/*** 返回所有 Customer 对象* @param conn* @return*/List<Customer> getAllCustomers(Connection conn);/*** 返回数据表中数据的条目* @param conn* @return*/Long getCount(Connection conn);/*** 返回表中最大的生日* @param conn* @return*/Date getMaxBirth(Connection conn);}

2 编写CustomersDao接口的实现类
创建 CustomerDaoImpl.java 文件,继承BaseDao并实现CustomersDao接口。

/*** ClassName: CustomerDaoImpl* Description:** @Create 2023/11/1 14:48* @Version 1.0*/
public class CustomerDaoImpl extends BaseDao<Customer> implements CustomersDao {@Overridepublic void insert(Connection conn, Customer cust) {String sql = "insert into customers(name,email,birth) values(?,?,?) ";updateTable(conn, sql, cust.getName(), cust.getEmail(), cust.getBirth());}@Overridepublic void deleteById(Connection conn, int id) {String sql = "delete from customers where id = ?";updateTable(conn, sql, id);}@Overridepublic void update(Connection conn, Customer cust) {String sql = "update customers set name = ?, email = ?, birth = ? where id = ?";updateTable(conn, sql, cust.getName(),cust.getEmail(),cust.getBirth(),cust.getId());}@Overridepublic Customer getCustomerById(Connection conn, int id) {String sql = "select id, name,email,birth from customers where id = ?";return getInstance(conn, sql, id);}@Overridepublic List<Customer> getAllCustomers(Connection conn) {String sql = "select id, name,email,birth from customers";return getForList(conn, sql);}@Overridepublic Long getCount(Connection conn) {String sql = "select count(*) from customers";return getValue(conn,sql);}@Overridepublic Date getMaxBirth(Connection conn) {String sql = "select max(birth) from customers";return getValue(conn,sql);}
}

3 测试

创建测试类 CustomerDaoImplTest 测试 CustomerDaoImpl


/*** ClassName: CustomerDaoImplTest* Description:** @Create 2023/11/1 15:18* @Version 1.0*/
public class CustomerDaoImplTest {private CustomerDaoImpl dao =  new CustomerDaoImpl();@Testpublic void insert() {Connection conn = null;try {conn = JDBCUtil.getConnection();Customer cust = new Customer(1,"songsong","songsong@163.com",new Date(21312425312L));dao.insert(conn,cust);} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void deleteById() {Connection conn = null;try {conn = JDBCUtil.getConnection();dao.deleteById(conn,2);} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void update() {Connection conn = null;try {conn = JDBCUtil.getConnection();Customer cust = new Customer(1,"songsong","songsong@163.com",new Date(21312425312L));dao.update(conn,cust);} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void getCustomerById() {Connection conn = null;try {conn = JDBCUtil.getConnection();System.out.println(dao.getCustomerById(conn, 4));} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void getAllCustomers() {Connection conn = null;try {conn = JDBCUtil.getConnection();List<Customer> customerList = dao.getAllCustomers(conn);customerList.forEach(System.out::println);} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void getCount() {Connection conn = null;try {conn = JDBCUtil.getConnection();System.out.println(dao.getCount(conn));} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}@Testpublic void getMaxBirth() {Connection conn = null;try {conn = JDBCUtil.getConnection();System.out.println(dao.getMaxBirth(conn));} catch (Exception e) {throw new RuntimeException(e);} finally {JDBCUtil.closeResource(conn,null);}}
}

http://www.ppmy.cn/news/1194542.html

相关文章

Qt中正确的设置窗体的背景图片的几种方式

Qt中正确的设置窗体的背景图片的几种方式 QLabel加载图片方式之一Chapter1 Qt中正确的设置窗体的背景图片的几种方式一、利用styleSheet设置窗体的背景图片 Chapter2 Qt的主窗口背景设置方法一&#xff1a;最简单的方式是通过ui界面来设置&#xff0c;例如设置背景图片方法二 &…

商标服务展示预约小程序的效果如何

想要打造自己的品牌&#xff0c;商标是必要的一步&#xff0c;除了可以自己申请外&#xff0c;部分商家会选择通过第三方代理平台操作&#xff0c;在商城注册场景包括查询、资料提交、驳回复审等。 市场生意并不缺&#xff0c;对商标注册代理机构来说&#xff0c;需要不断拓客…

竖拍的视频怎么做二维码?竖版视频二维码制作技巧

为了方便视频的展示和传播&#xff0c;现在将视频生成二维码后来使用的方式越来越常见&#xff0c;很多做二维码工具都可以制作视频二维码&#xff0c;但是无法设置下载权限或者播放竖版视频。那么如果做有下载功能的视频码该如何制作&#xff0c;可能很多小伙伴都不知道怎么做…

金蝶云星空表单插件获取日期控件判空处理(代码示例)

文章目录 金蝶云星空表单插件获取日期控件判空处理C#实现 金蝶云星空表单插件获取日期控件判空处理 C#实现 DateTime? deliveryDate (DateTime?)this.View.Model.GetValue("FApproveDate");//审核日期long leadtime 20;//天数if (!deliveryDate.IsNullOrEmpty()…

【C++】基础语法(上)

C基础语法 此语法笔记面向算法竞赛考研&#xff0c;可供参考&#xff0c;本人的一些笔记的记录~ 失踪人口回归&#xff0c;将近半个月没有更新&#xff0c;那么接下来也会逐步开始更新分享知识内容~ 本篇将分享cpp基础语法中的变量、输出输入语句、表达式、顺序语句、条件判断…

PY32F071单片机,主频最高72 M,带一路DAC,USB

PY32F071 系列微控制器采用高性能的 32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围的 MCU。嵌入高达128 Kbytes flash 和 16 Kbytes SRAM 存储器&#xff0c;最高工作频率 72 MHz。包含多种不同封装类型多款产品。芯片集成多路 I2C、SPI、USART 等通讯外设&#xff0c;1 …

新一代数据质量平台datavines

在我实习的第一家公司的时候&#xff0c;有幸参与Apache Griffin的开发&#xff0c;也先后在一起其他公司使用过数据质量平台&#xff0c;同时也调研过一些开源的数据质量平台。 最近和朋友一起参与开发了datavines数据质量平台&#xff0c;随着在数据行业越呆越久&#xff0c…

【考研数据结构代码题1】二叉搜索树的插入与查找

题目&#xff1a;请用C语言写出二叉树的二叉链表结构&#xff0c;并编写一个函数在二叉搜索树中可以搜索给定的关键字 难度&#xff1a;★ 二叉树的二叉链表结构 #include<stdio.h> #include<stdlib.h> //二叉树的结点结构 typedef struct Node{int data;//存放结…