JDBC连接数据库详讲

1.JDBC概述

JDBC连接数据库详讲_第1张图片

1.1 JDBC

JDBC(Java DataBase Connectivity),简单来讲JDBC是利用Java语言或程序连接并且访问数据库的一门技术,是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,提供了查询和更新数据库操作方法,通常是面向关系型数据库的。这种方法摒弃了原先通过CMD挥着Navicat等工具连接数据库的方式。

1.2 访问数据库步骤

1.注册驱动

  • 2.获取连接
  • 3.获取传输器
  • 4.通过传输器发送SQL到服务器质性并且返回执行结果
  • 5.数据处理
  • 6.释放资源
1.3 原理

每次需要访问数据时就和数据库建立连接,操作,返回结果,关闭。需要走完整的六个步骤。

2.通过JDBC访问数据库

2.1准备数据
--本机环境:win7,mysql(8.0.15)
set names utf8;
drop database if exists testjdbc_db;
create database testjdbc_db charset utf8;
use testjdbc_db;
create table account(
    id int primary key auto_increment,
    name varchar(50),
    money double
);
insert into account values(null, 'tom', 1000);
insert into account values(null, 'andy', 1000);
insert into account values(null, 'tony', 1000);
2.2 创建项目导入驱动包

注:导入MySQL驱动包,下载地址https://dev.mysql.com/downloads/mysql/
JDBC连接数据库详讲_第2张图片

JDBC连接数据库详讲_第3张图片

JDBC连接数据库详讲_第4张图片

2.3 代码实现
package com.MTngCat.Person.JDBC.Connection;

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

/**
 * JDBC连接数据库的步骤:
 * @author MTing
 * 步骤:
 *         1.注册驱动
 *         2.获取连接
 *        3.获取传输器
 *        4.通过传输器发送SQL到服务器质性并且返回执行结果
 *        5.数据处理
 *        6.释放资源
 */
public class connectionBasic {
    
    public static void main(String[] args) throws Exception {
        
        //1.注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.获取连接
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/testjdbc_db?characterEncoding=UTF-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true",
                "root",
                "MTingCat819"
                );
        //3.获取传输器
        Statement st = conn.createStatement();
        //4.通过传输器发送SQL到服务器执行并且返回执行结果
        String sql = "select * from account";
        ResultSet rs = st.executeQuery(sql);
        //5.数据处理
        while( rs.next() ) {
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");
            System.out.println(id + ":" + name + ":" + money );
        }
        //6.释放资源
//        rs.close();
//        st.close();
//        conn.close();
        if( rs != null ) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( st != null ) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                st = null;
            }
        }
        if( conn != null ) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
    
}


2.4 代码注意事项详注:
//1.注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

①MySQL版本在8.0之前的驱动的全限定类名是"com.mysql.jdbc.Driver"
②MySQL版本在8.0之后的驱动的全限定类名是"com.mydql.cj.jdbc.Driver"

    //2.获取连接
    Connection conn = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/testjdbc_db?characterEncoding=UTF-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true", 
            "root",
            "MTingCat819"
            );

①参数一:jdbc:mysql://localhost:3306/testjdbc_db
JDBC连接数据库详讲_第5张图片
用于指定访问的是哪一个数据库,如果连接本地数据库,可以简写为:jdbc:mysql:///testjdbc_db
②参数二:characterEncoding=UTF-8&serverTimezone=GMT%2B8"
这里指定的是编码格式和时区,MySQL驱动8.0之后的版本都需要自己配置时区。
③参数三:useServerPrepStms=true
保证MySQL驱动会把以连接器PreparedStatement类型传输来的SQL语句发送给数据库进行预编译为函数交给服务器存储key。
④参数四:cachePrepStms=true
保证在执行相同的语句时数据库不会进行二次编译,原因保证在第一次预编译为函数后的key值存在于服务器
⑤参数五:
⑥参数六:

  //3.获取传输器
  Statement st = conn.createStatement();

