柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

    • MySQL
    • JDBC
      • 体系构架
        • 体系结构
        • 组件
      • 首次应用
      • API
        • Connection
        • ResultSet
        • ResultSetMetaData
        • Statement
        • PrepareStatement
      • 多表关系
      • 事务应用
        • Savepoints(事务存档)
      • 批量处理
      • 反射处理集
      • 连接池
        • DBCP连接池
        • C3P0连接池
        • Druid连接池
        • HikariCP 连接池
        • 软编码
      • 代码索引
        • JDBC应用
        • JDBC应用 增、删、改
        • PreparedStatement预状态通道
        • JDBC事务应用
        • Savepoints存档
        • SQL批处理
        • JDBC整合应用
    • Hibernate
    • Mybatis
    • Redis
    • Redis原理篇
  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • 数据库
柏竹
2020-02-18
目录

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应用:

  1. 导入包 import java.sql.*
  2. **注册JDBC驱动程序 ** 通过Java程序 初始化驱动程序 Class.forName("com.mysql.cj.jdbc.Driver"); , 驱动类文件加载至内存中,并自动注册
  3. 连接对象 通过 DriverManager.getConnection(String url, String userName, String passWord )方法 获取 Connection对象 (数据库的物理连接)
  4. 执行查询 通过 Statement对象 构建 和 提交SQL语句到数据库
  5. 结果集提取数据 通过 ResultSet.getXXX(String 字段名 )方法 获取结果集检索数据(XXX代表对应的数据类型)
  6. 释放资源 关闭所有数据库资源,避免依赖JVM垃圾收集器

**注册JDBC驱动程序 方法 **

Class.forName(String str) 根据路径进行加载驱动 DriverManager.registerDriver(Driver mydriver) 静态方法 对象加载

点击代码示例* (JDBC应用)

# 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() 关闭对象

点击代码示例* (JDBC应用 增、删、改)

恶意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区别

  1. statement属于状态通道,PreparedStatement属于预状态通道
  2. 预状态通道会先编译sql语句,再去执行,比statement执行效率高
  3. 预状态通道支持占位符? ,给占位符赋值的时候,位置从1开始
  4. 预状态通道可以防止sql注入,因 预状态通道在处理值的时候以字符串形式处理
  5. 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) (可以自行下载查看详细操作 · 免费)

# 事务应用

点击事务了解 (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();

点击代码示例* (JDBC事务应用)

# 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();
            }
}

点击代码示例* (Savepoints存档)

# 批量处理

JDBC允许 批量处理SQL语句 ,通过事务一次调用提交库 一次发送多条SQL语句,可减少数据库的交互次数,提高质量

通过 PreparedStatement对象 、 Statement对象 实现批处理方法

返回 方法 说明
void addBatch() PreparedStatement对象添加SQL语句
void addBatch(String sql) Statement对象 添加SQL语句
int[] executeBatch() 获取批量执行的影响数(顺序=添加SQL顺序),并执行 批量SQL语句

实现步骤

  1. 连接数据库 Connection对象
  2. 设置手动事务 Connection对象 的 setAutoCommit(false)方法
  3. 获取通道对象 PreparedStatement对象 或 Statement对象
  4. 不同通道对象,添加方式不同! Statement对象 通过 addBatch(sql)方法 实现添加SQL语句 PreparedStatement对象 通过 addBatch()方法 实现添加 SQL语句
  5. 通过 通道对象 的 executeBatch()方法 批量执行SQL语句
  6. 提交事务 Connection对象 的 commit()方法 进行提交

注意: 批量处理过程中出现异常,可通过异常捕获进行回滚操作

点击代码示例* (SQL批处理)

# 反射处理集

利用反射处理查询到的结果集,对应的数据赋予对象! 注意:以下代码要求库中的字段名与类中的属性名相同,且类所有属性都有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);
    }
}

# 连接池

点击连接池说明 (opens new window)

# DBCP连接池

实现步骤:

  1. 导入jdk依赖包 mysql-jdbc.jar commons-dbcp.jar commons-pool.jar
  2. 实例 BasicDataSource对象
  3. 功能属性实现 BasicDataSource对象 的 set方法
  4. 获取连接 通过 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区别

  1. C3P0有自动回收空闲连接功能,DBCP没有
  2. C3P0无需手动,DBCP需手动配置文件
  3. C3P0配置文件命名固定(c3p0-config.xml)

实现步骤:

  1. 导入jdk依赖包

    mysql-jdbc.jar

    c3p0-0.9.1.2.jar (版本号)

  2. 创建 c3p0-config.xml 配置文件,路径:src文件夹下

  3. 手动 配置文件 调用无参的默认配置 <default-config> 调用有参的配置<named-config name="Myc3p0Test"> 自定命名

  4. 实例 ComboPooledDataSource对象 无参调用默认的,有参调用自定义的

  5. 获取连接 通过 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是目前大厂流行的连接池,有以下特点:

  1. 秒查询 快速的聚合能力以及亚秒级的OLAP查询能力
  2. 实时数据注入 保证在实时和离线环境下 事件的 实效性 和 统一性
  3. 可扩展PB级存储 扩容到PB的数据量,每秒百万级别的数据注入
  4. 多环境部署 可从多种数据系统中注入数据
  5. 丰富社区 学习交流

实现步骤: (实现方式跟DBCP差不多)

  1. 导入jdk依赖包 mysql-jdbc.jar druid-1.0.9.jar (版本号)
  2. 实例 DruidDataSource对象
  3. 功能属性实现 DruidDataSource对象 的 set方法
  4. 获取连接 通过 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整合应用

项目链接下载

#JDBC#
上次更新: 2023/03/12, 00:43:49

← MySQL Hibernate→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式