【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

这篇具有很好参考价值的文章主要介绍了【Java】学JDBC看这篇文章就够了—JDBC保姆级教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、JDBC概述

基本介绍

JDBC相关API

二、连接mysql数据库

准备工作

JDBC程序编写步骤

五种连接数据库的方式 

三、ResultSet(结果集)

基本介绍

四、Statement 和 PreparedStatement

Statement

PreparedStatement 

五、事务

基本介绍

六、批处理

基本介绍

七、数据库连接池

传统获取Connection问题分析

数据库连接池种类

Druid数据库连接池

八、Apache-DBUtils类库

基本介绍

使用DBUtils类库进行查询操作

使用DBUtils类库进行增删改操作

九、最后的话


 文章来源地址https://www.toymoban.com/news/detail-423122.html

一、JDBC概述

基本介绍

        1. JDBC为访问不同的数据库提供了统一的接口,为使用者屏蔽了细节问题。

 

        2. Java程序员使用JDBC,可以连接任何提供了JDBC驱动程序的数据库系统,从而完成对数据库的各种操作。 

 

        3. JDBC基本原理示意图

 

【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

 

        4. JDBC是Java提供一套用于数据库操作的接口API,Java程序员只需要面向这套接口编程即可。不同的数据库厂商,需要针对这套接口,提供不同实现。

 

【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

 

 

JDBC相关API

【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

 


二、连接mysql数据库

准备工作

        1. 创建一个 lib 目录

        2. 将 mysql-connector-java .jar  驱动复制进去(点击蓝色字体即可下载)

        3. 右键添加到 Library

 

【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

 

 

JDBC程序编写步骤

        1. 注册驱动 - 加载 Driver 类

        2. 获取连接 - 得到 Connection

        3. 执行增删改查 - 发送 SQL 给mysql执行

        4. 释放资源 - 关闭相关连接

 

五种连接数据库的方式 

        方式一:

package JDBC.Linkedways;

import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class linkedways1 {
    public static void main(String[] args) throws SQLException {
        //前提准备:导入mysql驱动

        //1.注册驱动
        Driver driver = new Driver();

        //2. 获取mysql连接
        // mysql连接地址  jdbc:mysql://IP:端口/数据库
        //此处我连接的时本地数据库,可以指定 ip 地址连接
        String url = "jdbc:mysql://localhost:3306/test";
        // Properties 文件存储用户名和密码
        Properties properties = new Properties();
        // user - 用户名   password — 密码  按此要求存入用户名和密码
        properties.setProperty("user", "root");
        properties.setProperty("password", "123456");
        // 按照指定的 url 和 Properties 获取连接
        Connection connect = driver.connect(url, properties);

        //3.执行增删改查
        //mysql语句
        String sql = "insert into jdbc values (1,'Mike',19)";

        Statement statement = connect.createStatement();
        //返回该指令影响的行数,为0则代表未执行成功
        int i = statement.executeUpdate(sql);
        System.out.println(i > 0 ? "yes" : "no");
        
        // 4. 释放资源
        connect.close();
        statement.close();

    }
}

        方式二:

package JDBC.Linkedways;

import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class linkedways2 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        //1. 加载 Driver 类 ,此处用类加载
        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) aClass.newInstance();

        //2. 获取mysql连接
        String url = "jdbc:mysql://localhost:3306/test";
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "123456");
        Connection connect = driver.connect(url, properties);

        //3. 执行mysql语句
        Statement statement = connect.createStatement();
        String sql = "update jdbc set age=age+1 where id = 1";
        int i = statement.executeUpdate(sql);
        System.out.println(i);

        //4. 关闭资源
        connect.close();
        statement.close();
    }
}

        方式三:

package JDBC.Linkedways;

import com.mysql.jdbc.Driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;


public class linkedways3 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        //1. 加载 Driver 类
        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) aClass.newInstance();

        //2. 连接mysql数据库
        String url = "jdbc:mysql://localhost:3306/test";
        //利用 Properties 文件获取用户名和密码
