认识 JDBC
JDBC (Java DataBase Connectivity) 是 Java 数据库连接技术的简称, 用于连接常用数据库.
Sun 公司提供了 JDBC API , 供程序员调用接口和类, 集成在 java.sql 和 javax.sql 包中.
Sun 公司还提供了 DriverManager 类用来管理各种不同的 JDBC 驱动.
不同数据库厂商提供各自的 JDBC 驱动, 所以我们想要连接数据库除了要了解 JDBC API 还需要下载各数据库厂商的驱动 jar 包.
JDBC API
JDBC API 主要用于与数据库建立连接, 执行 SQL 语句, 处理结果, 其中核心类和接口如下:
DriverManager: 依据数据库的不同, 管理 JDBC 驱动
Connection: 负责连接数据库并担任传送数据的任务
Statement: 由 Connection 产生, 负责执行 SQL 语句
ResultSet: 负责保存 Statement 执行后所产生的查询结果
JDBC 编码模板
1, 与数据库建立连接并获取连接
Connection connection=DriverManager.getConnection(URL, 数据库用户名, 密码);
2, 发送 SQL 语句, 得到执行结果
- Statement stmt=connection.createStatement();
- ResultSet rs=stmt.executeQuery(SQL 语句);
3, 处理返回结果
- while(rs.next()){
- int a=rs.getInt("a");
- String b=rs.getString("b");
- Date d=rs.getDate("d");
- ......
- }
4, 释放资源
- rs.close();
- stmt.close();
- connection.close();
使用 JDBC 连接到 MySQL 数据库
本例适合已经会使用 MySQL 数据库的同学, 首先我们下载 JDBC 的驱动 jar 包. 这个网址提供了 MySQL 各种语言连接数据库的驱动 https://www.mysql.com/products/connector/ ,MySQL Connector / J 8.0 与从 MySQL 5.5 开始的所有 MySQL 版本兼容.
8.0 下载地址
下载完成后解压, 后将 jar 添加依赖到项目中.
连接到 MySQL 数据库
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- public class DemoConnectMySQL {
- public static void main(String[] args) {
- // 连接 MySQL 的 URL
- String url="jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
- //MySQL 数据库用户名
- String user="root";
- //MySQL 数据库的密码
- String password="1234";
- Connection connection=null;
- try {
- connection=DriverManager.getConnection(url, user, password);
- System.out.println("连接成功");
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- try {
- connection.close();
- System.out.println("连接关闭");
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
url 指定数据库的连接字符串, 格式为:
jdbc: 数据库://ip 或域名: 端口号? 参数 & 参数......
这里的参数 useUnicode=true 使用 Unicode 字符, characterEncoding=utf8 设置编码防止中文乱码, serverTimezone=UTC 设置时区, useSSL=false 不使用 SSL
jdbc4.0 不需要加载驱动
PreparedStatement 增删改
PreparedStatement 继承了 Statement 接口, 表示预编译的 SQL 语句对象, SQL 语句被预编译并存储在 PreparedStatement 对象中, 可以使用此对象多次高效地执行该语句.(还避免了 SQL 注入的隐患)
先准备好数据库 books
表 book
字段 | 类型 | 属性 |
---|---|---|
id | 整数 | 主键, 自增 |
bName | 字符串 | 非空 |
price | 小数 | 非空 |
脚本也准备好了
- # 创建数据库
- CREATE DATABASE books;
- USE books;
- # 创建表
- CREATE TABLE book (
- id INT primary key auto_increment,
- bName VARCHAR ( 255 ) NOT NULL,
- price FLOAT NOT NULL
- );
PreparedStatement 添加数据
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- public class TestInsert {
- public static void main(String[] args) {
- Connection connection=null;
- PreparedStatement pstmt=null;
- String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
- String user="root";
- String password="1234";
- try {
- connection=DriverManager.getConnection(url,user,password);
- //sql 语句
- String sql="insert into book(bName,price) values (?,?)";
- pstmt=connection.prepareStatement(sql);
- // 传入参数
- pstmt.setString(1, "《java 入门到改行》");
- pstmt.setFloat(2, 11.11f);
- int result=pstmt.executeUpdate();
- System.out.println("受影响行数:"+result);
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- if (pstmt!=null) {
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection!=null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
说明:
1, 连接字符串要修改数据库名字为 books
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
2, 插入数据库的数据不能拼接而是要用 ? 代替
String sql="insert into book(bName,price) values (?,?)";
3,? 代替的参数要通过 set 类型 (位置, 值) 传入
- pstmt.setString(1, "《java 入门到改行》");
- pstmt.setFloat(2, 11.11f);
pstmt.setXxx() 的位置从 1 开始!
4, 增删改的 SQL 语句都使用这个方法, 返回受影响行数
int result=pstmt.executeUpdate();
删除数据
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- public class TestDelete {
- public static void main(String[] args) {
- Connection connection=null;
- PreparedStatement pstmt=null;
- String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
- String user="root";
- String password="1234";
- try {
- connection=DriverManager.getConnection(url,user,password);
- //sql 语句
- String sql="delete from book where id=?";
- pstmt=connection.prepareStatement(sql);
- // 传入参数 要删除 id
- pstmt.setInt(1, 1);
- int result=pstmt.executeUpdate();
- System.out.println("受影响行数:"+result);
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- if (pstmt!=null) {
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection!=null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
修改数据
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- public class TestUpdate {
- public static void main(String[] args) {
- Connection connection=null;
- PreparedStatement pstmt=null;
- String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
- String user="root";
- String password="1234";
- try {
- connection=DriverManager.getConnection(url,user,password);
- //sql 语句
- String sql="update book set bName=?,price=? where id=?";
- pstmt=connection.prepareStatement(sql);
- // 传入参数 要删除 id
- pstmt.setString(1, "《MySQL 从删库到跑路》");
- pstmt.setFloat(2, 16.66f);
- pstmt.setInt(3, 2);
- int result=pstmt.executeUpdate();
- System.out.println("受影响行数:"+result);
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- if (pstmt!=null) {
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection!=null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
增, 删, 改操作的写法都一样, 都调用 executeUpdate() 方法返回一个受影响行数, 唯一不同的 SQL 语句.
PreparedStatement 查询数据
查询数据需要用到 ResultSet 类保存返回的结果集, 我们获取数据要操作 ResultSet 获取.
ResultSet 常用方法
方法名 | 说明 |
---|---|
boolean next() | 将游标从当前位置向下移动一行 |
void close() | 关闭 ResultSet 对象 |
int getInt(int colIndex) | 以 int 形式获取结果集当前行指定列号值 |
int getInt(String colLabel) | 以 int 形式获取结果集当前行指定列名值 |
float getFloat(String colLabel) | 以 float 形式获取结果集当前行指定列名值 |
String getString(String colLabel) | 以 String 形式获取结果集当前行指定列名值 |
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- public class TestSelect {
- public static void main(String[] args) {
- Connection connection=null;
- PreparedStatement pstmt=null;
- ResultSet rs=null;
- String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
- String user="root";
- String password="1234";
- try {
- connection=DriverManager.getConnection(url,user,password);
- //sql 语句
- String sql="select bName,price,id from book where id=?";
- pstmt=connection.prepareStatement(sql);
- // 传入查询条件
- pstmt.setInt(1, 2);
- rs=pstmt.executeQuery();
- while(rs.next()) {
- // 通过列名获取列的值
- int id=rs.getInt("id");
- // 通过位置获取列的值
- String bName=rs.getString(1);
- float price=rs.getFloat("price");
- System.out.println(id+""+bName+" "+price);
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- if(rs!=null) {
- try {
- rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (pstmt!=null) {
- try {
- pstmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (connection!=null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
关闭对象时注意关闭的顺序, 后使用的先关闭: rs.close()->pstmt.close()->connection.close()
ResultSet 对象存在一个光标, 光标所指行为当前行. 想要获取列的数据需要先指向一行, 所以要先指定 next() 方法用于指向一行, 如果没有数据 next() 方法返回 false, 有数据返回 true.
使用 getXxx() 方法获取列的数据时建议写列名, 这样好识别
来源: https://www.cnblogs.com/AIThink/p/9940542.html