JDBC学习笔记(二)进阶篇

一、JDBC 扩展

1.1 实体类和ROM

实体类代码:

package com.atguigu.advanced.pojo;//类名就是数据库表的 t_ 后面的单词全写
public class Employee {private Integer empId;//emp_idprivate String empName;//emp_nameprivate Double empSalary;//emp_salaryprivate Integer empAge;//emp_age/*** 设置 无参、有参、get、set、toString 方法*/public Employee() {}public Employee(Integer empId, String empName, Double empSalary, Integer empAge) {this.empId = empId;this.empName = empName;this.empSalary = empSalary;this.empAge = empAge;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Double getEmpSalary() {return empSalary;}public void setEmpSalary(Double empSalary) {this.empSalary = empSalary;}public Integer getEmpAge() {return empAge;}public void setEmpAge(Integer empAge) {this.empAge = empAge;}@Overridepublic String toString() {return "Employee{" +"empId=" + empId +", empName='" + empName + '\'' +", empSalary=" + empSalary +", empAge=" + empAge +'}';}
}

ORM:

ORM:

以面向对象的思想去操作数据库。

即:一张表对应一个类,一行数据对应一个对象,一个列对应一个属性

package com.atguigu.advanced;import com.atguigu.advanced.pojo.Employee;
import org.junit.Test;import java.sql.*;
import java.util.ArrayList;public class JDBCAdvanced {/*** 什么是ORM* @throws Exception*/@Testpublic void testORM() throws Exception {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.创建连接对象Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");//3.获取PreparedStatement对象,执行SQL语句PreparedStatement preparedStatement = connection.prepareStatement("select * from t_emp where emp_id = ?");//4.为占位符赋值,然后执行并返回结果集preparedStatement.setInt(1,1);ResultSet resultSet = preparedStatement.executeQuery();//创建对象Employee employee = null;//5.处理结果,遍历resultSetif (resultSet.next()){employee = new Employee();int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");//为对象的属性赋值employee.setEmpId(empId);employee.setEmpName(empName);employee.setEmpSalary(empSalary);employee.setEmpAge(empAge);}System.out.println(employee);//6.释放资源resultSet.close();preparedStatement.close();connection.close();}@Testpublic void testORMList() throws Exception {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");//3.执行SQL语句,获取PreparedStatement对象PreparedStatement preparedStatement = connection.prepareStatement("select * from t_emp");//4.执行并接收返回的,结果集ResultSet resultSet = preparedStatement.executeQuery();//对象的创建Employee employee = null;ArrayList<Employee> employeeList = new ArrayList<>();//5.处理结果集,遍历resultSetwhile (resultSet.next()){employee = new Employee();int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");//为对象属性赋值employee.setEmpId(empId);employee.setEmpName(empName);employee.setEmpSalary(empSalary);employee.setEmpAge(empAge);//将每次循环封装的一行数据的对象存储在集合里employeeList.add(employee);}//处理结果:遍历集合for (Employee emp : employeeList){System.out.println(emp);}//6.释放资源resultSet.close();preparedStatement.close();connection.close();}
}

1.2 主键回显

主键回显:

在数据中,执行新增操作时,主键列为自动增长,可以在表中直观的看到,但是在Java程序中,我们执行完新增后,只能得到受影响的行数,无法得知当前新增数据的主键值。在Java程序中获取数据库中插入新数据后的主键值,并赋值给Java对象,此操作为主键回显(主键回填)。

