Java JDBC连接数据库的CURD操作(JDK1.8 + MySQL8.0.33 + mysql-connector-java-8.0.27-bin驱动)
JDBC概述
JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
连接数据库
java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。
在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。
我使用的是 mysql-connector-java-8.0.27-bin 驱动
1、加载驱动
不用显式调用 DriverManager 类的 registerDriver() 方法来注册驱动程序类的实例,是因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例。所以建议使用以下代码加载驱动。
Class.forName(“com.mysql.cj.jdbc.Driver”);
注意:驱动版本8+以上的才需要在jdbc前面.cj,否则直接写“com.mysql.jdbc.Driver”
2、获取连接
使用DriverManager.getConnection(url,user,password);获取连接
MySQL的连接URL编写方式:
jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值
jdbc:mysql://localhost:3306/数据库名
jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8(如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集)
jdbc:mysql://localhost:3306/数据库名?user=root&password=123456
连接数据库的时候也可以使用配置文件的方式保存配置信息,在代码中加载配置文件,这里就不再赘述。
使用PreparedStatement实现CRUD操作
为什么要用PreparedStatement而不是Statements是因为使用Statement操作数据表存在弊端:
问题一:存在拼串操作,繁琐
问题二:存在SQL注入问题
SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令(如:SELECT user, password FROM user_table WHERE user='a' OR 1 = ' AND password = ' OR '1' = '1') ,从而利用系统的 SQL 引擎完成恶意行为的做法。
对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可以了。
PreparedStatement的使用
可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象
PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值
具体步骤如下:
1 Class.forName("com.mysql.cj.jdbc.Driver");
2
3 Connection connection = DriverManager.getConnection(URL, name, password);
4
5 String sql = "SELECT * FROM t_user;";
6
7 PreparedStatement preparedStatement = connection.prepareStatement(sql);
8
9 ResultSet resultSet = preparedStatement.executeQuery();
10
11 while (resultSet.next()){
12 int id = resultSet.getInt("id");
13 String account = resultSet.getString("account");
14 String pw = resultSet.getString("PASSWORD");
15 String nickname = resultSet.getString("nickname");
16
17 System.out.println(id+"\t"+account+"\t"+pw+"\t"+nickname);
18 }
19
20 resultSet.close();
21
22 preparedStatement.close();
23
24 connection.close();
如果要传入参数,首先在sql语句中用?去占位,再调用setObject方法传递参数,如下所示:
1 Class.forName("com.mysql.cj.jdbc.Driver");
2
3 Connection connection = DriverManager.getConnection(url, name, password);
4
5 String sql = "SELECT * FROM t_user WHERE account=? AND password=?;";
6
7 PreparedStatement preparedStatement = connection.prepareStatement(sql);
8
9 String account = "root";
10 String pw = "123456";
11
12 preparedStatement.setObject(1,account);
13
14 preparedStatement.setObject(2,pw);
15
16 ResultSet resultSet = preparedStatement.executeQuery();
17
18 boolean next = resultSet.next();
19 System.out.println(next);
20
21 resultSet.close();
22
23 preparedStatement.close();
24
25 connection.close();
ResultSet
查询需要调用PreparedStatement 的 executeQuery() 方法,查询结果是一个ResultSet 对象
ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商提供实现
ResultSet 返回的实际上就是一张数据表。有一个指针指向数据表的第一条记录的前面。
ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行。调用 next()方法检测下一行是否有效。若有效,该方法返回 true,且指针下移。相当于Iterator对象的 hasNext() 和 next() 方法的结合体。
当指针指向一行时, 可以通过调用 getXxx(int index) 或 getXxx(int columnName) 获取每一列的值。
例如: getInt(1), getString("name")
注意:Java与数据库交互涉及到的相关Java API中的索引都从1开始。
资源的释放
释放ResultSet, Statement,Connection。
数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
可以在finally中关闭,保证及时其他代码出现异常,资源也一定能被关闭。
ResultSetMetaData
可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
ResultSetMetaData meta = rs.getMetaData();
getColumnName(int column):获取指定列的名称
getColumnLabel(int column):获取指定列的别名
getColumnCount():返回当前 ResultSet 对象中的列数。
getColumnTypeName(int column):检索指定列的数据库特定的类型名称。
getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。
isNullable(int column):指示指定列中的值是否可以为 null。
isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
使用ResultSetMetaData 将ResultSe中的数据存入List<Map>中的集合里:
1 Class.forName("com.mysql.cj.jdbc.Driver");
2
3 Connection connection = DriverManager.getConnection(url, name, password);
4
5
6 String sql = "SELECT id as ID,account as 账号,password as 密码,nickname as 昵称 FROM t_user;";
7
8 PreparedStatement preparedStatement = connection.prepareStatement(sql);
9
10 ResultSet resultSet = preparedStatement.executeQuery();
11
12 ResultSetMetaData metaData = resultSet.getMetaData();
13
14 List<Map> res = new ArrayList<>();
15
16 while (resultSet.next()){
17 Map map = new HashMap();
18
19 int columnCount = metaData.getColumnCount();
20
21 for (int i = 1; i <= columnCount; i++) {
22 String columnName = metaData.getColumnLabel(i);
23 map.put(columnName,resultSet.getObject(i));
24 }
25
26 res.add(map);
27 }
28
29 for (Map re : res) {
30 System.out.println(re);
31 }
32
33 resultSet.close();
34
35 preparedStatement.close();
36
37 connection.close();
主键回显
利用getGeneratedKeys方法获取一个结果集,首先在connection.prepareStatement方法中再传入一个参数:Statement.RETURN_GENERATED_KEYS 也可以用1代替(不推荐)
1 Class.forName("com.mysql.cj.jdbc.Driver");
2
3 Connection connection = DriverManager.getConnection(url, name, password);
4
5 String sql = "INSERT INTO t_user(account,password,nickname) VALUES(?,?,?);";
6
7 PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
8
9 preparedStatement.setObject(1,"test01");
10 preparedStatement.setObject(2,"123456");
11 preparedStatement.setObject(3,"JDBC");
12
13 int i = preparedStatement.executeUpdate();
14
15 if (i!=0){
16 System.out.println("Success");
17 ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
18 generatedKeys.next();
19 int anInt = generatedKeys.getInt(1);
20 System.out.println("主键="+anInt);
21 }else {
22 System.out.println("False");
23 }
24
25 preparedStatement.close();
26
27 connection.close();
批量执行SQL语句
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
addBatch(String):添加需要批量处理的SQL语句或是参数;
executeBatch():执行批量处理语句;
clearBatch():清空缓存的数据
通常我们会遇到两种批量执行SQL语句的情况:
多条SQL语句的批量处理;
一个SQL语句的批量传参;
注意:mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
String url = "jdbc:mysql://localhost:3306/databasename?rewriteBatchedStatements=true";写在配置文件的url后面
用preparedStatement.addBatch();将数据添加到sql语句后面
注意:写sql语句的时候后面不能写分号!
最后添加完了用
preparedStatement.executeBatch();执行sql语句,示例如下:
1 String url = "jdbc:mysql://localhost:3306/databasename?rewriteBatchedStatements=true";
2
3 Class.forName("com.mysql.cj.jdbc.Driver");
4
5 Connection connection = DriverManager.getConnection(url, name, password);
6
7 String sql = "INSERT INTO t_user(account,password,nickname) VALUES(?,?,?)";
8
9 PreparedStatement preparedStatement = connection.prepareStatement(sql);
10
11 for (int i = 0; i < 10000; i++) {
12 preparedStatement.setObject(1,"test"+i);
13 preparedStatement.setObject(2,"password"+i);
14 preparedStatement.setObject(3,"tt"+i);
15
16 preparedStatement.addBatch();
17 }
18
19 preparedStatement.executeBatch();
20
21 preparedStatement.close();
22
23 connection.close();
Java JDBC连接数据库的CURD操作(JDK1.8 + MySQL8.0.33 + mysql-connector-java-8.0.27-bin驱动)的更多相关文章
- 纯Java JDBC连接数据库,且用JDBC实现增删改查的功能
Java JDBC连接数据库 package cn.cqvie.yjq; import java.sql.*; /** * 注册数据库的驱动程序,并得到数据库的连接对象 * @author yu * ...
- Mybatis异常处理之MySQL Connector Java] will not be managed by Spring
很长时间没写后台代码有点生疏了,这不今天又出点小插曲,写个文章记录下. 由于要上传点数据到后台,顺手整了个mybatis+springmvc.在保存数据时出现了异常. Creating a new S ...
- Java JDBC批处理插入数据操作
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- Java JDBC批处理插入数据操作(转)
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- Java JDBC的 url 配置信息和Mybatis核心配置文件(MySQL 的配置信息)
JDBC 连接数据库的 url driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?uesSSL=true&u ...
- Java JDBC连接数据库 Access连接数据库
1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),再通过java.lang.Class类的静态方法forName(String classN ...
- [原创] Java JDBC连接数据库,反射创建实体类对象并赋值数据库行记录(支持存储过程)
1.SqlHelper.java import java.lang.reflect.*; import java.sql.*; import java.util.*; public class Sql ...
- java-Eclipse中使用JDBC连接数据库及相关操作
准备工作:mysql-connector-java-5.1.6-bin.jar配置 package com.job; import java.sql.Connection; import java.s ...
- JDBC连接数据库及其执行操作
作者:Alvin 功能:数据库连接与实现增删改查 时间:2019年3月4日08点33分 参考文章:https://www.2cto.com/database/201805/743741.html 一. ...
- java jdbc连接数据库,Properties 属性设置参数方法
今天在整合为数据库发现在配置中实现的赋值方式,可以用代码实现.特记录下共以后参考: 代码: // 操作数据库 Connection conn; String strData ...
随机推荐
- Linux下定时清空某个文件
问题 在一台单点机器部署完成且运行一段时间后,发现页面接口报错,登上机器发现磁盘满了.通过du -lh --max-depth=1 和 du -sh * 找出是哪个文件. 发现是 项目中 stdout ...
- 一条命令突破Windows限制,暂定更新时间至3000天
在系统界面上最长也就只能延期 35 天,而且 35 天以后一定要更新了才能继续暂停.不过,我找到了一段能延长暂停时间的代码 reg add "HKEY_LOCAL_MACHINE\SOFTW ...
- 论文解读(APCA)《Adaptive prototype and consistency alignment for semi-supervised domain adaptation》
[ Wechat:Y466551 | 付费咨询,非诚勿扰 ] 论文信息 论文标题:Adaptive prototype and consistency alignment for semi-super ...
- Blazor前后端框架Known-V1.2.12
V1.2.12 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Git ...
- vue3+vite2动态绑定图片优雅解决方案
优雅解决方案在最下面,小伙伴们儿可以直接前往 背景 在vue3+vite2项目中,我们有时候想要动态绑定资源,比如像下面的代码这样: <template> <div> < ...
- 形象谈JVM-第四章-JVM内存结构
给我一个CPU,给我一块内存,我来执行一段代码. 我要如何分配呢? new User(); 这里有一个有一个User类,如果我要new出来User对象,必须先知道它长什么样子,我先搞一块区域出来,把U ...
- Airtest遇到模拟器无法输入中文的情况该如何处理?
此文章来源于项目官方公众号:"AirtestProject" 版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 1. 前言 最近有收到同学们的一些提问,使用Air ...
- Visual Studio Code(vscode)下载慢 插件安装失败解决方案
目录 一.系统环境 二.前言 三.Visual Studio Code(vscode)简介 四.解决Visual Studio Code(vscode)下载慢的问题 4.1 问题描述 4.2 解决方案 ...
- 如何实现IP话机接入交换机?
组网图形 简介 如果语音设备支持LLDP协议,并且支持通过network-policy TLV字段获取语音VLAN,可以在交换机上配置命令lldp tlv-enable med-tlv network ...
- API数据接口的应用步骤
API(Application Programming Interface)是现代软件应用程序开发中的一项重要技术,它允许不同的应用程序之间进行通信和数据交换.API接口通过提供统一的访问点,使得应用 ...