JavaWeb开发之JDBC知识总结

JDBC(Java数据库连接),是一种用于执行SQL语句的Java的API,它由一组Java语言编写的类和接口组成,可以为多种关系型数据库提供统一访问。没有JDBC的时候,如果现在要开发一套系统,使用Java连接MySQL数据库,那么这时候Java程序员需要了解MySQL驱动API,如果使用Java连接Oracle数据库,那么这个时候Java程序员需要了解Oracle数据库驱动API。SUN公司提供一套统一的规范(接口)。然后各个数据库生产商提供这套接口的实现。这套接口规范就是JDBC的规范。

目录

1、JDBC入门程序

 2、JDBC的CRUD操作

3、JDBC之工具类的抽取

4、JDBC的SQL注入问题及解决

5、JDBC的CRUD操作之PreparedStatement

6、JBDC的事务管理

7、连接池之Druid与C3P0

8、JDBC之改写工具类

9、DBUtils的学习之CRUD操作

10、DBUtils使用之ResultSetHandler实现类


1、JDBC入门程序

首先创建数据库和表,并参插入数据,导入连接mysql的jar包,然后编写程序实现:加载驱动,获得连接,执行基本查询操作,释放资源。

创建数据库和表,插入记录代码如下:

create database if not exists web_test1;
use web_test1;
create table if not exists user(
	id int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	nickname varchar(20),
	age int
);
insert into user values (null,'aaa','123','小丽',34);
insert into user values (null,'bbb','123','大王',32);
insert into user values (null,'ccc','123','小明',28);
insert into user values (null,'ddd','123','大黄',21);

jdbc连接数据库,并执行查询语句:
 

import java.sql.*;

public class JDBCDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        test() ;
    }

    private static void test() throws ClassNotFoundException, SQLException {
        // 1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.获得连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test1", "root", "123456");
        Statement statement = conn.createStatement();
        // 3.2编写SQL语句:
        String sql = "select * from user";
        // 3.3执行SQL:
        ResultSet rs = statement.executeQuery(sql);
        // 3.4遍历结果集:
        while(rs.next()){
            System.out.print(rs.getInt("id")+" ");
            System.out.print(rs.getString("username")+" ");
            System.out.print(rs.getString("password")+" ");
            System.out.print(rs.getString("nickname")+" ");
            System.out.print(rs.getInt("age"));
            System.out.println();
        }
        // 4.释放资源
        rs.close();
        statement.close();
        conn.close();
    }
}

注意:上述包含了JDBC的几个API

1)DriverManager:驱动管理类,用于获得连接。

2)Connection:与数据库连接的对象,用于创建执行SQL语句的对象,主要包括下面三个:

  1. Statement                           :执行SQL
  2. CallableStatement              :执行数据库中存储过程
  3. PreparedStatement            :执行SQL.对SQL进行预处理。解决SQL注入漏洞。

另外Connection也可以进行事务管理。

 3)Statement对象主要用于执行SQL语句,也可以执行批处理,具体如下:

  1. boolean execute(String sql): 执行查询,修改,添加,删除的SQL语句。
  2. ResultSet executeQuery(String sql):执行查询(执行select语句)。
  3. int executeUpate(String sql):  执行修改,添加,删除的SQL语句。

4)ResultSet是结果集,一般使用查询语句查到的结果都是一个结果集,对结果集进行遍历使用next()方法。

 2、JDBC的CRUD操作

使用executeQuery(String sql)方法执行增删改的操作会返回被影响的记录行,使用这个executeUpate(String sql)方法执行查询操作会返回一个ResultSet结果集。最后需要进行资源的释放。

import java.sql.*;

public class JDBCDemo01 {
    public static void main(String[] args) {
        test() ;
    }

