• 4.JDBC技术


    一、JDBC概述
    1. JDBC:Java DataBase Connectivity Java连接数据库技术。

    2. JDBC四个接口一个类

      1. DriverManager:驱动管理器类,管理JDBC驱动,不同数据库驱动管理器不同
      2. Driver:驱动接口
      3. Connection:连接接口 传输数据
      4. Statement:由Connection创建,执行SQL接口
      5. ResultSet:保存Statement执行后产生的查询结果集接口
      // java.sql.DriverManager类,获取并加载驱动
      Class.forName("驱动连接");
          MySQL5:		"com.mysql.jdbc.Driver"
          MySQL8:		"com.mysql.cj.jdbc.Driver"
          Oracle11g:	"oracle.jdbc.driver.OracleDriver"    
          
      // java.sql.Driver驱动接口
      
      // java.sql.Connection 获取连接,实现与数据库之间的连接
      Connection conn = DriverManager.getConnection(数据库连接,用户名,密码);
          MySQL:		"jdbc:mysql://localhost:3306/数据库名?useSSL=false&characterEncoding=utf-8&serverTimeZone=Asia/Shanghai"
          Oracle: 	"jdbc:oracle:thin:@localhost:1521:数据库实例名"
          
      // java.sql.Statement,java.sql.PreparedStatement 发送并执行SQL接口
      // 1. 创建执行sql的对象
      Statement statement = conn.createStatement();		
      // 2. 创建预编译对象
      PreparedStatemnt preparedStatement = conn.prepareStatement(sql);
      // 3. 返回自增的键 仅在增加语句使用
      PreparedStatemnt preparedStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);	
      
      // java.sql.ResultSet	获取查询的结果集
      // 1. 执行sql返回结果集或操作的行数
      ResultSet resultSet = statement.executeQuery(sql);
      int num = statement.executeUpdate(sql);
      // 2. 预编译对象已经执行过sql 返回结果集或操作的行数
      ResultSet resultSet = preparedStatement.executeQuery();
      int num = preparedStatement.executeUpdate();
      // 3. 获取自增键的结果集
      Result resultSet = preparedStatement.getGeneratedKeys();
      
    3. JDBC连接步骤

      1. 加载驱动
      2. 创建连接
      3. 编写sql
      4. 获取sql执行对象
      5. 执行sql并返回
      6. 关闭资源
    二、SQL注入
    1. 概念:通过特殊参数传入程序,非法侵入系统
    2. 解决方法:使用PreparedStatement创建对象
     - PreparedStatement批处理速度快,效率高,安全性高
     - PreparedStatement不使用字符串拼接,安全性高
     - 预编译SQL命令,无需多次创建对象,批处理速度快,效率高
     - Statement使用SQL拼接,执行一次编译一次,效率低,安全性低
    
    三、封装Connection对象
    # jdbc.properties
    # DRIVER
    driverClassName=com.mysql.cj.jdbc.Driver
    # URL
    url=jdbc:mysql://localhost:3308/goods?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    # USER
    username=root
    # PASSWORD
    password=mysql
    # 最大活跃数量
    maxActive=50
    # 最大空闲数量
    maxIdle=20
    # 最大等待时长
    maxWait=60000
    
    package com.goods.util;
    
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    
    /**
     * @program: jdbc_study
     * @description: MySQL工具类
     * @author: MaEnguang
     * @create: 2021-06-01 10:10
     **/
    public class DBUtil {
        // 工具类 禁止外部实例化
        private DBUtil() {
        }
    
        // 声明一个配置文件类
        private static Properties properties = new Properties();
        // 创建数据源对象
        private static DataSource dataSource;
    
        static {
            try (
                    // 获取文件流
                    InputStream resourceAsStream = DBUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
            ) {// 文件类加载文件流
                properties.load(resourceAsStream);
                // 创建数据源管理
                dataSource = BasicDataSourceFactory.createDataSource(properties);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // 处理多线程
        private static ThreadLocal<Connection> local = new ThreadLocal<>();
    
        /**
         * 获取连接
         * @return
         * @throws ClassNotFoundException
         * @throws SQLException
         */
        public static Connection getConnection() throws SQLException {
            // 仅获取本地一条线程的连接
            Connection connection = local.get();
            if (connection == null || connection.isClosed()) {
                // 通过数据源管理连接
                connection = dataSource.getConnection();
                // 将数据源放到本地线程中 保证线程安全
                local.set(connection);
            }
            return connection;
        }
    
        /**
         * 关闭连接
         */
        public static void closeConnection() {
            try {
                // 仅获取本地一条线程的连接
                Connection connection = local.get();
                if (connection != null && !connection.isClosed()) {
                    // 释放数据源中占用的连接
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                // 线程需要移除
                local.remove();
            }
        }
    
    }
    
    四、事务
    1. 事务的特点

      1. 原子性:一个事务,要么都提交,要么都回滚
      2. 一致性:事务必须是数据库从一个一致性状态变到另一个一致性状态
      3. 隔离性:事务之间互不影响
      4. 持续性:事务的结果可以被永久保留
    2. 事务的开始与结束

      1. 显示开始:执行DML
      2. 显式结束:执行commit,rollback
      3. 隐式提交:执行了DDL,DCL,exit
      4. 隐式回滚:系统异常,死机
    3. 事务中易出现的并发问题

      1. 脏读:读取到未提交的数据
      2. 不可重复读:同时读取数据时能读取到此时被修改的数据
      3. 幻读:同时读取数据时,读取到此时新增或删除的数据
    4. 事务的隔离级别

      1. 读未提交:可以读取到未提交的数据,脏读
      2. 读已提交:不能读取到未提交的数据,避免脏读
      3. 可重复读:同时访问数据时,禁止修改,避免不可重复读
      4. 串行化:同时访问数据时,禁止添加删除数据,避免幻读
    5. JDBC中的事务

      // 业务层增删改操作需要提交事务
      // 关闭自动提交
      connection.setAutoCommit(false);
      // 业务处理...
      // 业务处理后提交事务
      connection.Commit();
      
  • 相关阅读:
    ZABBIX监控TCP连接状态
    MySQL索引(九)
    MySQL字符集、information_schema元数据(八)
    DML(数据库操作语言)(六)
    DDL(数据库定义语言)(五)
    MySQL多实例安装、配置、启动(四)
    CentOS7 编译安装MySQL5.6.38(一)
    MySQL权限管理、配置文件(三)
    MySQL服务的构成(二)
    yum lockfile is held by another process
  • 原文地址:https://www.cnblogs.com/forelim/p/14856155.html
Copyright © 2020-2023  润新知