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 ...
随机推荐
- 使用wsl 清理windows 下的C盘
大文件删除思路 ## 在wsl 中可以看到,C盘已经挂载了,挂载点为/mnt/c dewan@wsl ~% df /mnt/c Filesystem Size Used Avail Use% Moun ...
- Git: remote: The project you were looking for could not be found.
解决方案 最简单的是在电脑的用户凭证中修改,改为正确的结果. 特殊情况 既只对改项目配置,不影响全局 命令如下: 克隆 git clone http://username:password@xxx.c ...
- pandas 格式化日期
output_data["ShipDate"] = output_data["ShipDate"].dt.strftime("%Y/%m/%d&quo ...
- WEB前端资源网站推荐
https://www.bootcss.com/ https://www.bootcdn.cn/ http://www.jeasyui.net/plugins/756.html
- 7、Mybatis之特殊SQL
7.1 创建接口.映射文件和测试类 ++++++++++++++++++++++++++分割线++++++++++++++++++++++++++ 注意namespace属性值为对应接口的全限定类名 ...
- 作为用户我该如何调用API 接口获取商品数据
作为用户,如果你想要获取商品数据,可以通过调用API接口来实现.下面是一些步骤和注意事项,帮助你成功获取商品数据. 了解开放平台:首先,你需要了解开放平台,注册一个开发者账号,并创建一个应用.在创建应 ...
- 关于XXLJOB集群模式下调度失败的问题
xxljob在集群模式下调度高频任务时,有时会出现调度失败的问题,具体报错如下: java.io.EOFException: HttpConnectionOverHTTP@6be8bf0c(l:/10 ...
- Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法
Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面 简介 Unity 性能优化Shader分析处理函数:Sha ...
- 四千行代码写的桌面操作系统GrapeOS完整代码开源了
简介 学习操作系统原理最好的方法是自己写一个简单的操作系统. GrapeOS是一个非常简单的x86多任务桌面操作系统,源代码只有四千行,非常适合用来学习操作系统原理. 源码地址:https://git ...
- Ubuntu更新软件的命令
更新软件源 apt-get update 更新升级所有软件 apt-get upgrade 更新某个软件 apt-get upgrade 名 列出可更新的软件 apt list --upgradabl ...