    private static void test()  {
        Connection conn = null ;
        Statement statement = null ;
        ResultSet rs = null ;
        try {
            // 1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2.获得连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test1", "root", "123456");
            statement = conn.createStatement();
            // 3.2编写SQL语句:
            String sql1 = "insert into user values (null,'eee','123','阿黄',21)";
            String sql2 = "update user set password='abc',nickname='旺财' where id = 5";
            String sql3 = "delete from user where id = 5";
            String sql = "select * from user";

            // 3.3执行SQL:
            int num1 = statement.executeUpdate(sql1);
            if (num1 > 0) {
                System.out.println("插入成功");
            }
            int num2 = statement.executeUpdate(sql2);
            if (num2 > 0) {
                System.out.println("修改成功");
            }
            int num3 = statement.executeUpdate(sql3);
            if (num3 > 0) {
                System.out.println("删除成功");
            }

            rs = statement.executeQuery(sql);
            // 3.4遍历结果集:
            while (rs.next()) {
                System.out.print(rs.getInt("id") + " ");
                System.out.print(rs.getString("username") + " ");
                System.out.print(rs.getString("password") + " ");
                System.out.print(rs.getString("nickname") + " ");
                System.out.print(rs.getInt("age"));
                System.out.println();
            }
        }catch (Exception e){
            e.printStackTrace();

        }finally {
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if(statement != null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                statement = null;
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }

    }
}

3、JDBC之工具类的抽取

因为传统JDBC的开发,注册驱动,获得连接,释放资源这些代码都是重复编写的。所以可以将重复的代码提取到一个类中来完成。

首先在src目录下创建配置文件db.properties,配置Mysql,后面在工具类中直接加载就可以。

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web_test1
username=root
password=123456

编写工具类:


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

public class JDBCUtils {
    private static String driverClassName;
    private static String url;
    private static String username;
    private static  String password;

