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 ...
随机推荐
- EaselJS 源码分析系列--第四篇
鼠标交互事件 前几篇关注的是如何渲染,那么鼠标交互如何实现呢? Canvas context 本身没有像浏览器 DOM 一样的交互事件 EaselJS 如何在 canvas 内实现自己的鼠标事件系统? ...
- Node: 将时间戳转换成日期并分组
// 对时间戳按日期进行分组 let moment = require('moment') let timestamp_array = [ 1645059333000, 1613523333000, ...
- 2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1。 返回奇数层节点分配
2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1. 返回奇数层节点分配 ...
- 看,这些 plugins 常用又简单
前面文章中 体验了webpack的打包 .解析css资源 .处理图片字体等文件 接下来看看 plugins 有什么作用吧~ 项目路径如下,和上一篇 处理图片字体等文件 项目保持一致 demo ├─ s ...
- HDU 3829 Cat VS Dog 猫和狗(二分图)结题报告
听学长说这道题很ex,但是思路想到的话还是挺简单的. 可能是受上一道题(放置机器人)的启发,也是找互相冲突的点连线. 但是并不是完全一样(废话)放置机器人那道题是找到冲突点连线后直接求最大匹配即可. ...
- numpy和pandas的基本用法
安装numpy模块 pip install numpy 可以通过导入numpy模块来使用它 import numpy as np 1.创建数组: a = np.array([1, 2, 3, 4, 5 ...
- brpc internal
brpc 内部实现 thread model pthread 1:1atomic cache同步降低性能 fiber n:1 -> nginx 多核难以扩展, 用户不能做阻塞操作. contex ...
- 精选版:用Java扩展Nginx(nginx-clojure 入门)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 今天咱们以Java程序员的视角,来聊聊如何用 ...
- Antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败
antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败,导致输入框输入不了任何内容! 可能你的react及react-dom版本由于过高导致antd组件不能兼容,需要对reac ...
- 文心一言 VS 讯飞星火 VS chatgpt (89)-- 算法导论8.3 2题
二.用go语言,下面的排序算法中哪些是稳定的:插入排序.归并排序.堆排序和快速排序?给出一个能使任何排序算法都稳定的方法.你所给出的方法带来的额外时间和空间开销是多少? 文心一言: 在Go语言中,以下 ...