该方法用于向数据库服务器发送SQL语句的Statement传输对象。

//4.通过传输器发送SQL到服务器质性并且返回执行结果
        String sql = "select * from account";
        ResultSet rs = st.executeQuery(sql);
        //用于向数据库发送查询类型的sql语句,返回一个ResultSet对象结果集
        //int rows = st.executeUpdate(sql)
        //用于向数据库发送更新(增加、删除、修改)类型的sql语句,返回一个int值,表示影响的记录行数

①ResultSet结果集对象:用于封装SQL语句查询的结果,该对象提供了遍历数据以及获取数据的方法。

//5.数据处理
        while( rs.next() ) {
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");
            System.out.println(id + ":" + name + ":" + money );
        }

①遍历数据行的方法:next()使指向数据行的箭头向下移动一行,并且返回一个布尔类型的结果,后面有数据组则返回true,发欧泽false
②获取数据的方法

getInt(int columnIndex)
getInt(String columnLable)
getString(int columnIndex)
getString(String columnLable)
getDouble(int columnIndex)
getDouble(String columnLable)
getObject(int columnIndex)
getObject(String columnLable)
//6.释放资源
        rs.close();
        st.close();
        conn.close();

①释放资源:越晚获取的资源越先关闭
②为避免程序抛出异常释放资源的代码不会执行,应该把代码放在finally块中

if( rs != null ) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( st != null ) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                st = null;
            }
        }
        if( conn != null ) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
2.5 执行结果

JDBC连接数据库详讲_第6张图片

3.通过JDBC实现对数据库的操作

3.1 简化代码:数据库注册工具类

由于每次访问数据库都要走完整的六个步骤,也就是说每次对数据库操作都要写一系列的代码,所以我们编写数据库注册工具类进行简化代码。

package com.MTngCat.Person.JDBC.JDBCUtil;

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

/**
 * 创建jdbc工具类简化代码
 * @author MTing
 *    本质:
 *        注册驱动 + 获取连接
 */
public class JdbcUtil {
    public static Connection getConnection() {
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取数据库连接
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql:///testjdbc_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true",
                    "root",
                    "MTingCat819"
                    );
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Connection getConnection(String dbName,String user, String password) {
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取数据库连接
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql:///"+ dbName + "characterEncoding=utf-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true",
                    user,
                    password
                    );
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void close(Connection conn, Statement stat, ResultSet rs) {
        if( conn != null ) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
            if( stat != null ) {
                try {
                    stat.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    stat = null;
                }
            }
            if( rs != null ) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    rs = null;
                }
            }
        }
        
    }
}
3.2 测试代码
package com.MTngCat.Person.JDBC.Connection;

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

import java.sql.Statement;

import org.junit.Test;

import com.MTngCat.Person.JDBC.JDBCUtil.JdbcUtil;

/**
 * 通过JDBC工具类连接数据库
 * @author MTing
 *
 */
public class testJdbcUtil {
    
    //1.查询所有数据
    @Test
    public void testSelect() {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取连接
            stat = conn.createStatement();
            //4.通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "select * from account";
            rs = stat.executeQuery(sql);
            //5.处理结果
            while( rs.next() ) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                double money = rs.getDouble("money");
                System.out.println(id + ":" + name + ":" + money );
            }
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,stat,rs);
        }
    }
    //2.插入数据:Anny 4000
    @Test
    public void testInsert() {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取连接
            stat = conn.createStatement();
            //4.通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "insert into account values(null,'Anny',4000)";
            int rows = stat.executeUpdate(sql);
            //5.处理结果
            System.out.println("影响的行数是:" + rows);
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,stat,rs);
        }
    }
     
    //3.修改数据:Anny 4000->4800
    @Test
    public void testUpdate() {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取连接
            stat = conn.createStatement();
            //4.通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "update account set money = 4800 where name = 'Anny'";
            int rows = stat.executeUpdate(sql);
            //5.处理结果
            System.out.println("影响的行数是:" + rows);
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,stat,rs);
        }
    }
    
    //4.删除数据:Anny
    @Test
    public void testDelete() {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取连接
            stat = conn.createStatement();
            //4.通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "delete from account where name = 'Anny'";
            int rows = stat.executeUpdate(sql);
            //5.处理结果
            System.out.println("影响的行数是:" + rows);
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,stat,rs);
        }
    }
    
}

