JDBC和连接池

Posted Al_tair

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC和连接池相关的知识,希望对你有一定的参考价值。

JDBC和连接池

大家好,我是小笙,我们学习了JavaSe基础和mysql基础,自然而然我们需要通过JDBC和连接池来连接数据库和优化java程序操作数据库,以下是我的学习笔记


JDBC和连接池

JDBC

JDBC概述

java程序代码通过使用JDBC可以连接任何提供了JDBC驱动的数据库,从而完成对数据库的操作

JDBC基本原理图

JDBC API就是图中的接口规范,它统一了java应用程序和数据库的连接等操作

JDBC程序编写

  1. 注册驱动 - 加载Driver类
    • Driver :每个驱动程序类必须实现的接口
    • DriverManage :用于管理一组JDBC驱动程序的基本服务。
  2. 获取连接 - 得到Connection
  3. 执行增删改查 - 发送SQL语句给mysql数据库执行
  4. 释放资源 - 关闭相关的连接

连接数据库代码实现

// 方式一:静态加载
public static void main(String[] args) throws SQLException 
    // 1. 注册驱动 - 加载Driver类
    Driver driver = new Driver();

    // 2. 获取连接 - 得到Connection
    String url = "jdbc:mysql://localhost:3308/al_tair";
    // 将用户名和密码放入到Properties对象中
    Properties properties = new Properties();
    properties.setProperty("user","XXX"); // 用户
    properties.setProperty("password","XXXXXX"); // 密码
    Connection connect = driver.connect(url, properties);

    // 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
    String sql = "insert into dog values(2,'steven')";
    // statement用于执行静态sql语句并返回其生成的结果对象,后面具体详讲
    Statement statement = connect.createStatement();
    int rows = statement.executeUpdate(sql); // 返回是否添加成功
    System.out.println(rows>0? "添加成功" : "添加失败");

    // 4. 释放资源 - 关闭相关的连接
    statement.close();
    connect.close();


// 方式二:动态加载
// 1. 注册驱动 - 使用反射加载Driver类
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException 
     // 1. 注册驱动 - 使用反射加载Driver类
     Class cls = Class.forName("com.mysql.jdbc.Driver");
     Driver driver = (Driver) cls.newInstance();

     // 2. 获取连接 - 得到Connection
     String url = "jdbc:mysql://localhost:3308/al_tair";
     // 将用户名和密码放入到Properties对象中
     Properties properties = new Properties();
     properties.setProperty("user","XXX"); // 用户
     properties.setProperty("password","XXXXXX"); // 密码
     Connection connect = driver.connect(url, properties);

     // 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
     String sql = "insert into dog values(3,'marry')";
     // statement用于执行静态sql语句并返回其生成的结果对象
     Statement statement = connect.createStatement();
     int rows = statement.executeUpdate(sql); // 返回是否添加成功
     System.out.println(rows>0? "添加成功" : "添加失败");

     // 4. 释放资源 - 关闭相关的连接
     statement.close();
     connect.close();
 

// 方式三:DriverManage 
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException 
    // 1. 注册驱动 - 加载Driver类 - DriverManage :用于管理一组JDBC驱动程序的基本服务
    Class cls = Class.forName("com.mysql.jdbc.Driver");
    Driver driver = (Driver) cls.newInstance();
    String url = "jdbc:mysql://localhost:3308/al_tair";
    String root = "XXX";
    String pwd = "XXXXXX";
    // 注册驱动
    DriverManager.registerDriver(driver);

    // 2. 获取连接 - 得到Connection
    Connection connection = DriverManager.getConnection(url, root, pwd);

    // 3. 执行增删改查 - 发送SQL语句给mysql数据库执行
    String sql = "insert into dog values(4,'tony')";
    // statement用于执行静态sql语句并返回其生成的结果对象
    Statement statement = connection.createStatement();
    int rows = statement.executeUpdate(sql); // 返回是否添加成功
    System.out.println(rows>0? "添加成功" : "添加失败");

    // 4. 释放资源 - 关闭相关的连接
    statement.close();
    connection.close();