/*** 主键回显(主键回填)* @throws Exception*/@Testpublic void testKP() throws Exception {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");//3.预编译SQL语句,获取PreparedStatement对象;告知preparedStatement,返回新增数据的主键列的值String sql = "INSERT INTO t_emp(emp_name,emp_salary,emp_age) VALUES (?,?,?)";PreparedStatement preparedStatement = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);//创建对象,将对象的属性值,填充在?占位符上(ORM)Employee employee = new Employee(null,"jack",123.45,29);preparedStatement.setString(1, employee.getEmpName());preparedStatement.setDouble(2,employee.getEmpSalary());preparedStatement.setInt(3,employee.getEmpAge());//4.执行SQL,并获取返回的结果int result = preparedStatement.executeUpdate();//5.处理结果ResultSet resultSet = null;if(result > 0){System.out.println("成功!");//获取当前新增数据的主键列,回显到Java中employee对象的empId属性上//返回的结果值,是一个单行单例的结果存储在ResultSet里resultSet = preparedStatement.getGeneratedKeys();if (resultSet.next()){int empId = resultSet.getInt(1);employee.setEmpId(empId);}System.out.println(employee);}else {System.out.println("失败!");}//6.释放资源//避免空指针异常if (resultSet != null){resultSet.close();}preparedStatement.close();connection.close();}

1.3 批量操作

1、插入多条数据时,一条一条发送给数据库执行,效率低下

2、通过批量操作,可以提升多次操作效率

没有批量操作的代码

/*** 没有批量操作的代码* @throws Exception*/@Testpublic void testMoreInsert() throws Exception{//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "123456");//3.编写SQL语句String sql  = "insert into t_emp (emp_name,emp_salary,emp_age) values (?,?,?)";//4.创建预编译的PreparedStatement,传入SQL语句PreparedStatement preparedStatement = connection.prepareStatement(sql);//获取当前代码执行的时间,毫秒值//开始的时间long start = System.currentTimeMillis();for (int i=0;i<10000;i++){//5.为占位符赋值preparedStatement.setString(1,"marry"+i);preparedStatement.setDouble(2,100.0+i);preparedStatement.setInt(3,20+i);preparedStatement.executeUpdate();}//获取当前代码执行结束的时间,毫秒值long end = System.currentTimeMillis();System.out.println("消耗时间:"+ (end - start));//6.释放资源preparedStatement.close();connection.close();}

有批量操作的代码

/*** 有批量操作的代码* @throws Exception*/@Testpublic void testBatch() throws Exception{//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu?rewriteBatchedStatements=true", "root", "123456");//3.编写SQL语句/*【注意】:1.必须在连接数据库的URL后面追加?rewriteBatchedStatements=true,允许批量操作2.新增SQL必须用values,且语句最后不要追加;结束3.调用addBatch() 方法,将SQL语句进行批量添加操作4.统一执行批量操作,调用executeBatch()*/String sql  = "insert into t_emp (emp_name,emp_salary,emp_age) values (?,?,?)";//4.创建预编译的PreparedStatement,传入SQL语句PreparedStatement preparedStatement = connection.prepareStatement(sql);//获取当前代码执行的时间,毫秒值//开始的时间long start = System.currentTimeMillis();for (int i=0;i<10000;i++){//5.为占位符赋值preparedStatement.setString(1,"marry"+i);preparedStatement.setDouble(2,100.0+i);preparedStatement.setInt(3,20+i);preparedStatement.addBatch();}//执行批量操作preparedStatement.executeBatch();//获取当前代码执行结束的时间,毫秒值long end = System.currentTimeMillis();System.out.println("消耗时间:"+ (end - start));//6.释放资源preparedStatement.close();connection.close();}

二、连接池

2.1 现有问题

2.2 连接池

2.3 常见连接池

 

 

2.4 Druid 连接池使用

1、使用步骤

  • 引入 jar 包
  • 编码

2、代码实现 - 硬编码方式(了解)

把连接池的配置和Java代码耦合到一起,不利于更新(更改)、维护

/*** Druid 硬编码* @throws Exception*/@Testpublic void testHardCodeDruid() throws Exception{/*硬编码:将连接池的配置信息和Java代码耦合在一起1.创建DruidDataSource连接池对象2.设置连接池的配置信息【必须 | 非必须】3.通过连接池获取连接对象4.回收连接【不是释放连接,而是将连接归还给连接池,给其他线程进行复用】*///1.创建DruidDataSource连接池对象DruidDataSource druidDataSource = new DruidDataSource();//2.设置连接池的配置信息【必须 | 非必须】//2.1 必须设置的配置druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");druidDataSource.setUrl("jdbc:mysql:///atguigu");druidDataSource.setUsername("root");druidDataSource.setPassword("123456");//2.2 非必须设置的配置druidDataSource.setInitialSize(10);druidDataSource.setMaxActive(20);//3.通过连接池获取连接对象//DruidPooledConnection extends PoolableWrapper implements PooledConnection, ConnectionDruidPooledConnection connection = druidDataSource.getConnection();//基于connection进行CRUD//4.归还连接(回收连接)connection.close();}

3、代码实现 - 软编码方式(推荐⭐)

把连接池的配置提取出来放到配置文件里,把配置文件和 Java 代码解耦,好处是利于维护和更改。

在项目目录下创建resource文件夹,标识该文件夹为资源目录,创建db.properties配置文件,将连接信息定义在该文件中。

/*** 软编码* @throws Exception*/@Testpublic void testResourcesDruid() throws Exception {//1.创建Properties集合,用于存储外部配置文件的key和value值Properties properties = new Properties();//2.读取外部配置文件,获取输入流,加载到Properties集合里//字节输入流InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("db.properties");properties.load(inputStream);//3.基于Properties集合构建DruidDataSource连接池DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//4.通过连接池获取连接对象Connection connection = dataSource.getConnection();System.out.println(connection);//5.开发CRUD//6.回收连接connection.close();}

2.5 HikariCP 连接池使用

1、硬编码

/*** Hikari 硬编码* @throws Exception*/@Testpublic void testHardCodeHikari() throws Exception{/*硬编码:将连接池的配置信息和Java代码耦合在一起1、创建HikariDataSource连接池对象2、设置连接池的配置信息【必须 | 非必须】3、通过连接池获取连接对象4、回收连接*///1.创建HikariDataSource连接池对象HikariDataSource hikariDataSource = new HikariDataSource();//2.设置连接池的配置信息【必须 | 非必须】//2.1 必须设置的配置hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");hikariDataSource.setJdbcUrl("jdbc:mysql:///atguigu");hikariDataSource.setUsername("root");hikariDataSource.setPassword("123456");//2.2 非必须设置的配置hikariDataSource.setMinimumIdle(10);hikariDataSource.setMaximumPoolSize(20);//3.通过连接池获取连接对象Connection connection = hikariDataSource.getConnection();System.out.println(connection);//4.回收连接connection.close();}

2、软编码

/*** Hikari 软编码* @throws Exception*/@Testpublic void testResourcesHikari() throws Exception{//1.创建Properties集合,用于存储外部配置文件的key和value值Properties properties = new Properties();//2.读取外部配置文件,获取输入流,加载到Properties集合里InputStream inputStream = HikariTest.class.getClassLoader().getResourceAsStream("hikari.properties");properties.load(inputStream);//3.创建HikariConfig连接池配置对象,将Properties集合传进去HikariConfig hikariConfig = new HikariConfig(properties);//4.基于HikariCofig连接池配置对象,构建HikariDataSourceHikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);//5.获取连接Connection connection = hikariDataSource.getConnection();System.out.println(connection);//6.回收连接connection.close();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847759.shtml

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

相关文章

太极图形课——渲染——光线追踪实战第一部分呢

根据概念部分我们逐步通过太极实现光线追踪 总共可以分为5步 第一步&#xff1a;如何发射出一道光&#xff1f; 首先明确何为一道光&#xff0c;光从我们眼睛&#xff08;摄像机&#xff09;射出&#xff0c;那么在三维虚拟世界里&#xff0c;我们可以认为这道光就是一条射线…

凸包算法Revit实例

ConvertHullAlgorithm &#xff08;凸包算法&#xff09; 引用 《计算几何》-导言&#xff1a;凸包的例子 前言 算法的基本逻辑与理念来自于《计算几何》这本书&#xff0c;后面其他几章的演示也都会在Revit中实现调试&#xff0c;希望能够每个算法都找一个合适的实现方向在R…

美国遛宠黑科技掀起热潮,沃尔玛跨境新品解析

美国遛宠黑科技掀起热潮&#xff0c;这一趋势不仅反映了宠物主人们对于宠物关怀的日益加深&#xff0c;也展示了科技在日常生活中的广泛应用。在这一热潮中&#xff0c;创新遛宠产品为宠物主人带来便利与体验。沃尔玛作为全球零售巨头&#xff0c;紧跟趋势&#xff0c;推出跨境…

用C#(WinForm)开发触摸屏,体验感满满

用C#&#xff08;WinForm&#xff09;开发触摸屏&#xff0c;体验感满满

加油卡APP系统开发,打造便利的汽车加油模式

随着人们生活水平的提高&#xff0c;汽车已经成为了家中必备的交通工具&#xff0c;因此&#xff0c;汽车加油也成为了大众经常要做的事。在互联网的发展下&#xff0c;汽车加油卡APP出现在了居民的生活中。加油卡系统与各个加油站合作&#xff0c;提供各种优惠折扣&#xff0c…

【Unity美术】spine软件的使用—2D动画的制作

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

透视亚马逊云科技中国峰会:生成式AI全面提速,加速行业应用落地

导读&#xff1a;亚马逊云科技在中国&#xff0c;生成式AI与行业化战略齐头并进。 “亚马逊云科技致力于成为企业构建和应用生成式AI的首选。” 近日2024亚马逊云科技中国峰会上&#xff0c;亚马逊全球副总裁、亚马逊云科技大中华区总裁储瑞松分享了亚马逊云科技中国业务最新进…

Linux下文件权限管理

任务要求 1. 在跳板机上为开发部门专门创建一个目录&#xff0c;只允许开发部门所有员工使用该目录 2. 其他人员不能进入和查看该目录里的内容 任务分解 1. 在跳板机给开发部门创建目录 2. 对该目录做好权限的管控工作 只允许开发部门的所有人使用&#xff0c;创建、删除…

无人机航迹规划:人工原生动物优化器(Artificial Protozoa Optimizer ,APO)求解无人机路径规划,提供MATLAB代码

一、无人机模型介绍 单个无人机三维路径规划问题及其建模_无人机路径规划场景建模-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、人工原生动物优化算法APO求解无人机路径规…

【Flutter】 TextField限制长度时, 第三方手写输入法、ios原始拼音输入法输入被吞问题

问题描述 TextField限制长度时&#xff0c; 当你的输入字符长度已经到了最大值-1时&#xff0c;使用第三方手写输入法或者ios原生拼音输入法输入liang&#xff08;什么拼音都行&#xff0c;这里只是举例&#xff09;&#xff0c;输到i那么li都会消失。 原因分析 这是因为第三…

缓存方法返回值

1. 业务需求 前端用户查询数据时,数据查询缓慢耗费时间; 基于缓存中间件实现缓存方法返回值:实现流程用户第一次查询时在数据库查询,并将查询的返回值存储在缓存中间件中,在缓存有效期内前端用户再次查询时,从缓存中间件缓存获取 2. 基于Redis实现 参考1 2.1 简单实现 引入…

【Java面试】十四、LinkedList相关

文章目录 1、单向链表1.1 结构1.2 查询的时间复杂度1.3 插入删除的时间复杂度 2、双向链表2.1 时间复杂度 3、ArrayList和LinkedList的区别是什么 1、单向链表 1.1 结构 存储空间上&#xff0c;非连续链表的每个元素称结点Node每个结点包括两块&#xff1a;存储数据的数据域d…

C/C++ 进阶(5)二叉平衡搜索树(AVL树)

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 目录 一、概念 二、平衡因子 三、操作 插入 旋转 左单旋 右单旋 左右双旋 右左双旋 一、概念 二叉平衡搜索树又称AVL树&#xff0c;是一种特殊的二叉搜索树。一般的二叉搜索树在遇到数据有序时&…

路由策略简介

一、路由策略 1、定义: 路由策略(RoutingPolicy)作用于路由&#xff0c;主要实现了路由过滤和路由属性设置等功能&#xff0c;它通过改变路由属性(包括可达性)来改变网络流量所经过的路经。 2、目的 设备在发布、接收和引入路由信息时&#xff0c;根据实际组网需要实施一些策…

微服务开发与实战Day01 - MyBatisPlus

一、微服务 概念&#xff1a;微服务是一种软件架构风格&#xff0c;它是以专注于单一职责的很多小型项目为基础&#xff0c;组合除复杂的大型应用。 课程安排&#xff1a; https://www.bilibili.com/video/BV1S142197x7/?spm_id_from333.1007.top_right_bar_window_history.…

Vue3-Vite-ts 前端生成拓扑图vis,复制即用

完整代码&#xff0c;复制即可用&#xff0c;样式自调 试过 jointjs dagre-d3 vis&#xff0c;好用一点&#xff0c;可添加同层的双向箭头 方法1&#xff1a;Vis.js npm install vis-network <template><div id"mynetwork" class"myChart" :st…

通过DirectML和ONNXRuntime运行Phi-3模型

更多精彩内容&#xff0c;欢迎关注我的公众号“ONE生产力”&#xff01; 上篇我们讲到通过Intel Core Ultra系列处理器内置的NPU加速运行Phi-3模型&#xff0c;有朋友评论说他没有Intel处理器是否有什么办法加速Phi-3模型。通常&#xff0c;使用GPU特别是NVIDA的GPU加速AI模型…

混剪素材库有哪些?分享7个高质量混剪视频素材网站

作为自媒体创作者&#xff0c;我们经常需要高质量的混剪视频素材来吸引观众。今天&#xff0c;我将为大家介绍几个优质的视频素材网站&#xff0c;确保您的短视频制作既高效又充满创意。 蛙学府素材网 首推蛙学府素材网&#xff0c;这个平台真是创作者的福音。无论是短视频素材…

重磅消息! Stable Diffusion 3将于6月12日开源 2B 版本的模型,文中附候补注册链接。

在OpenAI发布Sora后&#xff0c;Stability AI也发布了其最新的模型Stabled Diffusion3, 之前的文章中已经和大家介绍过&#xff0c;感兴趣的小伙伴可以点击以下链接阅读。Sora是音视频方向&#xff0c;Stabled Diffusion3是图像生成方向&#xff0c;那么两者没有必然的联系&…

electron-Vue: Module parse failed: Unexpected character ‘ ‘

​ electron-Vue项目中&#xff0c;我自己写了一个node的C扩展&#xff08;xx.node&#xff09;&#xff0c;然后在.vue文件里import它&#xff0c;然后运行npm run electron:serve&#xff0c;报错如下: ​​ electron-Vue打包默认使用webpack&#xff0c;默认情况下webpack没…