①单元测试:不用创建新的类,也不用提供main方法,也不用创建实例,就可以直接执行的方法,添加@Test注解就可以通过单元测试(Junit)框架测试该方法,框架会创建该方法的实例,通过实例调用该方法。,满足单元测试方法的几个条件:
a.方法必须是公共的
b.方法必须是非静态的
c.方法必须是无返回值的
d.方法必须是无参数的
e.方法可以抛出异常
f.进行单元测试的方法或者类,命名时不要命名为 Test/test

5.Statement和PreparedStatement区别

5.1 概述

简单PreparedStatement是Statement子类接口,比Statement更加安全,并且能够提高执行效率。

5.2 原理

底层中Statement在执行语句时,是直接将语句发送给数据库进行编译,正确则执行,错误抛出异常,即每一次的对数据库的操作都被认为是新的操作,而且传递的参数也是以拼接的方式,效率低下,线程不安全。
PreparedStatement在执行SQL语句时,先将SQL语句交个数据库进行预编译,错误抛出异常,正确生成骨架即函数,用户只需要传递参数即可,提高了执行效率,线程安全。

6.SQL注入攻击(深度理解Statement和PreparedStatement)

6.1 准备数据
use testjdbc_db;
create table user(
    id int primary key auto_increment,
    username varchar(50),
    password varchar(50)
);
insert into user values(null,'MTing','123');
insert into user values(null,'Cat','234');

JDBC连接数据库详讲_第7张图片

6.2 创建登录类,提供登录方法
package com.MTngCat.Person.JDBC.PS;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

import com.MTngCat.Person.JDBC.JDBCUtil.JdbcUtil;

public class loginUser {
    public static void main(String[] args) {
        
        @SuppressWarnings("resource")
        Scanner sc = new Scanner( System.in );
        System.out.println("欢迎登录!");
        System.out.println("请输入用户名称:");
        String user = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        login( user, password );
    }
    private static void login( String user, String password ) {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取连接
            stat = conn.createStatement();
            //4.通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "select * from user where username='"+ user + "'and password = '"+ password +"'";
            rs = stat.executeQuery(sql);
            //5.处理结果
            System.out.println( sql );
            if( rs.next() ) { //有数据 -- 用户名密码都正确
                System.out.println("登录成功!");
            }else { //没数据 -- 用户名或密码不正确
                System.out.println("登录失败, 用户名或密码不正确!");
            }
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,stat,rs);
        }
    }

}

JDBC连接数据库详讲_第8张图片

6.3 测试登录方法
6.3.1 异常

JDBC连接数据库详讲_第9张图片

6.3.2 异常

JDBC连接数据库详讲_第10张图片

6.3.3 异常

JDBC连接数据库详讲_第11张图片

6.3.4 正常

JDBC连接数据库详讲_第12张图片

6.3.4 SQL注入攻击

从以上的异常中不难看出,在不按照正常的输入的情况下依旧能登录成功,这就是SQL注入攻击,原因:执行查询的SQL语句是拼接而来的

String sql = "select * from user where username='"+ user + "'and password = '"+ password +"'"

其中的参数是用户端提交过来的,按照这种方式,用户在提交数据时如果掺杂特殊符号等,会导致SQL语句的语义发生变化,从而执行一些意外的操作

7.如何防止SQL注入攻击

7.1 正则表达式