// 方式四:方式三的简化版(推荐)
/*
Driver 原码分析:注册Driver在静态代码块中已经实现
public class Driver extends NonRegisteringDriver implements java.sql.Driver 
    public Driver() throws SQLException 
    
    static 
        try 
            DriverManager.registerDriver(new Driver());
         catch (SQLException var1) 
            throw new RuntimeException("Can't register driver!");
        
    

*/
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, SQLException 
    Class cls = Class.forName("com.mysql.jdbc.Driver");
    String url = "jdbc:mysql://localhost:3308/al_tair";
    String root = "XXX";
    String pwd = "XXXXXX";

    // 1. 获取连接 - 得到Connection
    Connection connection = DriverManager.getConnection(url, root, pwd);

    // 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
    String sql = "insert into dog values(5,'jack')";
    // statement用于执行静态sql语句并返回其生成的结果对象
    Statement statement = connection.createStatement();
    int rows = statement.executeUpdate(sql); // 返回是否添加成功
    System.out.println(rows > 0 ? "添加成功" : "添加失败");

    // 3. 释放资源 - 关闭相关的连接
    statement.close();
    connection.close();


// 方式五:mysql5.1.6可以无需手动反射Driver类,会自动调用驱动jar下的驱动包
public static void main(String[] args) throws SQLException 
    String url = "jdbc:mysql://localhost:3308/al_tair";
    String root = "root";
    String pwd = "luo1234567";

    // 1. 获取连接 - 得到Connection
    Connection connection = DriverManager.getConnection(url, root, pwd);

    // 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
    String sql = "insert into dog values(6,'son')";
    // statement用于执行静态sql语句并返回其生成的结果对象
    Statement statement = connection.createStatement();
    int rows = statement.executeUpdate(sql); // 返回是否添加成功
    System.out.println(rows > 0 ? "添加成功" : "添加失败");

    // 3. 释放资源 - 关闭相关的连接
    statement.close();
    connection.close();

使用配置文件读入来连接数据库

// Properties.properties
root = root
pwd = XXXXXX
url = jdbc:mysql://localhost:3308/al_tair
driver = com.mysql.jdbc.Driver
    
// package com.Al_tair.connectMySql.myJDBC;
public class JdbcDemo6 
    public static void main(String[] args) throws IOException, SQLException 
        Properties properties = new Properties();
        String filePath = "E:\\\\Java_training\\\\Java_code\\\\JavaIdea03\\\\java\\\\Javase_HSping\\\\src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
        properties.load(new FileInputStream(filePath));
        String url = properties.getProperty("url");
        String root = properties.getProperty("root");
        String pwd = properties.getProperty("pwd");
        // 1. 获取连接 - 得到Connection
        Connection connection = DriverManager.getConnection(url, root, pwd);

        // 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
        String sql = "insert into dog values(7,'Jason')";
        // statement用于执行静态sql语句并返回其生成的结果对象
        Statement statement = connection.createStatement();
        int rows = statement.executeUpdate(sql); // 返回是否添加成功
        System.out.println(rows > 0 ? "添加成功" : "添加失败");

        // 3. 释放资源 - 关闭相关的连接
        statement.close();
        connection.close();
    

// 拓展:如果用idea编译器无法正确使用相对路径,检查:Run -> Edit Configurations -> 选中对应java程序修改Working directory,该地址就是相对位置的起点;如果不会就使用全路径

Statement

Statement对象用于执行静态SQL语句并返回其生成的结果对象

在业务中,我们一般不使用Statement对象对数据库(存在SQL注入的风险:利用某些系统没有对用户输入的数据及逆行充分的过滤,注入非法的SQL语句,恶意攻击数据库)

进而我们使用 PrepareStatement(预处理,主要使用这个),CallableSatement(可以处理数据库的存储过程)

// PrepareStatement 讲解
// ? 占位符 可以通过set语句填充,如下图
String sql = "SELECT *FROM emp WHERE username = ? AND password = ?";
// 预处理的好处
// 1. 不再使用 + 拼接sql语句,减少语法错误
// 2. 有效的解决了sql注入问题
// 3. 大大减少了编译次数,效率较高

// executeUpdate() 方法无需再填入sql语句
public static void main(String[] args) throws IOException, SQLException 
    String admin_name = "";
    String admin_pwd = "";

    // 读取配置文件
    Properties properties = new Properties();
    String filePath = "src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
    properties.load(new FileInputStream(filePath));
    String url = properties.getProperty("url");
    String root = properties.getProperty("root");
    String pwd = properties.getProperty("pwd");
    // 1. 获取连接 - 得到Connection
    Connection connection = DriverManager.getConnection(url, root, pwd);

    // 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
    String sql = "select `name`,pwd from admin where name = ? and pwd = ? ";
    // preparedStatement用于执行静态sql语句并返回其生成的结果对象
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setString(1,admin_name);
    preparedStatement.setString(2,admin_pwd);

    int rows = preparedStatement.executeUpdate();
    System.out.println(rows> 0 ? "成功" : "失败");
    // 3. 释放资源 - 关闭相关的连接
    preparedStatement.close();
    connection.close();

