JDBC
# JDBC
JDBC是一种SQL语句的Java API ,Java语言编写的 类和接口
- 连接数据库
- 创建 SQL语句
- 在数据库中SQL查询
- 查看和生成记录
# 体系构架
# 体系结构
**JDBC API:** 提供应用程序JDBC管理器连接 **JDBC Driver Manager:** 管理器驱动程序连接# 组件
DriverManager: 此类 管理数据库驱动程序列表 Driver: 此接口 处理与数据库服务器的通信,连接具体驱动 Connection: 该界面具有用于联系数据库的所有方法 Statement: 此接口 创建的对象将SQL语句提交到数据库 ResultSet: 在使用Statement对象执行SQL查询后,这些对象保存从数据库检索的数据。它作为一 个迭代器,允许我们移动其数据。 SQLException: 此类数据库发生的错误
# 首次应用
构建JDBC应用:
- 导入包
import java.sql.*
- **注册JDBC驱动程序 ** 通过Java程序 初始化驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
, 驱动类文件加载至内存中,并自动注册 - 连接对象 通过
DriverManager.getConnection(String url, String userName, String passWord )方法
获取Connection对象
(数据库的物理连接) - 执行查询 通过
Statement对象
构建 和 提交SQL语句到数据库 - 结果集提取数据 通过
ResultSet.getXXX(String 字段名 )方法
获取结果集检索数据(XXX代表对应的数据类型) - 释放资源 关闭所有数据库资源,避免依赖JVM垃圾收集器
**注册JDBC驱动程序 方法 **
Class.forName(String str) 根据路径进行加载驱动 DriverManager.registerDriver(Driver mydriver) 静态方法 对象加载
# API
实现数据库连接交互信息
# Connection
连接数据库 DriverManager.getConnection()方法
建立连接,重载方法有
DriverManager.getConnection(String url) DriverManager.getConnection(String url,Properties prop) DriverManager.getConnection(String url,String user,String password) DriverManager.getConnection(String url, Properties info)
数据库URL配置
RDBMS | JDBC驱动程序名称 | 网址格式 |
---|---|---|
MYSQL8 | com.mysql.cj.jdbc.Driver | jdbc:mysql://HostName:3306/databaseName?serverTimezone=UTC |
MySQL | com.mysql.jdbc.Driver | jdbc:mysql://HostName:3306/databaseName |
ORACLE | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:@HostName:Port Number:databaseName |
DB2 | COM.ibm.db2.jdbc.net.DB2Driver | jdbc:db2:HostName:Port / databaseName |
SYBASE | com.sybase.jdbc.SybDriver | jdbc:sybase:Tds:HostName:Port Number / databaseName |
HostName: IP地址 Post: 端口 databaseName: 库名
注意:mysql8以后的url必须添加时区 ==serverTimezone=UTC==
# ResultSet
数据库中的查询结果集
ResultSet对象
维护指向结果集中当前行的光标。 如果没有在 createStatement()方法
中指定参数 ,则自动获取TYPE_FORWARD_ONLY
参数 | 说明 |
---|---|
ResultSet.TYPE_SCROLL_INSENSITIVE | 光标可前后滚动,对数据更改不敏感 |
ResultSet.TYPE_SCROLL_SENSITIVE | 光标可前后滚动,对底层数据更改敏感 |
ResultSet.TYPE_FORWARD_ONLY | 光标只能在结果集中向前移动 |
# ResultSetMetaData
一般用于获取 ResultSet对象
中字段的类型和属性的信息的对象
ResultSetMetaData方法
返回 | 方法 | 说明 |
---|---|---|
String | getColumnName(int column) | 获取 指定字段名称(从1开始) |
String | getColumnLabel(int column) | 获取 指定字段的别名(从1开始) |
int | getColumnCount() | 获取 当前ResultSet对象中的字段数 |
String | getColumnTypeName(int column) | 检索 指定字段的库,特定的类型名称 |
··· | ··· | ··· |
# Statement
在使用 Statement对象
执行SQL语句之前,连接后得到 Connection对象
的 createStatement()方法
创建Statement对象
//以下代码需要 异常 捕获或抛出
//获取数据库的实体连接
Connection connection = ······ ;
Statement stmt = connection.createStatement();
Statement方法
返回 | 方法 | 说明 |
---|---|---|
boolean | execute(String SQL) | 是否存在 ResultSet对象 |
int | executeUpdate(String SQL) | 在数据库中执行SQL语句,并且获取 SQL语句影响的行数 |
ResultSet | executeQuery(String SQL) | 获取 查询的结果集,迭代遍历可获取数据 |
void | close() | 关闭对象 |
恶意SQL注入
通过SQL命令插入Web表单提交或输入域名或页面请求的查询字符串,最终以伪信息进行SQL执行命令,示例:
String username = "aa";
//跳过判断 ; 通过 或 进行 1=1
String password = " '' OR 1=1 ";
String sql = "SELECT * FROM users WHERE username = '"+username+"' AND password = "+password;
# PrepareStatement
PrepareStatement接口
预状态通道,也是 Statement接口
的子接口,它能简化代码、预防注入恶意sql注入、提高效率的优点
SQL语句可动态的提供参数相应的数据
//抛出|捕获 异常
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pps = Connection.prepareStatement(sql);
pps.setString(1 , "张三");
pps.setInt(2 , "123123");
//执行sql
int resultSet = pps.executeQuery();
···
pps.close();
在当中所有参数都由 ?
标记,执行SQL前,必须提供为每个参数提供值!!
PreparedStatement方法
返回 | 方法 | 说明 |
---|---|---|
boolean | execute() | 是否存在 ResultSet对象 |
int | executeUpdate() | 在数据库中执行SQL语句,并且获取 SQL语句影响的行数 |
ResultSet | executeQuery() | 获取 查询的结果集,迭代遍历可获取数据 |
XXX | setXXX(int mark,XXX value) | XXX代表绑定对应的数据类型 mark: 下标锁定(下标是从1开始) value: 指定下标赋予值 |
··· | ||
void | close() | 关闭对象 |
点击代码示例* (PreparedStatement预状态通道)
statement和PreparedStatement区别
- statement属于状态通道,PreparedStatement属于预状态通道
- 预状态通道会先编译sql语句,再去执行,比statement执行效率高
- 预状态通道支持占位符
?
,给占位符赋值的时候,位置从1开始 - 预状态通道可以防止sql注入,因 预状态通道在处理值的时候以字符串形式处理
- PreparedStatement通道传递的参数只能是变量,并非变量
# 多表关系
数据库的分类有:一对一、一对多、多对多
实体类通过属性的方式建立两表关系 类名=表名 、 列名=属性名
实现方式原理:通过查询提取出的数据,对相应类属性进行赋值
有学生类(Student),有ID、姓名属性,生成它们的get、set方法 数据库数据 (XX库 Student表)
sid | sname |
---|---|
1 | 柏竹 |
2 | 黑猫 |
以下代码实例
····
//执行SQL
String sql = "SELECT * FROM student";
PreparedStatement pps = connection.prepareStatement(sql);
resultSet = pps.executeQuery();
Student student = new Student();
while (resultSet.next()){
student.setSid(resultSet.getInt("sid"));
student.setsName(resultSet.getString("sname"));
}
点击多表项目测试代码 (opens new window) (可以自行下载查看详细操作 · 免费)
# 事务应用
JDBC连接默认是 自动提交模式
,JDBC也支持手动事务,每条SQL语句完成后自动提交到数据库
事务能使控制库数据何时进行数据更改,如果一组SQL语句视为一个逻辑单元去执行,要么全部成功,要么全部失败!
通过 Connection对象
进行事务提交回滚操作!
返回 | 方法 | 说明 |
---|---|---|
void | setAutoCommit(boolean autoCommit) | 是否关闭自动提交事务(自动打开事务) |
boolean | getAutoCommit() | 是否为自动提交事务模式 |
void | commit() | 提交事务 |
void | rollback() | 回滚事务 |
void | close() | 释放资源 |
//connection 已连接
connection.setAutoCommit(false);
//SQL操作
·····
//手动提交
connection.commit();
# Savepoints(事务存档)
事务执行过程,可设置保存点,设置保存点库数据会更变。保存存档后的点(库更改后数据是永久性的),当中出现异常,回滚事务时会返回至存档点,并非开头启动事务点!
通过 Connection对象
进行存档点的操作!
返回 | 方法 | 说明 |
---|---|---|
Savepoint | setSavepoint(String name) | 定义存档点,需设存档点名 |
void | releaseSavepoint(Savepoint savepoint) | 删除指定存档点 |
void | rollback(Savepoint savepoint) | 指定回滚目的 |
Savepoint archiveNo1 = null;
try {
···
//connection 已连接
connection.setAutoCommit(false);
Statement statement = connection.createStatement();
//SQL操作
·····
//以上是SQL完成操作
archiveNo1 = connection.setSavepoint("ArchiveNo1");
·····
//手动提交
connection.commit();
} catch (Exception throwables) {
//异常回滚
try {
connection.rollback(archiveNo1);
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
# 批量处理
JDBC允许 批量处理SQL语句 ,通过事务一次调用提交库 一次发送多条SQL语句,可减少数据库的交互次数,提高质量
通过 PreparedStatement
对象 、 Statement
对象 实现批处理方法
返回 | 方法 | 说明 |
---|---|---|
void | addBatch() | PreparedStatement对象添加SQL语句 |
void | addBatch(String sql) | Statement对象 添加SQL语句 |
int[] | executeBatch() | 获取批量执行的影响数(顺序=添加SQL顺序),并执行 批量SQL语句 |
实现步骤
- 连接数据库
Connection对象
- 设置手动事务
Connection对象
的setAutoCommit(false)
方法 - 获取通道对象
PreparedStatement
对象 或Statement
对象 - 不同通道对象,添加方式不同!
Statement
对象 通过addBatch(sql)
方法 实现添加SQL语句PreparedStatement
对象 通过addBatch()
方法 实现添加 SQL语句 - 通过 通道对象 的
executeBatch()
方法 批量执行SQL语句 - 提交事务
Connection
对象 的commit()
方法 进行提交
注意: 批量处理过程中出现异常,可通过异常捕获进行回滚操作
# 反射处理集
利用反射处理查询到的结果集,对应的数据赋予对象! 注意:以下代码要求库中的字段名与类中的属性名相同,且类所有属性都有get、set方法!(类至少有一个相同)
//库连接
···
List studentall = new ArrayList();
//student表 = studnet类 ,且 表studnet的字段 = 类studnet的属性!!
String sql = "SELECT * FROM student";
pps = connection.prepareStatement(sql);
rs = pps.executeQuery();
//提取 结果集 字段的类型和属性的信息
ResultSetMetaData metaData = rs.getMetaData();
//赋予字段数
int count = metaData.getColumnCount();
String[] columnNames = new String[count];
//字段数组
for (int i = 0 ; i < count ; i++) {
columnNames[i] = metaData.getColumnName(i+1);
}
//通过反射 student类中的所有方法
Method[] declaredMethods = student.getDeclaredMethods();
while (rs.next()){
//无参的构造方法
Object s = cla.newInstance();
//遍历数组字段
for (String columnName : columnNames) {
//用于比较 set方法名
String newColumnName = "set"+columnName;
//遍历类方法
for (Method declaredMethod : declaredMethods) {
//比较方法名(无视大小写)
if (declaredMethod.getName().equalsIgnoreCase(newColumnName)){
//通过反射实现方法
declaredMethod.invoke(s , rs.getObject(columnName));
break;
}
}
//每条数据都添加
list.add(s);
}
}
# 连接池
# DBCP连接池
实现步骤:
- 导入jdk依赖包 mysql-jdbc.jar commons-dbcp.jar commons-pool.jar
- 实例
BasicDataSource对象
- 功能属性实现
BasicDataSource对象
的 set方法 - 获取连接 通过
BasicDataSource对象
的getConnection()方法
配置实例
public void testHard() throws SQLException{
// 硬编码 使用DBCP连接池
BasicDataSource source = new BasicDataSource();
//设置连接的信息
source.setDriverClassName("com.mysql.jdbc.Driver");
//设置 url 、 用户 、 密码 ···
source.setUrl("jdbc:mysql://localhost:3306/day2");
source.setUsername("root");
source.setPassword("111");
//获取连接
Connection connection = source.getConnection();
}
# C3P0连接池
C3P0与DBCP区别
- C3P0有自动回收空闲连接功能,DBCP没有
- C3P0无需手动,DBCP需手动配置文件
- C3P0配置文件命名固定(c3p0-config.xml)
实现步骤:
导入jdk依赖包
mysql-jdbc.jar
c3p0-0.9.1.2.jar (版本号)
创建
c3p0-config.xml
配置文件,路径:src文件夹下手动 配置文件 调用无参的默认配置
<default-config>
调用有参的配置<named-config name="Myc3p0Test">
自定命名实例
ComboPooledDataSource对象
无参调用默认的,有参调用自定义的获取连接 通过
ComboPooledDataSource对象
的getConnection()方法
手动配置 c3p0-config.xml
配置文件。实例:
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<!-- 基本配置 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai</property>
<property name="user">root</property>
<property name="password"></property>
<!--扩展配置-->
<!-- 连接超过1min报错-->
<property name="checkoutTimeout">60000</property>
<!--30秒检查空闲连接 -->
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<!-- 30秒不适用丢弃-->
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="Myc3p0Test">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai</property>
<property name="user">root</property>
<property name="password"></property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
# Druid连接池
Druid是目前大厂流行的连接池,有以下特点:
- 秒查询 快速的聚合能力以及亚秒级的OLAP查询能力
- 实时数据注入 保证在实时和离线环境下 事件的 实效性 和 统一性
- 可扩展PB级存储 扩容到PB的数据量,每秒百万级别的数据注入
- 多环境部署 可从多种数据系统中注入数据
- 丰富社区 学习交流
实现步骤: (实现方式跟DBCP差不多)
- 导入jdk依赖包 mysql-jdbc.jar druid-1.0.9.jar (版本号)
- 实例
DruidDataSource对象
- 功能属性实现
DruidDataSource对象
的 set方法 - 获取连接 通过
DruidDataSource对象
的getConnection()方法
# HikariCP 连接池
目前最优选连接池 , 也是SpringBoot默认使用的连接池
依赖
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
提示
如果采用的是SpringBoot项目 , 可无需引入以上依赖
示例
点击展开
public static void main(String[] args) throws Exception {
HikariConfig config = new HikariConfig();
// 基础配置
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
config.setJdbcUrl("jdbc:mysql://localhost:3306/ruoyi-vue");
config.setUsername("root");
config.setPassword("root");
// 线程池配置
config.setMinimumIdle(4);
config.setMaximumPoolSize(8);
config.setIdleTimeout(60 * 10);
HikariDataSource dataSource = new HikariDataSource(config);
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("select * from sys_user");
while (res.next()) {
System.out.println(
"id:" + res.getLong("user_id") +
",name:" + res.getString("user_name")
);
}
res.close();
}
SpringBoot配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
dynamic:
hikari:
# 最大连接池数量
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 连接测试query(配置检测连接是否有效)
connectionTestQuery: SELECT 1
# 多久检查一次连接的活性
keepaliveTime: 30000
# 软编码
软编码,在项目中添加配置文件,可避免今后代码多次修改
使用 properties类型
的文件,示例
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day2
username=root
password=111
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=6000
属性提取
提取前提注意文件路径,以下代码是 src文件夹下的路径!
//方法1
//需要添加 IOException异常捕获
InputStream inputStream = Dbutils.class.getClassLoader().getResourceAsStream("linkInfo.properties");
Properties properties = new Properties();
properties.load(inputStream);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String userName = properties.getProperty("user");
String passWord = properties.getProperty("password");
//方法2
ResourceBundle bundle = ResourceBundle.getBundle("文件名");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String userName = bundle.getString("user");
String passWord = bundle.getString("password");
# 代码索引
# JDBC应用
数据库数据:(Test库 student表 的数据)
SNO (varchar) | SNAME (varchar) | SSEX (varchar) | SBIRTHDAY (data) | CLASS (varchar) |
---|---|---|---|---|
108 | 曾华 | 男 | 1977-09-01 | 95033 |
105 | 匡明 | 男 | 1975-10-02 | 95031 |
107 | 王丽 | 女 | 1976-01-23 | 95033 |
101 | 李军 | 男 | 1976-02-20 | 95033 |
109 | 王芳 | 女 | 1975-02-10 | 95031 |
103 | 陆君 | 男 | 1974-06-03 | 95031 |
import java.sql.*;
import java.util.Properties;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-15 22:11
* @Modified_By:
* @Project: JDBC应用测试
*/
public class Demo {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
/*//也可以,通过对象 进行加载驱动
Driver myDriver = new com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver( myDriver );*/
//2. 获取连接
String userName = "root";
String passWord = "";
//jdbc:mysql://hostname:3306/databaseName?serverTimezone=UTC
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
/*//也可以,数据库URL和一个Properties对象连接
//前提需要导包 import java.util.Properties;
String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
Properties info = new Properties();
info.put("user","root");
info.put("password","");
connection = DriverManager.getConnection(URL , info);*/
//3. 定义sql,创建状态通道(进行sql语句的发送)
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM student;");
//4. 取出结果集信息
while (resultSet.next()) {
//取出数据
System.out.print("学号:" + resultSet.getInt("SNO") + ", ");
System.out.print("姓名:" + resultSet.getString("SNAME") + ", ");
System.out.print("性别:" + resultSet.getString("SSEX") + ", ");
System.out.println("班级:" + resultSet.getString("CLASS"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
//5. 关闭,释放资源
try {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
/*
学号:108, 姓名:曾华, 性别:男, 班级:95033
学号:105, 姓名:匡明, 性别:男, 班级:95031
学号:107, 姓名:王丽, 性别:女, 班级:95033
学号:101, 姓名:李军, 性别:男, 班级:95033
学号:109, 姓名:王芳, 性别:女, 班级:95031
学号:103, 姓名:陆君, 性别:男, 班级:95031
*/
# JDBC应用 增、删、改
import java.sql.*;
import java.util.Properties;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-15 22:11
* @Modified_By:
* @Project: JDBC应用 增、删、改
*/
public class Demo2 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int result = 0;
try {
//本次使用另一方法应用JDBC
//1. 加载驱动
Driver myDriver = new com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver( myDriver );
//2. 获取连接
//前提需要导包 import java.util.Properties;
String rul = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
Properties info = new Properties();
info.put("user","root");
info.put("password","");
connection = DriverManager.getConnection(rul , info);
//3. 定义sql,创建状态通道(进行sql语句的发送)
statement = connection.createStatement();
//4. SQL语句操作
//建表(前提:库中没有该表 tableTest)
String tableName = "tableTest";
String newTable = "CREATE TABLE "+tableName+"(no int,name varchar(10) NOT NULL);";
statement.executeUpdate(newTable);
//是否空表 (是否记录有数据)
if (!statement.execute("SELECT * FROM "+tableName+";")){
System.out.println("NULL Table....Creating");
}else {
System.out.println("NOT NULL Table");
}
//新增数据10条
String[] name = new String[]{"Sans","Jack","Tom","Cate","Jone","Bcck"};
for (int i = 1 ; i <= 5 ; i++) {
//INSERT INTO 表名 VALUES(值1 [,值2. . .]);
System.out.println("INSERT INTO "+tableName+" VALUE("+i+","+name[i]+");");
result = statement.executeUpdate("INSERT INTO "+tableName+" VALUE("+i+",'"+name[i-1]+"');");
isItDone(result);
}
//修改表(将 sans名 改为 Sanscan名)
//UPDATE 表名 SET 字段名1 = 字段值1 [,字段名2 = 值2…] [WHERE 条件表达式];
System.out.println("UPDATE "+tableName+" SET "+" name = 'Sanscan' WHERE name = 'sans';");
result = statement.executeUpdate("UPDATE "+tableName+" SET "+" name = 'Sanscan' WHERE name = 'sans';");
isItDone(result);
//删除数据 (删除名为Cate的记录)
//DELETE FROM 表名 [WHERE 条件表达式];
System.out.println("DELETE FROM "+tableName+" WHERE name = 'Cate';");
result = statement.executeUpdate("DELETE FROM "+tableName+" WHERE name = 'Cate';");
isItDone(result);
//查表
resultSet = statement.executeQuery("SELECT * FROM "+tableName+";");
while (resultSet.next()) {
//取出数据
System.out.print("NO." + resultSet.getInt("no") + ", ");
System.out.println("Name:" + resultSet.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//5. 关闭,释放资源
try {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**测试SQL语句执行情况*/
private static void isItDone(int result) {
if (result != 0){
System.out.println("执行成功");
}
result = 0;
}
}
/*
NOT NULL Table
INSERT INTO tableTest VALUE(1,Jack);
执行成功
INSERT INTO tableTest VALUE(2,Tom);
执行成功
INSERT INTO tableTest VALUE(3,Cate);
执行成功
INSERT INTO tableTest VALUE(4,Jone);
执行成功
INSERT INTO tableTest VALUE(5,Bcck);
执行成功
UPDATE tableTest SET name = 'Sanscan' WHERE name = 'sans';
执行成功
DELETE FROM tableTest WHERE name = 'Cate';
执行成功
NO.1, Name:Sanscan
NO.2, Name:Jack
NO.3, Name:Tom
NO.5, Name:Jone
*/
# PreparedStatement预状态通道
import java.sql.*;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-15 22:11
* @Modified_By:
* @Project: JDBC 预状态通道测试 PreparedStatement接口
*/
public class Demo3 {
public static void main(String[] args) {
Connection connection = null;
ResultSet resultSet = null;
PreparedStatement pps = null;
try {
//1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
String userName = "root";
String passWord = "";
//jdbc:mysql://hostname:3306/databaseName?serverTimezone=UTC
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
/*
* 3. 定义PreparedStatement预状态通道(进行sql语句的发送)
* */
String sql = "SELECT * FROM student WHERE CLASS=? AND SNAME=?;";
pps = connection.prepareStatement(sql);
String uName = "95031";
String uClass = "王芳";
//通过指定下标进行赋予值
pps.setString(1,uName);
pps.setString(2,uClass);
resultSet = pps.executeQuery();
//4. 取出结果集信息
while (resultSet.next()) {
//取出数据
System.out.print("学号:" + resultSet.getInt("SNO") + ", ");
System.out.print("姓名:" + resultSet.getString("SNAME") + ", ");
System.out.print("性别:" + resultSet.getString("SSEX") + ", ");
System.out.println("班级:" + resultSet.getString("CLASS"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
//5. 关闭,释放资源
try {
if (connection != null) {
connection.close();
}
if (pps != null) {
pps.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
/*
学号:109, 姓名:王芳, 性别:女, 班级:95031
*/
# JDBC事务应用
数据库 test库 cs表
no(int 主键 自增) | name(varchar 标签名) |
---|---|
··· | ··· |
import java.sql.*;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-18 19:44
* @Modified_By:
* @Project: 手动事务
*/
public class ManualAffairTest {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String userName = "root";
String passWord = "";
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
//关闭自动事务
connection.setAutoCommit(false);
//通道
statement = connection.createStatement();
//SQL操作
//新增加条数
String sql = "INSERT INTO cs (name) VALUES('11');";
System.out.println("影响数 : " + statement.executeUpdate(sql));
System.out.println("事务是否自动模式?"+ connection.getAutoCommit());
//手动提交
connection.commit();
} catch (Exception throwables) {
//异常回滚
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
try {
if (statement != null){
statement.cancel();
}
if (connection != null) {
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
/*
影响数 : 1
事务是否自动模式?false
*/
# Savepoints存档
import java.sql.*;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-18 22:18
* @Modified_By:
* @Project:Savepoints存档测试
*/
public class SavepointsTest {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
Savepoint archiveNo1 = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String userName = "root";
String passWord = "";
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
//关闭自动事务
connection.setAutoCommit(false);
//通道
statement = connection.createStatement();
//SQL操作
//新增加条数
System.out.println("影响数 : " + statement.executeUpdate("INSERT INTO cs (name) VALUES('22a');"));
//以上是SQL完成操作
archiveNo1 = connection.setSavepoint("ArchiveNo1");
System.out.println("影响数 : " + statement.executeUpdate("INSERT INTO cs (name) VALUES('22b');"));
System.out.println(3/0);
//手动提交
connection.commit();
} catch (Exception throwables) {
//异常回滚
try {
connection.rollback(archiveNo1);
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
# SQL批处理
数据库 test库 cs表
no(int 主键 自增) | name(varchar 标签名) |
---|---|
··· | ··· |
Statement通道实现批量处理
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-19 20:49
* @Modified_By:
* @Project: Statement通道实现批量处理
*/
public class StatementTest {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String userName = "root";
String passWord = "";
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
//关闭自动事务
connection.setAutoCommit(false);
//通道
statement = connection.createStatement();
//SQL操作
//新增加条数
String sql1 = "INSERT INTO cs (name) VALUES('柏竹a');";
statement.addBatch(sql1);
String sql2 = "INSERT INTO cs (name) VALUES('柏竹b');";
statement.addBatch(sql2);
String sql3 = "INSERT INTO cs (name) VALUES('柏竹c');";
statement.addBatch(sql3);
String sql4 = "INSERT INTO cs (name) VALUES('柏竹d');";
statement.addBatch(sql4);
String sql5 = "INSERT INTO cs (name) VALUES('柏竹e');";
statement.addBatch(sql5);
//批量执行SQL语句
int[] ints = statement.executeBatch();
for (int tmp : ints) {
System.out.println("anInt : " + tmp);
}
//手动提交
connection.commit();
} catch (Exception throwables) {
//异常回滚
try {
if (connection != null) {
connection.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
try {
if (connection != null) {
connection.close();
}
if (statement != null){
statement.cancel();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
PreparedStatement通道实现批量处理
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @Author: 柏竹
* @Description: 一个简洁主义...
* @Date_Created_in: 2021-03-19 21:23
* @Modified_By:
* @Project: PreparedStatement通道实现批量处理
*/
public class PreparedStatementTest {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement pps = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String userName = "root";
String passWord = "";
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url , userName , passWord);
//关闭自动事务
connection.setAutoCommit(false);
//通道
String sql = "INSERT INTO cs (name) VALUES(?);";
pps = connection.prepareStatement(sql);
//SQL操作
//新增加条数
pps.setString(1,"柏竹a");
pps.addBatch();
pps.setString(1,"柏竹b");
pps.addBatch();
pps.setString(1,"柏竹c");
pps.addBatch();
pps.setString(1,"柏竹d");
pps.addBatch();
pps.setString(1,"柏竹e");
pps.addBatch();
//批量执行SQL语句
int[] ints = pps.executeBatch();
for (int tmp : ints) {
System.out.println("anInt : " + tmp);
}
//手动提交
connection.commit();
} catch (Exception throwables) {
//异常回滚
try {
if (connection != null) {
connection.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
try {
if (connection != null) {
connection.close();
}
if (pps != null){
pps.cancel();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
# JDBC整合应用
项目链接下载