//        Properties properties = new Properties();
//        properties.setProperty("user", "root");
//        properties.setProperty("password", "123456");
//        Connection connection = DriverManager.getConnection(url, properties);

        //直接利用变量获取用户名和密码
        String user = "root";
        String password = "123456";
        DriverManager.registerDriver(driver);//可省略
//        com.mysql.jdbc.Driver //追进 Driver 类 可以发现在类加载的时候会自动注册
        /*
                static {
                        try {
                            DriverManager.registerDriver(new Driver());
                        } catch (SQLException var1) {
                            throw new RuntimeException("Can't register driver!");
                        }
                    }
         */
        //利用 DriverManager 类的 getConnection() 方法
        Connection connection = DriverManager.getConnection(url, user, password);

        //3. 执行mysql命令
        String sql = "insert into jdbc values (2,'Milan',20)";

        Statement statement = connection.createStatement();

        statement.executeUpdate(sql);

        //4. 关闭资源
        statement.close();
        connection.close();

    }
}

        方式四:

package JDBC.Linkedways;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class linkedways4 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 1. 加载 Driver 类
        Class.forName("com.mysql.jdbc.Driver");
//        com.mysql.jdbc.Driver //追进Driver类 可以发现在类加载的时候会自动注册
        /*
                static {
                    try {
                        DriverManager.registerDriver(new Driver());
                    } catch (SQLException var1) {
                        throw new RuntimeException("Can't register driver!");
                    }
                }
         */
        // 2. 连接mysql
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, user, password);

        // 3. 执行mysql语句
        String sql = "delete from jdbc where id = 4";
        Statement statement = connection.createStatement();
        statement.executeUpdate(sql);

        // 4. 关闭资源
        statement.close();
        connection.close();

    }
}

        方式五:

package JDBC.Linkedways;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class linkedways5 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
        //在4的基础上进行改进,通过读取外部配置文件来读取需要的数据,而不是直接在代码里写
        //这样我们可以在配置文件修改信息而程序不需要重新编译
        //准备工作
        //将外部配置文件读取进内存 FileInputStream
        Properties properties = new Properties();
        properties.load(new FileInputStream(new File("src/mysql.properties")));
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        //1. 加载Driver
        Class.forName(driver);//可不写
        /**
         * 1. mysql驱动 5.1.6 可以无需Class.forName(driver);
         * 2. 从JDK1.5以后使用的jdbc4,不再需要显示调用 Class.forName(driver) 注册驱动
         *    而是自动调用驱动jar包下的META-INF\java.sql.Driver 文本中的类名称去注册
         * 3. 建议还是写上,这样会更加明确。
         */

        //2. 连接mysql
        Connection connection = DriverManager.getConnection(url, user, password);

        //3. 执行mysql语句
        String sql = "insert into jdbc values(4,'ise',20)";
        Statement statement = connection.createStatement();
        int i = statement.executeUpdate(sql);

        //4. 关闭资源
        statement.close();
        connection.close();
    }
}

 

#mysql.properties配置文件
#建议放在src文件夹下
#url=jdbc:mysql://ip:端口/数据库?rewriteBatchedStatements=true
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
#user=用户名
user=root
#password=密码
password=123456
#driver=对应数据库对应的Driver类
driver=com.mysql.jdbc.Driver

温馨提示:推荐用最后一种,灵活度比较高而且操作简单。

 


三、ResultSet(结果集)

基本介绍

        1. 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。

 

        2. ResultSet对象保持一个光标指向其当前数据行。最初,光标位于第一行之前。

 

        3. next 方法将光标移动到下一行,并且由于在ResultSet 对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集。

代码演示:

package JDBC.ResultSet;

import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

public class ResultSet01 {
    public static void main(String[] args) throws Exception {
        //准备工作
        Properties properties = new Properties();
        properties.load(new FileInputStream(new File("src//mysql.properties")));
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        //1. loaded driver
        Class.forName(driver);

        //2. linked mysql
        Connection connection = DriverManager.getConnection(url, user, password);

        //3. do mysql_order
        PreparedStatement preparedStatement = connection.prepareStatement("select * from jdbc ");
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1) + "    " +
                    resultSet.getString(2) + "    " +
                    resultSet.getInt(3));
        }
        //4. close
        connection.close();
        preparedStatement.close();
        resultSet.close();

    }
}