ResultSet(结果集)

概念:表示数据库结果集的数据表(通常通过执行查询数据库语句执行)

ResultSet对象保持一个光标指向当前的数据行,光标从第一行开始向下遍历,如果没有更多行的时候将会返回false,迭代器的用法

public class ResultSetDemo1 
    public static void main(String[] args) throws IOException, SQLException \\
        // 读取配置文件
        Properties properties = new Properties();
        String filePath = "src\\\\com\\\\Al_tair\\\\connectMySql\\\\myJDBC\\\\Properties.properties";
        properties.load(new FileInputStream(filePath));
        String url = properties.getProperty("url");
        String root = properties.getProperty("root");
        String pwd = properties.getProperty("pwd");
        // 1. 获取连接 - 得到Connection
        Connection connection = DriverManager.getConnection(url, root, pwd);

        // 2. 执行增删改查 - 发送SQL语句给mysql数据库执行
        String sql = "select *from dog";
        // statement用于执行静态sql语句并返回其生成的结果对象
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next())
            int index = 1;
            int id = resultSet.getInt(index++); // 获取第一列
            String name = resultSet.getString(index); // 获取第二列
            System.out.println("id: "+ id + "  name: "+name);
        

        // 3. 释放资源 - 关闭相关的连接
        resultSet.close();
        statement.close();
        connection.close();
    

JDBC API梳理

JDBC自定义工具类

为了减少代码复用性,我们添加工具类来实现连接和关闭

public class JDBCUtils 
    private static String user; // 用户名
    private static String password; // 密码
    private static String url; // url

    static 
        String filePath = "E:\\\\Java_training\\\\Java_code\\\\JavaIdea03\\\\java\\\\Javase_HSping" +
                "\\\\src\\\\com\\\\Al_tair\\\\connectMySql\\\\utils\\\\Properties.properties";
        Properties properties = new Properties();
        try 
            properties.load(new FileInputStream(filePath));
            user = properties.getProperty("root");
            password = properties.getProperty("pwd");
            url = properties.getProperty("url");
         catch (IOException e) 
            throw new RuntimeException(e);
        
    
    
    // 连接数据库
    public static Connection getConnection()
        try 
            return DriverManager.getConnection(url,user,password);
         catch (SQLException throwables) 
            throw new RuntimeException(throwables);
        
    
    
    // 查询语句关闭
    public static void closeQueryConnection(ResultSet rst, Statement statement,Connection connection)
        try 
            rst.close();
            statement.close();
            connection.close();
         catch (SQLException throwables) 
            throw new RuntimeException(throwables);
        
    

    // dml语句操作关闭
    public static void closeDmlConnection(Statement statement,Connection connection)
        try 
            statement.close();
            connection.close();
         catch (SQLException throwables) 
            throw new RuntimeException(throwables);
        
    

操作数据库的事务

概念:创建Connection默认是自动提交事务,每次执行sql语句都会默认自动提交commit,不能发生回滚

批处理

作用:用来一次性插入多条sql语句,提高插入效率

JDBC批量处理(PreparedStatement接口)方法如下

PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.addBatch(); // 增加批处理数据
preparedStatement.executeBatch(); // 进行批处理
preparedStatement.clearBatch(); // 清空批处理

注意:JDBC连接Mysql时候,如果要使用批处理功能,必须在url路径中添加如下语句,并且往往和PreparedStatement一起使用,不仅减少编译次数,也可以减少运行次数,效率大大提高

// 添加?rewriteBatchedStatements=true语句
root = xxxx
pwd = xxxxxxxx
url = jdbc:mysql://localhost:3308/al_tair?rewriteBatchedStatements=true

测试代码(批量处理大大减少时间)

// 批处理底层数据就是存放在ArrayList集合中batchedArgs对象数组中
public class BatchDemo 
    public static void main(String[] args) throws SQLException 
        Connection connection = JDBCUtils.getConnection();
        // ? 占位符
        String sql = 04-JDBC-连接池

JDBC 连接池:连接重用?

JDBC—— 获取连接池方式

JAVAWEB学习笔记10_JDBC连接池&DBUtils

Glassfish 应用服务器中的 JDBC 和连接池

javaWeb_JDBC_数据库连接池概述以及dbcp连接池