    static{
        Properties properties = new Properties() ;
        try {
            properties.load(new FileInputStream("src/db.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        driverClassName=properties.getProperty("driverClassName");
        url=properties.getProperty("url");
        username=properties.getProperty("username");
        password=properties.getProperty("password");
    }

    /**
     * 注册驱动的方法
     */
    public static void loadDriver(){
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得连接的方法
     */
    public static Connection getConnection(){
        Connection conn = null;
        try{
            // 将驱动一并注册:
            loadDriver();
            // 获得连接
            conn = DriverManager.getConnection(url,username, password);
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 释放资源的方法
     */
    public static void release(Statement stmt, Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }

    public static void release(ResultSet rs, Statement stmt, Connection conn){
        // 资源释放:
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            rs = null;
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

调用工具类进行测试:
 

import utils.JDBCUtils;

import java.sql.*;

public class JDBCDemo01 {
    public static void main(String[] args) {
        test() ;
    }

    private static void test()  {
        Connection conn = null ;
        Statement statement = null ;
        ResultSet rs = null ;
        try {
            conn = JDBCUtils.getConnection() ;
            statement = conn.createStatement();
            // 3.2编写SQL语句:

            String sql = "select * from user";
            // 3.3执行SQL
            rs = statement.executeQuery(sql);
            // 3.4遍历结果集:
            while (rs.next()) {
                System.out.print(rs.getInt("id") + " ");
                System.out.print(rs.getString("username") + " ");
                System.out.print(rs.getString("password") + " ");
                System.out.print(rs.getString("nickname") + " ");
                System.out.print(rs.getInt("age"));
                System.out.println();
            }
        }catch (Exception e){
            e.printStackTrace();

        }finally {
            JDBCUtils.release(rs,statement,conn);
        }

    }
}

4、JDBC的SQL注入问题及解决

在早期互联网上SQL注入漏洞普遍存在。有一个网站,用户需要进行注册,用户注册以后根据用户名和密码完成登录。假设现在用户名已经被其他人知道了,但是其他人不知道你的密码,也可以登录到网站上进行相应的操作。

  1. 输入用户名
    1. aaa’ or ‘1=1 密码随意
    2. aaa’ --      密码随意

使用的用户名和密码中带有SQL语句的关键字,使得不需要验证密码即实现登录的功能。

采用PreparedStatement对象解决SQL注入漏洞。这个对象将SQL预先进行编译,使用?作为占位符。?所代表内容是SQL所固定。再次传入变量(包含SQL的关键字)。这个时候也不会识别这些关键字,就可以避免SQL注入为问题发生。

5、JDBC的CRUD操作之PreparedStatement

使用PreparedStatement可以进行预编译SQL,后面不会识别输入的关键子,防止出现SQL注入问题,整个过程如下:首先连接数据库,编写SQL语句,预编译SQL,设置参数,并执行相应的DML操作,最后释放资源。


import utils.JDBCUtils;

import java.sql.*;

public class JDBCDemo01 {
    public static void main(String[] args) {
        test() ;
    }

    private static void test()  {
        Connection conn = null ;
        PreparedStatement statement = null ;
        ResultSet rs = null ;
        try {
            conn = JDBCUtils.getConnection() ;
            String sql1 = "insert into user values (null,?,?,?,?)";
            String sql2 = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";
            String sql3 = "delete from user where id = ?";
            String sql = "select * from user";
            // 插入操作
            statement = conn.prepareStatement(sql1);
            // 设置参数:
            statement.setString(1, "eee");
            statement.setString(2, "abc");
            statement.setString(3, "旺财");
            statement.setInt(4, 32);
            // 执行SQL
            int num = statement.executeUpdate();
            if(num > 0){
                System.out.println("插入成功!");
            }
            // 修改操作
            statement = conn.prepareStatement(sql2);
            // 设置参数:
            statement.setString(1, "abc");
            statement.setString(2, "1234");
            statement.setString(3, "旺旺");
            statement.setInt(4, 23);
            statement.setInt(5, 6);
            // 执行SQL:
            num = statement.executeUpdate();
            if(num > 0){
                System.out.println("修改成功!");
            }
            //删除操作
            statement = conn.prepareStatement(sql3);
            statement.setInt(1,4);
            num = statement.executeUpdate();
            if(num > 0){
                System.out.println("删除成功!");
            }

            //查询操作
            statement = conn.prepareStatement(sql);
            rs = statement.executeQuery(sql);
            // 3.4遍历结果集:
            while (rs.next()) {
                System.out.print(rs.getInt("id") + " ");
                System.out.print(rs.getString("username") + " ");
                System.out.print(rs.getString("password") + " ");
                System.out.print(rs.getString("nickname") + " ");
                System.out.print(rs.getInt("age"));
                System.out.println();
            }
        }catch (Exception e){
            e.printStackTrace();

        }finally {
            JDBCUtils.release(rs,statement,conn);
        }
    }
}

6、JBDC的事务管理

事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全都成功,要么全都失败。进行事务管理之前,我们先进行数据准备,创建一个数据库和表,并插入一些数据,具体如下:

create database if not exists web_test1;
use web_test1;
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
insert into account values (null,'aaa',10000);
insert into account values (null,'bbb',10000);
insert into account values (null,'ccc',10000);

事务管理常用的API包括开启事务,提交事务,事务回滚,具体如下:

通过下面的的转账案例学习JDBC的事务管理,首先开启事务,在整个事务执行过程中没有发生异常则提交事务,否则回滚事务到最初的状态。

import utils.JDBCUtils;

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

public class JDBCDemo02 {
    public static void main(String[] args) {
        demo1() ;
    }
    public static void demo1() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            /**
             * 完成转账代码:
             * * 扣除某个账号的钱
             * * 给另外一个账号加钱
             */
            // 获得连接:
            conn = JDBCUtils.getConnection();
            // 开启事务
            conn.setAutoCommit(false);
            // 编写SQL语句:
            String sql = "update account set money = money + ? where name = ?";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            // 设置参数:
            // 用aaa账号给bbb账号转1000元
            pstmt.setDouble(1, -1000);
            pstmt.setString(2, "aaa");
            // 执行SQL:扣除aaa账号1000元
            pstmt.executeUpdate();

            //int i = 1 / 0;

            // 给bbb账号加1000
            pstmt.setDouble(1, 1000);
            pstmt.setString(2, "bbb");
            pstmt.executeUpdate();

            // 提交事务:
            conn.commit();
        } catch (Exception e) {
            // 回滚事务:
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            JDBCUtils.release(pstmt, conn);
        }

    }
}

7、连接池之Druid与C3P0

连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。

我们先来看第一个连接池,Druid阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行快速整合。

首先需要引入连接数据库的jar包和连接池的jar包,具体如下:

下面从连接池中直接获得连接,编写SQL语句,预编译,然后进行查询操作,最后释放资源。

import com.alibaba.druid.pool.DruidDataSource;
import utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class JDBCDemo02 {
    public static void main(String[] args) {
        demo1() ;
    }
    public static void demo1(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            // 使用连接池:
            DruidDataSource dataSource = new DruidDataSource();
            // 手动设置数据库连接的参数:
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql:///web_test1");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");
            // 获得连接:
//			conn = JDBCUtils.getConnection();
            conn = dataSource.getConnection();
            // 编写SQL:
            String sql = "select * from account";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            // 设置参数:
            // 执行SQL:
            rs = pstmt.executeQuery();
            while(rs.next()){
                System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(rs, pstmt, conn);
        }
    }

}

 上面的连接池案例是使用手动配置MySQL参数的方法,我们将配置参数卸载.properties文件中,通过加载配置文件的方式获取配置参数,具体如下:

import com.alibaba.druid.pool.DruidDataSourceFactory;
import utils.JDBCUtils;

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 JDBCDemo02 {
    public static void main(String[] args) {
        demo1() ;
    }
    public static void demo1(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{

            // 配置文件的方式获取配置参数
            Properties properties = new Properties();
            properties.load(new FileInputStream("src/db.properties"));
            DataSource dataSource =  DruidDataSourceFactory.createDataSource(properties);

            // 获得连接:
            conn = dataSource.getConnection();
            // 编写SQL:
            String sql = "select * from account";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            // 设置参数:
            // 执行SQL:
            rs = pstmt.executeQuery();
            while(rs.next()){
                System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(rs, pstmt, conn);
        }
    }
}

我们下面学习另外一个开源的连接池C3P0,首先我们需要导入相关jar包,具体如下:

 首先我们使用手动设置MySQL参数的方式使用C3P0连接池,首先创建连接,设置参数,然后从连接池获得连接,后面就可以写SQL语句,预编译并执行查询操作了,具体如下:

import com.mchange.v2.c3p0.ComboPooledDataSource;
import utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JDBCDemo02 {
    public static void main(String[] args) {
        demo1() ;
    }
    public static void demo1(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            // 创建连接池:
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            // 设置连接参数:
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql:///web_test1");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            // 从连接池中获得连接:
            conn = dataSource.getConnection();
            // 编写SQL:
            String sql = "select * from account";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            // 执行SQL:
            rs = pstmt.executeQuery();
            while(rs.next()){
                System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(rs, pstmt, conn);
        }
    }
}

下面将数据库的参数配置在c3p0-config.xml文件中,这样会自动加载配置,不粗要在程序中设置数据库的配置信息,具体如下,包含两种配置,一种是默认配置,另外一种是带名称参数的配置。

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 这是默认配置信息 -->
    <default-config>
        <!-- 连接四大参数配置 -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/web_test1?useUnicode=true&amp;characterEncoding=utf-8</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 池参数配置 -->
        <property name="acquireIncrement">3</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">2</property>
        <property name="maxPoolSize">10</property>
    </default-config>

    <named-config name="otherConfig">
        <!-- 连接四大参数配置 -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/web_test1?useUnicode=true&amp;characterEncoding=utf-8</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 池参数配置 -->
        <property name="acquireIncrement">3</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">2</property>
        <property name="maxPoolSize">10</property>
    </named-config>

</c3p0-config>

加载配置文件并从连接池获得连接,然后编写SQL语句,预编译并执行查询操作的代码如下:

import com.mchange.v2.c3p0.ComboPooledDataSource;
import utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JDBCDemo02 {
    public static void main(String[] args) {
        demo1() ;
    }
    public static void demo1(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            // 创建连接池:
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            // 从连接池中获得连接:
            conn = dataSource.getConnection();
            // 编写SQL:
            String sql = "select * from account";
            // 预编译SQL:
            pstmt = conn.prepareStatement(sql);
            // 执行SQL:
            rs = pstmt.executeQuery();
            while(rs.next()){
                System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            JDBCUtils.release(rs, pstmt, conn);
        }
    }
}

8、JDBC之改写工具类

之前的工具类是使用传统的方式获得连接,现在直接在工具类中创建连接,每次直接使用即可,不用重复创建,具体如下:

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.*;

public class JDBCUtils02 {
    private static final ComboPooledDataSource datasource = new ComboPooledDataSource() ;
    
    public  static DataSource getDataSource(){
        return datasource ;
    }

    public static Connection getConnection(){
        Connection conn = null;
        try{
            conn = datasource.getConnection() ;
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
    }

    public static void release(Statement stmt, Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }

    public static void release(ResultSet rs, Statement stmt, Connection conn){
        // 资源释放:
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            rs = null;
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

            stmt = null;
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

9、DBUtils的学习之CRUD操作

DBUtils是Apache提供的一个对JDBC进行简单封装的工具类,可以简化JDBC应用的开发。JDBC手写比较麻烦,而且有非常多的代码是类似的。比如获得连接,预编译SQL,释放资源等..那么可以将这些代码抽取出来放到工具类中。将类似的代码进行抽取。大大简化JDBC的编程。

它的核心运行类对象是QueryRunner对象,该对象有一些常用的API

 通过QueryRunner核心运行类是西安CRUD操作,不需要预编译之类的,当然这个也需要导入相关jar包,代码具体如下:

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DBUtils {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {

        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource());
        //添加操作
        queryRunner.update("insert into account values (null,?,?)", "ddd",10000);
        //修改操作
        queryRunner.update("update account set name=?,money=? where id =?", "eee",20000,4);
        //删除操作
        queryRunner.update("delete from account where id = ?", 3);
        //查询一条记录的操作
        Account account = queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>() {
            @Override
            public Account handle(ResultSet resultSet) throws SQLException {
                Account account = new Account() ;
                while(resultSet.next()){
                    account.setId(resultSet.getInt("id"));
                    account.setName(resultSet.getString("name"));
                    account.setMoney(resultSet.getDouble("money"));
                }
                return account ;
            }
        }, 1) ;

        System.out.println(account);

        //查询多条语句
        List<Account> list = queryRunner.query("select * from account", new ResultSetHandler<List<Account>>() {
            @Override
            public List<Account> handle(ResultSet resultSet) throws SQLException {
                List<Account> list = new ArrayList<>();
                while(resultSet.next()){
                    Account account = new Account() ;
                    account.setId(resultSet.getInt("id"));
                    account.setName(resultSet.getString("name"));
                    account.setMoney(resultSet.getDouble("money"));
                    list.add(account) ;
                }
                return list ;
            }
        }) ;

        for(Account account1 : list){
            System.out.println(account1);
        }

    }
}

10、DBUtils使用之ResultSetHandler实现类

1)ArrayHandler和ArrayListHandler

一条记录封装到一个数组当中。这个数组应该是Object[]

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;

import java.sql.SQLException;
import java.util.Arrays;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        Object [] objects = queryRunner.query("select * from account where id = ?",new ArrayHandler(),1) ;
        System.out.println(Arrays.toString(objects));
    }
}

将多条记录封装到一个装有Object[]的List集合中。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        List<Object[]> list = queryRunner.query("select * from account ",new ArrayListHandler()) ;
        for(Object [] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
    }
}

2)BeanHandlerBeanListHandler

将一条记录封装到一个JavaBean中。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import java.sql.SQLException;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        Account account = queryRunner.query("select * from account where id = ?",new BeanHandler<Account>(Account.class),1) ;
        System.out.println(account);
    }
}

将多条记录封装到一个装有JavaBean的List集合中。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        List<Account> account = queryRunner.query("select * from account",new BeanListHandler<Account>(Account.class)) ;
        for(Account account1 : account){
            System.out.println(account1);
        }
    }
}

3)MapHandler和MapListHandler

将一条记录封装到一个Map集合中,Map的key是列名,Map的value就是表中列的记录值。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import java.sql.SQLException;
import java.util.Map;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        Map<String,Object> map = queryRunner.query("select * from account where id = ?",new MapHandler(),1) ;
        System.out.println(map);
    }
}

将多条记录封装到一个装有Map的List集合中。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        List<Map<String,Object>> list = queryRunner.query("select * from account",new MapListHandler()) ;
        for(Map map : list){
            System.out.println(map);
        }
    }
}

4)ColumnListHandler、ScalarHandler

将数据中的某列封装到List集合中。

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import java.sql.SQLException;
import java.util.List;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        List<Object> list = queryRunner.query("select * from account",new ColumnListHandler("name")) ;
        for(Object object : list){
            System.out.println(object);
        }
    }
}

将单个值封装。


import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.SQLException;

public class DBUtils02 {
    public static void main(String[] args) throws SQLException {
        test() ;
    }

    private static void test() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils02.getDataSource()) ;
        Object object = queryRunner.query("select count(*) from account",new ScalarHandler()) ;
        System.out.println(object);
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值