四、Statement 和 PreparedStatement

Statement

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

        2. Statement 对象执行 SQL 语句,存在 SQL 注入风险。

        3. SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,恶意攻击数据库。

        4. 要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了。

代码演示:

package JDBC.Statement;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class Statement01 {
    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
        //准备工作
        Properties properties = new Properties();
        properties.load(new FileInputStream("src//mysql.properties"));
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");

        String name = "1' or"; //
        String pwd = "or '1'= '1"; // 万能密码

        //加载Driver
        Class.forName(driver); // 可省略

        //获取mysql连接
        Connection connection = DriverManager.getConnection(url, user, password);

        //执行mysql命令
        Statement statement = connection.createStatement();

        //SQL注入 通过插入一些非法语句使得验证条件被屏蔽
        String sql = "select * from users where name ='"
                + user + "' and password = '" + pwd + "'";

        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
            System.out.print(resultSet.getInt(1) + "\t");
            System.out.print(resultSet.getString(2) + "\t\t");
            System.out.println(resultSet.getString(3));
        }

        //关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

PreparedStatement 

        1. PreparedStatement 执行的 SQL 语句中的参数用问号表示,调用PreparedStatement 对象的 setXxx() 方法来设置这些参数。setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从1 开始),第二个是设置的 SQL 语句中参数的值。

        2. 调用 executeQuery() ,执行查询操作,返回ResultSet对象

        3. 调用 executeUpdate() ,执行增,删,改操作。

        4. 使用预处理可以不再使用 + 拼接sql语句,减少语法错误,而且可以有效的解决了SQL注入问题,还能大大减少编译次数,效率较高。通常情况下,我们推荐使用PreparedStatement。

代码演示:

