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驱动)的更多相关文章

  1. 纯Java JDBC连接数据库,且用JDBC实现增删改查的功能

    Java JDBC连接数据库 package cn.cqvie.yjq; import java.sql.*; /** * 注册数据库的驱动程序,并得到数据库的连接对象 * @author yu * ...

  2. Mybatis异常处理之MySQL Connector Java] will not be managed by Spring

    很长时间没写后台代码有点生疏了,这不今天又出点小插曲,写个文章记录下. 由于要上传点数据到后台,顺手整了个mybatis+springmvc.在保存数据时出现了异常. Creating a new S ...

  3. Java JDBC批处理插入数据操作

    在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...

  4. Java JDBC批处理插入数据操作(转)

    在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...

  5. Java JDBC的 url 配置信息和Mybatis核心配置文件(MySQL 的配置信息)

    JDBC 连接数据库的 url driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?uesSSL=true&u ...

  6. Java JDBC连接数据库 Access连接数据库

    1.加载JDBC驱动程序:  在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),再通过java.lang.Class类的静态方法forName(String  classN ...

  7. [原创] Java JDBC连接数据库,反射创建实体类对象并赋值数据库行记录(支持存储过程)

    1.SqlHelper.java import java.lang.reflect.*; import java.sql.*; import java.util.*; public class Sql ...

  8. java-Eclipse中使用JDBC连接数据库及相关操作

    准备工作:mysql-connector-java-5.1.6-bin.jar配置 package com.job; import java.sql.Connection; import java.s ...

  9. JDBC连接数据库及其执行操作

    作者:Alvin 功能:数据库连接与实现增删改查 时间:2019年3月4日08点33分 参考文章:https://www.2cto.com/database/201805/743741.html 一. ...

  10. java jdbc连接数据库,Properties 属性设置参数方法

    今天在整合为数据库发现在配置中实现的赋值方式,可以用代码实现.特记录下共以后参考: 代码:        // 操作数据库        Connection conn; String strData ...

随机推荐

  1. 使用wsl 清理windows 下的C盘

    大文件删除思路 ## 在wsl 中可以看到,C盘已经挂载了,挂载点为/mnt/c dewan@wsl ~% df /mnt/c Filesystem Size Used Avail Use% Moun ...

  2. Git: remote: The project you were looking for could not be found.

    解决方案 最简单的是在电脑的用户凭证中修改,改为正确的结果. 特殊情况 既只对改项目配置,不影响全局 命令如下: 克隆 git clone http://username:password@xxx.c ...

  3. pandas 格式化日期

    output_data["ShipDate"] = output_data["ShipDate"].dt.strftime("%Y/%m/%d&quo ...

  4. WEB前端资源网站推荐

    https://www.bootcss.com/ https://www.bootcdn.cn/ http://www.jeasyui.net/plugins/756.html

  5. 7、Mybatis之特殊SQL

    7.1 创建接口.映射文件和测试类 ++++++++++++++++++++++++++分割线++++++++++++++++++++++++++ 注意namespace属性值为对应接口的全限定类名 ...

  6. 作为用户我该如何调用API 接口获取商品数据

    作为用户,如果你想要获取商品数据,可以通过调用API接口来实现.下面是一些步骤和注意事项,帮助你成功获取商品数据. 了解开放平台:首先,你需要了解开放平台,注册一个开发者账号,并创建一个应用.在创建应 ...

  7. 关于XXLJOB集群模式下调度失败的问题

    xxljob在集群模式下调度高频任务时,有时会出现调度失败的问题,具体报错如下: java.io.EOFException: HttpConnectionOverHTTP@6be8bf0c(l:/10 ...

  8. Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法

    Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面 简介 Unity 性能优化Shader分析处理函数:Sha ...

  9. 四千行代码写的桌面操作系统GrapeOS完整代码开源了

    简介 学习操作系统原理最好的方法是自己写一个简单的操作系统. GrapeOS是一个非常简单的x86多任务桌面操作系统,源代码只有四千行,非常适合用来学习操作系统原理. 源码地址:https://git ...

  10. Ubuntu更新软件的命令

    更新软件源 apt-get update 更新升级所有软件 apt-get upgrade 更新某个软件 apt-get upgrade 名 列出可更新的软件 apt list --upgradabl ...