通过正则表达式的方式对用户提交的数据进行验证,如果用户提交注入特殊符号等的不合法数据,提示用户重新输入。

7.2 使用PreparedStatement对象替换Statement

本质:增加SQL预编译生成骨架,保证语义的准确性不会发生改变。

7.2.1代码
package com.MTngCat.Person.JDBC.PS;

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

import com.MTngCat.Person.JDBC.JDBCUtil.JdbcUtil;

public class loginUser2 {
    public static void main(String[] args) {
        
        @SuppressWarnings("resource")
        Scanner sc = new Scanner( System.in );
        System.out.println("欢迎登录!");
        System.out.println("请输入用户名称:");
        String user = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        login( user, password );
    }
    private static void login( String user, String password ) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.注册驱动,2.获取连接
            conn = JdbcUtil.getConnection();
            //3.获取传输器,通过传输器发送SQL语句到服务器执行并返回结果
            String sql = "select * from user where username = ? and password = ?";
            ps = conn.prepareStatement(sql);
            //4.设置SQL语句中的参数
            ps.setString(1, user);
            ps.setString(2, password);
            //5.执行SQL语句
            rs = ps.executeQuery();
            //5.处理结果
            System.out.println( sql );
            if( rs.next() ) { //有数据 -- 用户名密码都正确
                System.out.println("登录成功!");
            }else { //没数据 -- 用户名或密码不正确
                System.out.println("登录失败, 用户名或密码不正确!");
            }
            //6.关闭连接,释放资源
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn,ps,rs);
        }
    }

}

JDBC连接数据库详讲_第13张图片

7.2.2 测试登录方法
7.2.2.1 无异常
7.2.2.2 正常

JDBC连接数据库详讲_第14张图片

JDBC连接数据库详讲_第15张图片

JDBC连接数据库详讲_第16张图片

7.连接池的应用

1. 概念引入

在上面所讲连接中,每次访问数据库都会创建一个连接,初始化连接,关闭连接,会走访问数据库的所有操作,由于每次创建初始化连接和关闭连接会花费大量的时间,会导致整个程序效率低下,因此为解决在访问数据库时要不断的初始化连接和关闭连接带来的时间消耗问题,我们采取了连接池的方式

2.何为连接池

池即容器,连接池顾名思义是能够存储有很多连接的容器,在程序启动时我们第一次访问数据库,就会在连接池中创建一个连接,首次创建的连接进行初始化也会花费很多的时间,但是当用完这个连接执行*.close()方法的时候,不再是关闭连接,而是把连接送回到连接池中,下次需要访问数据库的时候,直接从连接池中取出第一次用完放回的连接对象,不需要再次初始化,用完放回连接池,即也不需要关闭连接,解决的访问数据库时初始化连接和关闭连接耗时长的问题---预见问题出现的点,并且避开问题寻求捷径的思想是连接池的主要思想

JDBC连接数据库详讲_第17张图片

3.代码实现
3.1 导包 build path

JDBC连接数据库详讲_第18张图片

3.2代码实现
3.2.1 通过静态代码块获取连接
//2.创建一个连接池对象
    static ComboPooledDataSource pool = new ComboPooledDataSource();
    //3.设置连接池的基本信息(方式一)
    static {
        try {
            pool.setDriverClass("com.mysql.cj.jdbc.Driver");
            pool.setJdbcUrl("jdbc:mysql:///testjdbc_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true");
            pool.setUser("root");
            pool.setPassword("MTingCat819");
        }catch (Exception e) {
            e.printStackTrace();
        }    
    }
package com.MTngCat.Person.JDBC.C3P0;

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