package JDBC.PreparedStatement;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class PStatement_02 {
    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {
        //准备工作
        Properties properties = new Properties();
        properties.load(new FileInputStream("src//mysql.properties"));
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");

        String name = "1' or"; //
        String pwd = "or '1'= '1"; // 万能密码

        //加载Driver
        Class.forName(driver); // 可省略

        //获取mysql连接
        Connection connection = DriverManager.getConnection(url, user, password);

        //执行mysql命令
        String sql = "select * from users where name = ? and password = ?";

        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //在preparedStatement 调用setXxx()时会检查插入的语句,以此避免SQL注入问题
        preparedStatement.setString(1, name);
        preparedStatement.setString(2, pwd);

        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.print(resultSet.getInt(1) + "\t");
            System.out.print(resultSet.getString(2) + "\t\t");
            System.out.println(resultSet.getString(3));
        }//此时无输出

        //关闭资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

 


五、事务

基本介绍

        1. JDBC程序中当一个Connection 对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。

        2. JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务。

        3. 调用Connection的setAutoCommit(false)可以取消自动提交事务。

        4. 在所有的SQL语句都成功执行后,调用Connecttion的commit() 方法,提交事务。

        5. 在其中某个操作失败或者出现异常时,调用Connection的rollback() 方法,回滚事务,默认回滚到事务开始时,也可以自己设置保存点。

 代码演示:

package JDBC.Transaction;

import JDBC.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class transaction_01 {
    public static void main(String[] args) throws SQLException {
        //由前面的学习过程我们能发现,在JDBC操作数据库时,
        //获得Connection连接和释放资源的操作是相同的
        //因此我们可以写一个工具类,专门用来做连接操作和关闭资源操作
 
        //调用 JDBCUtils 工具类获得连接
        Connection con = JDBCUtils.con();
        String create_Table = "create table account (id int,`name` varchar(33),money double)";
        String insert1 = "insert into account values(1,'mike',1000)";
        String insert2 = "insert into account values(2,'Alice',20000)";
        String money_sub = "update account set money = money - 100 where id = 1";
        String money_add = "update account set money = money + 100 where id = 2";
        PreparedStatement preparedStatement = null;

        try {
            preparedStatement = con.prepareStatement(create_Table);
            preparedStatement.execute();
            preparedStatement = con.prepareStatement(insert1);
            preparedStatement.executeUpdate();
            preparedStatement = con.prepareStatement(insert2);
            preparedStatement.executeUpdate();
            con.setAutoCommit(false);//开始事务
            preparedStatement = con.prepareStatement(money_sub);
            preparedStatement.executeUpdate();
//            int a = 1 / 0;
            preparedStatement = con.prepareStatement(money_add);
            preparedStatement.executeUpdate();
            con.commit();//所有操作完成,提交事务
        } catch (SQLException e) {
            try {
                con.rollback();//若有异常事务回滚到开始时
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        } finally {
            //调用 JDBCUtils 工具类释放资源
            JDBCUtils.close(null, con, preparedStatement);
        }
    }
}

JDBCUtils工具类

 

        将获取连接和释放资源的过程封装成方法。

package JDBC;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class JDBCUtils {
    public static String url;
    public static String user;
    public static String password;
    public static String driver;
    
    //类加载时自动调用
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src//mysql.properties"));
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            driver = properties.getProperty("driver");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    //获得一个连接
    public static Connection con() {
        try {
            return DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    //关闭传入的资源,资源不存在则传入null
    public static void close(ResultSet resultSet, Connection connection, Statement statement) {

        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (connection != null) {
                connection.close();
            }
            if (statement != null) {
                statement.close();
            }


        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}

 


六、批处理

基本介绍

        1. 当需要成批插入或者更新时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理,通常情况下要比单独提交处理更有效率。

        2. JDBC的批量处理语句包括下面方法:

                addBatch():添加需要批量处理的SQL语句或参数

                executeBatch():执行批量处理语句

                clearBatch():清空批处理包的语句

        3. JDBC 连接MySQL时,如果要使用批处理功能,需要在url中添加参数?rewriteBatchedStatements=true(切记切记)

        4. 批处理往往和PreparedStatement一起搭配使用,既能减少编译次数,又减少运行次数,效率大大提高。

代码演示:

package JDBC.Batch_;

import JDBC.JDBCUtils;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Batch_01 {

    @Test
    // 传统方法执行5000句SQL指令
    public void m1() throws SQLException {
        Connection con = JDBCUtils.con();
        String sql = "insert into account values (?,?,?)";
        PreparedStatement preparedStatement = con.prepareStatement(sql);
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            preparedStatement.setInt(1, i);
            preparedStatement.setString(2, "jack" + i);
            preparedStatement.setInt(3, 22);
            preparedStatement.executeUpdate();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - begin);//耗时2281ms
        JDBCUtils.close(null, con, preparedStatement);
    }

    @Test
    //批处理执行5000句SQL语句
    public void m2() throws SQLException {
        Connection con = JDBCUtils.con();
        String sql = "insert into account values (?,?,?)";
        PreparedStatement preparedStatement = con.prepareStatement(sql);
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {//执行5000次sql
            preparedStatement.setInt(1, i);
            preparedStatement.setString(2, "jack" + i);
            preparedStatement.setInt(3, 20);
            preparedStatement.addBatch();//往批处理包添加SQL语句
            if ((i + 1) % 1000 == 0) {//批处理包添加1000条SQL语句后
                preparedStatement.executeBatch();//执行该批处理包
                preparedStatement.clearBatch();//清空该批处理包
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(end - begin);//耗时51ms

        JDBCUtils.close(null, con, preparedStatement);
    }


}

七、数据库连接池

传统获取Connection问题分析

 

        1. 传统的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证IP地址,用户名和密码(0.05s - 1s 时间)。需要数据库连接时,就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃。

 

        2. 每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将会导致数据库内存泄漏,最终将导致数据库重启。

 

        3. 传统获取连接方式,不能控制创建的连接数量,如连接过多,也可能导致内存泄漏,数据库崩溃。

 

        4. 为了解决传统开发中的数据库连接问题,可以采用数据库连接池技术。

 

数据库连接池种类

 

        JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现。

        常见的数据库连接池有下面几种。

        1. C3P0 数据库连接池,速度相对较慢,稳定性不错。

        2. DBCP 数据库连接池,速度相对C3P0较快,但不稳定。

        3. Proxool 数据库连接池,有监控连接池状态的功能,稳定性较C3P0差一点。

        4. BoneCP 数据库连接池,速度快。

        5. Druid(德鲁伊)数据库连接池,由阿里提供,集DBCP,C3P0,Proxool 优点于一身的数据库连接池。(后面主要介绍德鲁伊数据库连接池的使用)

 

Druid数据库连接池

 

准备工作:1.将 druid.jar 文件添加到lib目录(点击蓝色字体即可下载)

                  2. 右键选择 Add as Library

 

配置文件:1. 将下面配置信息存入 druid.properties 中

                  2. 将 druid.properties 存到 src 目录下

#配置文件,根据自己的具体需求设置
#driverClassName=对应数据库的驱动路径
driverClassName=com.mysql.jdbc.Driver
#url=jdbc:mysql://ip:端口/数据库?rewriteBatchedStatements=true
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
#username=你的用户名  password=对应的密码  
username=root
password=123456
#初始化连接数量
initialSize=20
#最小连接数量
minIdle=20
#最大连接数量
maxActive=50
#最大等待时间
maxWait=5000

 

 

代码演示:

package JDBC.Druid;

import JDBC.JDBCUtils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

//传统连接数据库和通过数据池连接对比

public class Druid01 {
    @Test
    //连续连接数据库5000次,每次连接完不关闭
    //出现错误提示:Too many connections
    public void m1() {
        for (int i = 0; i < 5000; i++) {
            //错误信息
            // Data source rejected establishment of connection,
            // message from server: "Too many connections"
            Connection con = JDBCUtils.con();
        }
    }

    //连接5000次数据库,每次连接完都关闭
    @Test
    public void m2() throws SQLException {
        long l = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            Connection con = JDBCUtils.con();
            con.close();
        }
        long l1 = System.currentTimeMillis();
        System.out.println(l1 - l);//耗时4385ms
    }

    //使用druid连接池连接数据库
    //获取5000次连接
    @Test
    public void m3() throws Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src//druid.properties"));

        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        long l = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            Connection connection = dataSource.getConnection();
            connection.close();
        }
        long l1 = System.currentTimeMillis();
        System.out.println(l1 - l);//耗时311ms
    }

}
package JDBC.Druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

public class Druid011 {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src//druid.properties"));

        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

        Connection connection = dataSource.getConnection();
        String sql = "select * from account";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.print(resultSet.getInt(1) + "\t");
            System.out.print(resultSet.getString(2) + "\t");
            System.out.println(resultSet.getInt(3));
        }

        connection.close();
        resultSet.close();
        preparedStatement.close();
    }
}

JDBCUtilsByDruid工具类

 

        在JDBCUtils工具类的基础上,将基于Druid数据库连接池的获取连接和释放资源操作封装成方法。

package JDBC;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtilsByDruid {
    public static DataSource dataSource = null;
    public static Properties properties = null;


    static {
        try {
            properties = new Properties();
            properties.load(new FileInputStream("src//druid.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static void close(ResultSet resultSet, Connection connection, Statement statement) {
        try {
            if (resultSet != null)
                resultSet.close();
            if (connection != null)
                connection.close();
            if (statement != null)
                statement.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

 


八、Apache-DBUtils类库

基本介绍

 

        1. commons - dbutils 是Apache 组织提供的一个开源JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量。

 

        2. QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增、删、改、查、批处理。

 

        3. ResultSetHandler接口:该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。其部分实现类如下:

【Java】学JDBC看这篇文章就够了—JDBC保姆级教程

  

使用DBUtils类库进行查询操作

        

 准备工作:

        1. 将 commons-dbutils.jar 文件添加到lib目录中(点击蓝色字体即可下载)

        2. 右键选择 Add as Library

 

package JDBC.Druid;

import JDBC.JDBCUtils;
import JDBC.JDBCUtilsByDruid;
import JDBC.student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class Druid02 {


    @Test
    //传统思路
    public void test1() throws SQLException {

        Connection con = JDBCUtils.con();

        PreparedStatement preparedStatement = con.prepareStatement("select * from jdbc");

        ResultSet resultSet = preparedStatement.executeQuery();
        ArrayList<student> students = new ArrayList<>();

        while (resultSet.next()) {
            int id = resultSet.getInt(1);
            String name = resultSet.getString(2);
            int age = resultSet.getInt(3);
            students.add(new student(id, name, age));
        }
        JDBCUtils.close(resultSet, con, preparedStatement);
        for (student student : students) {
            System.out.println(student);
        }


    }
    //使用DBUtils类库进行查询操作
    // 查询多行多列数据
    @Test
    public void m1() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        List<student> query = queryRunner.query(connection, "select * from jdbc",
                new BeanListHandler<>(student.class));
        /*
            注意:student类必须有无参构造器和 set 函数
            若无参构造器不存在,则无法实例化对象
            若set 不存在,则无法赋值,所有属性都会被赋一个默认值
        */
        System.out.println(query);

        JDBCUtilsByDruid.close(null, connection, null);
    }

    @Test
    //查询单行数据
    public void m2() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        student query = queryRunner.query(connection, "select * from jdbc where id = 1",
                new BeanHandler<>(student.class));
        System.out.println(query);
        JDBCUtilsByDruid.close(null, connection, null);
    }

    @Test
    //返回单行单列数据
    public void m3() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        Object query = queryRunner.query(connection, "select name from jdbc where id = 2", new ScalarHandler());
        System.out.println(query);
        JDBCUtilsByDruid.close(null, connection, null);
    }
}

 

使用DBUtils类库进行增删改操作

 

package JDBC.Druid;

import JDBC.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.SQLException;

public class Druid03 {
    //测试插入数据
    @Test
    public void m1() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();

        QueryRunner queryRunner = new QueryRunner();
        int update = queryRunner.update(connection, "insert into jdbc values(4,'erson',45)");
        System.out.println(update > 0 ? "yes" : "no");
        JDBCUtilsByDruid.close(null, connection, null);
    }

    @Test
    //测试更改数据
    public void m2() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();

        QueryRunner queryRunner = new QueryRunner();

        int update = queryRunner.update(connection, "update jdbc set name = 'Lihua' where id = 1 ");
        System.out.println(update > 0 ? "yes" : "no");
        JDBCUtilsByDruid.close(null, connection, null);
    }

    @Test
    //测试删除数据
    public void m3() throws SQLException {
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        int update = queryRunner.update(connection, "delete from jdbc where id =4");
        System.out.println(update > 0 ? "yes" : "no");
        JDBCUtilsByDruid.close(null, connection, null);
    }
}

 


九、最后的话

✨  原创不易,还希望各位大佬支持一下


👍  点赞,你的认可是我创作的动力!


⭐️  收藏,你的青睐是我努力的方向!


✏️  评论,你的意见是我进步的财富!

 

 

 

 

 

到了这里,关于【Java】学JDBC看这篇文章就够了—JDBC保姆级教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaWeb入门看这一篇文章就够了

    第1节 什么是web 第2节 什么是JavaWeb   第1节 JavaWeb服务器是什么 第2节 常见的JavaWeb服务器介绍 Tomcat当前最流行的web容器(免费) jetty(免费) Weblogic(收费) 第3节 Tomcat服务器 tomcat服务器介绍 tomcat的目录结构   tomcat的常用命令 tomcat的用户管理 tomcat的服务配置管理 在一台服务器上配

    2024年02月03日
    浏览(65)
  • DevOps是什么?只看这篇文章就够了!

    作者:沈洲 原文链接:DevOps是什么?只看这篇文章就够了!-云社区-华为云 作为一个热门的概念,DevOps这个名词在程序员社区里频频出现,备受技术大佬们的追捧。甚至网络上有了“南无DevOps”的戏言(南无在梵语的意思是“皈依”),也侧面反映了DevOps的风靡。 然而,一

    2024年02月21日
    浏览(48)
  • tmux 使用看这一篇文章就够了

    tmux是一个终端复用工具,允许用户在一个终端会话中同时管理多个终端窗口,提高了终端使用效率,尤其在服务器上进行远程管理时更加实用。在tmux中,可以创建多个终端窗口和窗格,并在这些窗口和窗格之间自由切换,还可以在后台运行会话,即使在终端断开连接后也可

    2024年02月02日
    浏览(57)
  • 关于电脑屏幕亮度的调整,看这篇文章就够了

    你可能需要定期更改屏幕亮度。当外面很亮的时候,你想把它调大,这样你就能看到。当你在黑暗的房间里时,你会希望它变暗,这样就不会伤害你的眼睛。降低屏幕亮度也有助于节省电力并延长笔记本电脑的电池寿命。 除了手动更改屏幕亮度外,Windows还可以通过多种方式

    2024年01月16日
    浏览(44)
  • 初级面试问到rabbitMQ,看这一篇文章就够了!

    一、rabbitMQ的基础要点回顾 1.使用场景 1) 解耦: 使用消息队列避免模块间的直接调用。将所需共享的数据放在消息队列中,对于新增的业务模块,只要对该类消息感兴趣就可以订阅该消息,对原有系统无影响,降低了各个模块的耦合度,提供系统的扩展性。 2) 异步: 消息

    2024年02月04日
    浏览(51)
  • 交换机如何隔离广播域?(看这篇文章就够了)

         交换机可以隔离冲突域但是不能隔离广播域,当主机数目较多时会导致安全隐患、广播泛滥、性能显著下降甚至造成网络不可用。在这种情况下出现了VLAN (虚拟局域网,Virtual Local Area Network)技术解决以上问题。       如图是一个典型的交换网络,网络中只有终端计算

    2024年02月10日
    浏览(49)
  • 干货|工作中要使用Git,看这篇文章就够了

    本文将从 Git 入门到进阶、由浅入深,从常用命令、分支管理、提交规范、vim 基本操作、进阶命令、冲突预防、冲突处理等多方面展开,足以轻松应对工作中遇到的各种疑难杂症,如果觉得有所帮助,还望看官高抬贵手给个赞呗,感谢! 虽说现在工作中使用 Git 都会用一些图

    2023年04月25日
    浏览(36)
  • 关于HDMI如何连接显示器,看这篇文章就够了

    使用HDMI(高清多媒体接口)电缆将显示器连接到计算机,可以提供一种简单方便的方式来增强你的观看体验。HDMI是一种广泛使用的数字视频和音频接口,可实现视频和音频信号的高质量未压缩传输。使用HDMI,你可以在显示器上享受令人惊叹的视觉效果和水晶般清晰的声音,

    2024年02月01日
    浏览(93)
  • 27、BGP与OSPF有啥区别?看这篇文章就够了

    今天跟大家聊聊BGP与OSPF。 BGP和OSPF是两种最常见的路由协议,BGP在大型网络中具有动态路由优势,而OSPF具有更高效的路径选择和收敛速度。 边界网关协议(Border Gateway Protocol,简称BGP)和开放最短路径优先协议(Open Shortest Path First,简称OSPF)是世界上最流行的两种基于标准的动态

    2024年02月10日
    浏览(37)
  • 何为 Vue3 组件标注 TS 类型,看这篇文章就够了!

    要说今年最热门的前端技术,Vue3 和 TS 绝对榜上有名了。今天就给大家分享一下如何在 Vue3 组件中结合 Composition-Api 使用 TS 类型。如果有不会或者不熟的小伙伴,一起学起来吧! 使用 script setup 当使用 script setup 时, defineProps() 宏函数支持从它的参数中推导类型: 这被称为

    2023年04月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包