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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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的计算

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

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

智能工厂架构

引: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相乘运算…

Unity中Shader的GI相关数据的准备

文章目录 前言一、把 Unity 中用到的 GI 的函数移植到我们自定义的 cginc 文件中二、开始使用和 GI 相关的方法1、了解 UnityGI 结构体的内容,并且准备 UnityGI 的数据2、了解 SurfaceOutput 结构体&#xff0c;并且准备数据3、了解并准备 UnityGIInput 结构体&#xff0c;并且…

centos7安装oxidized备份软件

首先需要提前下载ruby&#xff0c;因为默认yum安装的版本太低 https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz 1、yum remove ruby ruby-devel&#xff08;有就卸载&#xff0c;没有则忽略&#xff09; 2、将下载好的ruby包解压到/opt下 [rootoxidized ruby-…

第6章_多表查询

文章目录 多表查询概述1 一个案例引发的多表连接1.1 案例说明1.2 笛卡尔积理解演示代码 2 多表查询分类讲解2.1 等值连接 & 非等值连接2.1.1 等值连接2.1.2 非等值连接 自连接 & 非自连接内连接与外连接演示代码 3 SQL99语法实现多表查询3.1 基本语法3.2 内连接&#x…

2023.11.03 homework

小学4年级数学 1 2 3 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 19…

我的大语言模型微调踩坑经验分享

由于 ChatGPT 和 GPT4 兴起&#xff0c;如何让人人都用上这种大模型&#xff0c;是目前 AI 领域最活跃的事情。当下开源的 LLM&#xff08;Large language model&#xff09;非常多&#xff0c;可谓是百模大战。面对诸多开源本地模型&#xff0c;根据自己的需求&#xff0c;选择…

【Midjourney入门教程1】Midjourney的注册、订阅

文章目录 前言一、Midjourney是什么二、Midjourney注册三、新建自己的服务器四、开通订阅 前言 AI绘画即指人工智能绘画&#xff0c;是一种计算机生成绘画的方式。是AIGC应用领域内的一大分支。 AI绘画主要分为两个部分&#xff0c;一个是对图像的分析与判断&#xff0c;即“…

Azure 机器学习 - 无代码自动机器学习的预测需求

了解如何在 Azure 机器学习工作室中使用自动化机器学习在不编写任何代码行的情况下创建时序预测模型。 此模型将预测自行车共享服务的租赁需求。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕…

Linux flock和fcntl函数详解

文章目录 flock函数描述返回值和错误码笔记 fcntl函数描述复制文件描述符文件描述标志文件状态标志 咨询锁强制锁管理信号租赁文件和目录变更通知改变管道容量 返回值错误备注遗留问题 flock函数 主要功能是在已打开的文件应用或者删除共享锁或者独占锁。sys/file.h声明了这个…