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

文章目录

  • 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.mzph.cn/news/129711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决mysql数据库root用户看不到库

第一种方式&#xff1a; 1.首先停止MySQL服务&#xff1a;service mysqld stop 2.加参数启动mysql&#xff1a;/usr/bin/mysqld_safe --skip-grant-tables & 然后就可以无任何限制的访问mysql了 3.root用户登陆系统&#xff1a;mysql -u root -p mysql 4.切换数据库&#…

【Flutter】Flutter 动画深入解析(1):掌握 AnimationController 的使用

【Flutter】Flutter 动画深入解析(1):掌握 AnimationController 的使用 文章目录 一、前言二、AnimationController 简介三、AnimationController 的主要功能四、Ticker 提供者五、AnimationController 的生命周期六、与 AnimationController 一起使用的 Future七、实际业务…

PS2024免费磨皮滤镜Portraiture插件下载

Portraiture 4是一款适用于LR的人像智能磨皮美化滤镜插件&#xff0c;操作简便、省去了选择蒙版和逐步像素处理的繁琐流程&#xff0c;帮助您实现高效的肖像修饰。快速对照片中皮肤、头发、眉毛等部位进行美化&#xff0c;无需手动调整&#xff0c;大大提高P图效率。全新4版本&…

C#线程学习,线程的创建,线程的暂停,线程的锁lock,Monitor,线程使用中的注意事项(一)

C#线程学习&#xff0c;线程的创建&#xff0c;线程的暂停&#xff0c;线程的锁lock,Monitor&#xff0c;线程使用中的注意事项&#xff08;一&#xff09; 八股文 线程和进程 进程是指程序的一次执行过程&#xff0c;而线程是指进程中执行的一条单一逻辑控制流。 进程是由多…

Redis ACL安全策略详解

一&#xff0c;redis新特性ACL安全策略介绍 在 Redis6 之前的版本&#xff0c;我们只能使用 requirepass 参数给 default 用户配置登录密码&#xff0c;同一个 redis 集群的所有开发都共享 default 用户&#xff0c;难免会出现误操作把别人的 key 删掉或者数据泄露的情况。 因此…

基于单片机的智能鱼缸控制系统的设计与实现

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、开发技术和原理的相关知识2.1开发设计目标2.2 开发设计使用技术和原理2.2.1嵌入式技术2.2.2传感器技术 二、基于单片机的智能鱼缸控制系统的总体设计3.1智能鱼缸控制系统的基本组成3.1.1系统的构成部分3.2需求…

高校动物实验室建设要点

高校动物实验室应按照合理的规划布局进行设计&#xff0c;以便满足实验教学和科学研究的需求。如区分功能区域。根据实验室的不同功能&#xff0c;划分出饲养区、实验区、准备区和储存区等功能区域。动物房应根据不同种类动物的需求进行布置&#xff0c;确保各种动物的饲养条件…

uni-app 解决钉钉小程序日期组件uni-datetime-picker不兼容ios问题

最近在使用uni-app开发 钉钉小程序 &#xff0c;遇到一个ios的兼容性问题 uni-datetime-picker 组件在模拟器上可以使用&#xff0c;在真机上不生效问题 文章目录 1. 不兼容的写法&#xff0c;uni-datetime-picker 不兼容IOS2. 兼容的写法&#xff0c;使用 dd.datePicker 实现。…

【ZMQ】ZMQ/ZeroMQ简介、三种消息模式demo程序

ZMQ/ZeroMQ简介、三种消息模式demo程序 一、什么是ZMQ二、ZMQ的特点三、Demo程序代码3.1 发布-订阅模式&#xff08;P/S&#xff09;demo3.2 请求-应答模式&#xff08;REQ/RES&#xff09;demo3.3 推拉模式&#xff08;P/P&#xff09;demo 一、什么是ZMQ ZeroMQ&#xff08;…

Java数组小练习求出数组中的最大值