import org.junit.Test;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 测试C3P0连接池的使用
 *    1.导入C3P0jar包
 *    2.在程序中创建一个连接池(容器:里面会放一批连接)
 *     3.设置连接数据的基本信息(驱动类的全路径,连接库的URL地址,连接库的用户名和密码)
 *        3.1直接将连接数据库的参数写死在程序中,使得代码不灵活
 *        3.2将连接数据库的基本信息配置在c3p0.properties文件,文件放在类目录下,即src根目录下    
 *        3.3将连接数据库的基本信息配置在池c3p0-config.xml中,文件放在类目录下。
 *        3.2和3.3中的文件名和文件的配置信息都是固定的
 *4.从链接池中获取一个连接使用
 * @author MTing
 *
 */
public class testC3P0 {

    //2.创建一个连接池对象
    static ComboPooledDataSource pool = new ComboPooledDataSource();
    //3.设置连接池的基本信息(方式一)
    static {
        try {
            pool.setDriverClass("com.mysql.cj.jdbc.Driver");
            pool.setJdbcUrl("jdbc:mysql:///testjdbc_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true");
            pool.setUser("root");
            pool.setPassword("MTingCat819");
        }catch (Exception e) {
            e.printStackTrace();
        }    
    }
    //查询表中所有的信息
    @Test
    public void testFindAll() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
    @Test
    public void testFindAll02() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
    //查询MTing
    @Test
    public void testOne() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user where username = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ps.setString(1, "MTing");
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
}
3.2.2 通过配置文件获取连接(c3p0.properties)
# key=value
c3p0.driverClass=com.mysql.cj.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///testjdbc_db?characterEncoding=UTF-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true
c3p0.user=root
c3p0.password=MTingCat819
3.2.3 通过配置文件获取连接(c3p0-config.xml)


    
        
            com.mysql.cj.jdbc.Driver
        
        
            jdbc:mysql:///testjdbc_db?characterEncoding=UTF-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true
        
        
            root
        
        
            MTingCat819
        
    
package com.MTngCat.Person.JDBC.C3P0;

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

import org.junit.Test;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 测试C3P0连接池的使用
 *    1.导入C3P0jar包
 *    2.在程序中创建一个连接池(容器:里面会放一批连接)
 *     3.设置连接数据的基本信息(驱动类的全路径,连接库的URL地址,连接库的用户名和密码)
 *        3.1直接将连接数据库的参数写死在程序中,使得代码不灵活
 *        3.2将连接数据库的基本信息配置在c3p0.properties文件,文件放在类目录下,即src根目录下    
 *        3.3将连接数据库的基本信息配置在池c3p0-config.xml中,文件放在类目录下。
 *        3.2和3.3中的文件名和文件的配置信息都是固定的
 *4.从链接池中获取一个连接使用
 * @author MTing
 *
 */
public class testC3P001 {

    //2.创建一个连接池对象
    ComboPooledDataSource pool = new ComboPooledDataSource();
    //3.设置连接池的基本信息(方式一)
//    static {
//        try {
//            pool.setDriverClass("com.mysql.cj.jdbc.Driver");
//            pool.setJdbcUrl("jdbc:mysql:///testjdbc_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&useServerPrepStms=true&cachePrepStms=true");
//            pool.setUser("root");
//            pool.setPassword("MTingCat819");
//        }catch (Exception e) {
//            e.printStackTrace();
//        }    
//    }
    //查询表中所有的信息
    @Test
    public void testFindAll() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
    @Test
    public void testFindAll02() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
    //查询MTing
    @Test
    public void testOne() throws SQLException {
        
        //4.初始化一个连接对象
        Connection conn = pool.getConnection();
        //5.编写SQL,获取连接器
        String sql = "select * from user where username = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        //6.执行操作返回查询对象
        ps.setString(1, "MTing");
        ResultSet rs = ps.executeQuery();
        //7.处理结果
        while( rs.next() ) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id + " " + username + " " + password);
            System.out.println(pool.getClass().getName());
        }
        //8.关闭连接
        if( rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if( ps != null) {
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                ps = null;
            }
        }
        if( conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }
}

你可能感兴趣的:(java,mysql,jdbc,c3p0)