加油&#xff0c;新时代打工人&#xff01; Java基础八之数组的定义和获取元素 package demo;/*** author wenhao* date 2023/11/04 10:47* description 数组练习*/ public class ArrDemo {public static void main(String[] args) {//求一个数组中的最大值int [] arr {66,12…

ActiveMQ是什么?-九五小庞

MQ是消息中间件&#xff0c;是一种在分布式系统中应用程序借以传递消息的媒介&#xff0c;常用的有ActiveMQ&#xff0c;RabbitMQ&#xff0c;kafka。ActiveMQ是Apache下的开源项目&#xff0c;完全支持JMS1.1和J2EE1.4规范的JMS Provider实现。特点&#xff1a;1、支持多种语言…

Cross-Entropy Loss(多分类损失函数)

文章目录 1. 网络输出output&#xff1a;score2. Cross-Entropy Loss(多分类损失函数) 1. 网络输出output&#xff1a;score 2. Cross-Entropy Loss(多分类损失函数) 先用softmax function把score 变成 probabilities。再用交叉熵损失函数来进行Loss的计算

10个常用的React UI组件库

背景&#xff1a;在快速变化的前端开发世界中&#xff0c;react前端框架简洁明了&#xff0c;赢得了全球开发者的广泛青睐&#xff0c;相比于从零开始创建每一个组件&#xff0c;使用现成的 React UI 组件库可以极大地提高我们的开发效率&#xff0c;React社区已经积累了大量优…

【Midjourney入门教程4】与AI对话,写好prompt的必会方法

文章目录 1、语法2、单词3、要学习prompt 框架4、善用参数&#xff08;注意版本&#xff09;5、善用模版6、临摹7、垫图 木匠不会因为电动工具的出现而被淘汰&#xff0c;反而善用工具的木匠&#xff0c;收入更高了。 想要驾驭好Midjourney&#xff0c;可以从以下方面出发调整&…

搭建 L2TP over IPSec VPN

记得开放允许访问 UDP 500、1701、4500共3个端口 1. 服务器安装软件: yum -y install openswan xl2tpd ppp2. 服务器配置文件 /etc/ipsec.conf 修改内容如下&#xff0c;云服务器一般网卡地址填私网地址: config setupprotostacknetkeylogfile/var/log/ipsec.logvirtual_pri…

智能工厂架构

引:https://www.bilibili.com/video/BV1Vs4y167Kx/?spm_id_from=333.788&vd_source=297c866c71fa77b161812ad631ea2c25 智能工厂框架 智能工厂五层系统框架 MES 数据共享 <

JumpServer开源堡垒机与万里安全数据库完成兼容性认证

近日&#xff0c;中国领先的开源软件提供商FIT2CLOUD飞致云宣布&#xff0c;JumpServer开源堡垒机已经与万里安全数据库软件GreatDB完成兼容性认证。针对产品的功能、性能、兼容性方面&#xff0c;经过双方共同测试&#xff0c;万里安全数据库软件&#xff08;简称&#xff1a;…

软件测试用例方法---边界值法

原则&#xff1a; 输入最小值&#xff08;min&#xff09;、稍大于最小值&#xff08;min&#xff09;、域内任意值&#xff08;nom&#xff09;、稍小于最大值&#xff08;max-&#xff09;、最大值&#xff08;max&#xff09; 写法&#xff1a;“单故障”假设&#xff08;致…

Redis Part2

Redis中如何的去存放一个Java对象&#xff1f; 直接存放Json类型即可&#xff0c;因为我们Json类型最终就是一个String类型。 Spring Boot整合Redis 三步骤完成SpringBoot对Redis数据库的整合 引入spring-boot-starter-data-redis依赖在application.yml中配置Redis信息注入Re…

关于pytorch张量维度转换及张量运算

关于pytorch张量维度转换大全 1 tensor.view()2 tensor.reshape()3 tensor.squeeze()和tensor.unsqueeze()3.1 tensor.squeeze() 降维3.2 tensor.unsqueeze(idx)升维 4 tensor.permute()5 torch.cat([a,b],dim)6 torch.stack()7 torch.chunk()和torch.split()8 与tensor相乘运算…