JDBC

JDBC

1. 数据库驱动

驱动:声卡,显卡,数据库

graph TB id1[应用程序] --> id2[MySQL驱动] id1 --> id3[Oracle驱动] id2 --> id4[数据库] subgraph 数据库厂商 id2 id3 end id3 --> id4

我们的程序会通过数据库驱动,和数据库打交道

2. JDBC

SUN公司为了简化开发人员对数据库的统一操作,提供了一个JAVA操作数据库的规范,俗称JDBC

这些规范的实现由具体的厂商去做

对于开发人员来说,我们只需要掌握JDBC的接口操作即可!

graph TB id1[应用程序] --> id2[JDBC] id2 --> id3[MySQL驱动] id2 --> id4[Oracle驱动] id3 --> id5[数据库] id4 --> id5 subgraph 开发人员 id2 end subgraph 数据库厂商 id3 id4 end

java.sql

javax.sql

还需要导入一个数据库驱动包 mysql-connector-java-5.1.48.jar

3. 第一个JDBC程序

  1. 创建测试数据库

    create database jdbcStudy character set utf8 collate utf8_general_ci;
    
    use jdbcStudy;
    
    create table `users`(
    id int primary key,
    name varchar(40),
    password varchar(40),
    email varchar(60),
    birthday date
    );
    
    insert into `users`(id,name,password,email,birthday)
    values(1,'zhansan','123456','zs@sina.com','1980-12-04'),
    (2,'lisi','123456','lisi@sina.com','1981-12-04'),
    (3,'wangwu','123456','wangwu@sina.com','1979-12-04')
    
  2. 创建一个普通项目

  3. 导入数据库驱动

    注意,创建lib目录并复制jar包后,需要进行以下的操作才能导入!

    img

  4. 编写测试代码

package com.wang.lesson01;

import java.sql.*;

//我的第一个jdbc程序
public class jdbcFirstDemon01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");     //固定写法,加载驱动

        //2.用户信息和URL
        //URL ?前的内容是jdbc:使用的数据库厂商://主机名:端口号/数据库的名称
        //URL ?后的内容 useUnicode=true&characterEncoding=utf8&useSSL=true
        //第一个参数:使用unicode编码,可以显示中文
        //第二个参数:设定字符集为utf-8
        //第三个参数:使用安全的的连接
        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String password = "123456";

        //3.连接成功,数据库对象 Connection代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);   //al + enter

        //4.执行SQL的对象 Statement执行SQL的对象
        Statement statement = connection.createStatement();

        //5.执行SQL的对象 去执行SQL,可能存在结果,返回查看结果
        

        ResultSet resultSet = statement.executeQuery(sql);  //返回的结果集,结果集中封装了我们全部查询出来的结果

        while (resultSet.next()) {
            System.out.println(("id=" + resultSet.getObject("id")));
            System.out.println(("name=" + resultSet.getObject("name")));
            System.out.println(("password=" + resultSet.getObject("password")));
            System.out.println(("email=" + resultSet.getObject("email")));
            System.out.println(("birthday=" + resultSet.getObject("birthday")));
            System.out.println("====================================");
        }

        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

步骤总结:

  1. 加载驱动

  2. 连接数据库DriverManager

  3. 获得自信sql的对象 Statement

  4. 获得返回的结果集

  5. 释放连接

4. DriveManager

//建议写第二种写法
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");     //固定写法,加载驱动

//Connection代表数据库
Connection connection = DriverManager.getConnection(url, username, password); 
//数据库设置自动提交
connection.setAutoCommit();
//事务提交
connection.commit();
//事务回滚
connection.rollback();

5. URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy?
    useUnicode=true&characterEncoding=utf8&useSSL=true";

//mysql默认port 3306
//协议://主机地址:端口号/数据库名?参数1&参数2&参数3    

//orale默认端口1521
//jdbc:oracle:thin:@localhost:1521:sid    

6. Statement

执行SQL的对象

String sql = "select * from users";	//编写SQL

statement.executeQuery();   //查询操作 返回ResultSet
statement.execute();        //执行任何SQL
statement.executeUpdate();  //更新,插入,删除都是用这个,返回一个受影响的行数

jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。

Statement对象的executeUpdate方法,用于向数据库发送增、删。改的SQL语句,executeUpdate执行完后,将会返回一个整数(级增删改语句导致了数据库几行数据发生了变化)。

Statement。executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象

1. CRUD操作-create

使用executeUpdate(String sql)完成数据添加的操作

Statement st = conn.createStatement();
String sql = "insert into user (`XXX`,`XXX`,...) values (XXX,XXX,...)";
int num = st.executeUpdate(sql);
if(num > 0) {
    System.out.println("insert successfully!");		//如果受影响的行数大于1,则说明插入成功
}

2. CRUD操作-delete

使用executeUpdate(String sql)方法完成数据删除操作

Statement st = conn.createStatement();
String sql = "delete from user where id = 1";
int num = st.executeUpdate(sql);
if(num > 0) {
    System.out.println("delete successfully!");		//如果受影响的行数大于1,则说明删除成功
}

3. CRUD操作-update

使用executeUpdate(String sql)方法完成数据修改操作

Statement st = conn.createStatement();
String sql = "update user set name = '' where name = ''";
int num = st.executeUpdate(sql);
if(num > 0) {
    System.out.println("delete successfully!");		//如果受影响的行数大于1,则说明更新成功
}

4. CRUD操作-read

使用executeQuery(String sql)方法完成数据查询操作

Statement st = conn.createStatement();
String sql = "select * from user where id = 1";
ResultSet rs = st.executeQuery(sql);
while(re.next()) {
    //根据获取列的数据类型,分别调用rs的相应方法映射到Java对象中
}

5. 代码实现

1. 提取工具类

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username = root
password = 123456
package com.wang.lesson02.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {

    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //1.驱动只用加载一次
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }


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

        if (st != null) {
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

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

2. 编写增删改的方法,使用executeUpdate方法

package com.wang.lesson02;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestInsert {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();  //获取数据库连接
            st = conn.createStatement();      //获得sql的执行对象
            String sql = "insert into users(id,`name`,`password`,`email`,`birthday`)"
                    + "values(4,'wang','123456','123456789@qq.com','2020-01-01')";

            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("插入成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {

            JdbcUtils.release(conn, st, rs);
        }
    }
}
package com.wang.lesson02;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestDelete {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();  //获取数据库连接
            st = conn.createStatement();      //获得sql的执行对象
            String sql = "delete from `users` where id = 1";

            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("删除成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {

            JdbcUtils.release(conn, st, rs);
        }
    }
}
package com.wang.lesson02;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestUpdate {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();  //获取数据库连接
            st = conn.createStatement();      //获得sql的执行对象
            String sql = "update users set `name` = 'wang_sky' where id = 4";

            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("更新成功!");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {

            JdbcUtils.release(conn, st, rs);
        }
    }
}

4. 查询

package com.wang.lesson02;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestSelect {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();  //获取数据库连接
            st = conn.createStatement();      //获得sql的执行对象
            String sql = "select * from users where id = 2";

            rs = st.executeQuery(sql);  //查询完毕会返回一个结果集

            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {

            JdbcUtils.release(conn, st, rs);
        }
    }
}

7. ResultSet

查询的结果集:封装了所有的查询结果

获得指定的数据类型

resultSet.getObject();  //在不知道列类型的情况下使用
//如果知道列的类型就使用指定的类型
resultSet.getString();  
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();
...

遍历,指针

resultSet.beforeFirst();    //移动到最前面
resultSet.afterLast();      //移动到最后面
resultSet.next();           //移动到下一个数据
resultSet.previous();       //移动到前一行
resultSet.absolute(row);    //移动到指定行(row)

8. 释放资源

//6.释放连接
resultSet.close();
statement.close();
connection.close();		//耗资源,用完关掉

9. SQL注入的问题

sql存在漏洞,会被攻击导致数据泄露

本质:SQL会被拼接or

package com.wang.lesson02;

import com.wang.lesson02.utils.JdbcUtils;

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

public class SQLInject {
    public static void main(String[] args) {
        //login("lisi", "123456");
        login(" 'or '1=1", "' or '1=1");
    }

    //登陆业务
    public static void login(String username, String password) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();

            //SQL
            //select * from users where `name` = 'lisi' and `password` = '123456';
            //select * from users where `name` = '' or '1=1' and `password` = '' or '1 = 1';
            //上面语句中'' or '1 = 1'为null 或 true,保证永远为真
            String sql = "select * from users where `name` = '"
                    + username + "' and `password` = '" + password
                    + "'";

            rs = st.executeQuery(sql);

            while (rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("password"));
                System.out.println("=========================");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }
}

10. PreparedStatement对象

可以防止SQL注入,并且效率更高!

1. insert

package com.wang.lesson03;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();

            //区别
            //使用?占位符代替参数
            String sql = "insert into users(id,`name`,`password`,`email`,`birthday`) values(?, ?, ?, ?, ?)";

            st = conn.prepareStatement(sql);   //预编译SQL:先写SQL,不执行

            //手动给参数赋值
            st.setInt(1, 5);
            st.setString(2, "wang");
            st.setString(3, "456789");
            st.setString(4, "456789@qq.com");
            //注意点:sql.Date   SQL     java.sql.Date()传入时间戳获得SQL的Date
            //      util.Date   Java    new Date().getTime()获得时间戳
            st.setDate(5, new java.sql.Date(new Date().getTime()));

            //执行
            int i = st.executeUpdate();
            if (i >0)
                System.out.println("插入成功!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }
    }
}

2. delete

package com.wang.lesson03;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestDelete {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();

            //区别
            //使用?占位符代替参数
            String sql = "delete from users where `id` = ?";

            st = conn.prepareStatement(sql);   //预编译SQL:先写SQL,不执行

            //手动给参数赋值
            st.setInt(1, 5);

            //执行
            int i = st.executeUpdate();
            if (i >0)
                System.out.println("删除成功!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }
    }
}

3. update

package com.wang.lesson03;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestUpdate {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();

            //区别
            //使用?占位符代替参数
            String sql = "update users set `name` = ? where `name` = ?;";

            st = conn.prepareStatement(sql);   //预编译SQL:先写SQL,不执行

            //手动给参数赋值
            st.setString(1, "wang");
            st.setString(2, "wang_sky");

            //执行
            int i = st.executeUpdate();
            if (i >0)
                System.out.println("更新成功!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }
    }
}

4. select

package com.wang.lesson03;

import com.wang.lesson02.utils.JdbcUtils;

import java.sql.*;

public class TestSelect {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();

            String sql = "SELECT * from users where `id` = ?";

            st = conn.prepareStatement(sql);

            st.setInt(1, 2);    //传递参数

            rs = st.executeQuery();

            if (rs.next()) {
                System.out.println(rs.getString("name"));
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }
}

5. PreparedStatement防止SQL注入的本质

把传递进来的参数当做字符

假设其中存在转义字符,比如说 ' 会被直接转义

11. 事务

要么都成功,要么都失败

1. ACID原则:

  • 原子性:要么全部完成,要么都不完成
  • 一致性:总数不变
  • 隔离性:多个进程互不干扰
  • 持久性:一单提交不可逆,持久化到数据库

2. 隔离性的问题:

  • 脏读:一个事务读取了另一个没有提交的事务
  • 不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变
  • 虚读(幻读):在同一个事务内,读取到了别人插入的数据,到最后前后读出结果不一致

3. 代码实现

  1. 开启事务 conn.setAutoCommit(false);
  2. 一组业务执行完毕,提交事务
  3. 可以在catch语句中显式的定义回滚语句,但默认失败会回滚
package com.wang.lesson04;

import com.wang.lesson02.utils.JdbcUtils;

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

public class TestTransaction {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();
            //关闭数据库的自动提交,自动会开启事务
            conn.setAutoCommit(false);  //开启事务

            String sql_1 = "update account set money = money - 100 where name = 'A'";
            st = conn.prepareStatement(sql_1);
            st.executeUpdate();

            int x = 1 / 0;  //报错,只执行了上面的SQL,此处报错下面的SQL不执行

            String sql_2 = "update account set money = money + 100 where name = 'B'";
            st = conn.prepareStatement(sql_2);
            st.executeUpdate();

            //业务完毕,提交数据
            conn.commit();

            System.out.println("成功!");

        } catch (SQLException throwables) {
            /*
            显示定义失败回滚,可以不写
            try {
                conn.rollback();    //如果失败则回滚事务
            } catch (SQLException e) {
                e.printStackTrace();
            }
            */
            //如果失败,默认回滚
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn, st, rs);
        }

    }
}

12. 数据库连接池

数据库连接——>执行完毕——>释放

其中,连接——>释放 十分浪费系统资源

1. 池化技术

准备一些预先的资源,过来就连接预先准备好的

------ 开门 --- 业务员:等待 --- 服务 ------

最小连接数:与常用连接数相同

最大连接数:业务最高承载上限

超过最大连接数——>排队等待

等待超时:100ms

2. 编写连接池

实现一个接口 DataSource

开源数据源实现

  • DBCP
  • C3P0
  • Druid:阿里巴巴

使用了这些数据库连接池之后,我们在项目中就不需要编写连接数据库的代码了!

1. DBCP

从Maven中导入

注意:设置properties文件的路径时考虑和源码的路径是否在一个目录下,否则要加./向上一级目录寻找!

DBCP的配置文件

#连接设置   这里面的名字,是DBCP数据源中定义好的
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username = root
password = 123456

#上面的为必须写,下面的为可选项

#<!-- 初始化连接 -->
initialSize = 10

#最大连接数量
maxActive = 50

#<!-- 最大空闲连接 -->
maxIdle = 20

#<!-- 最小空闲连接 -->
minIdle = 5

#<!-- 超时等待时间以毫秒为单位 60000毫秒(60S) -->
maxWait = 60000

#JDBC驱动建立连接时附带的连接属性的属性格式必须为这样:[属性名=property;]
#注意:"user"与"password"两个属性会被明确地传递,因此这里不需要包含他们
connectionProperties = useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接自动提交(auto-commit)状态
defaultAutoCommit = true

#driver default 指定由连接池所创建的连接的只读(read-only)状态
#如果没有设置该值,则"setReadOnly"方法将不被调用。(某些驱动并不支持只读模式,如Informix)
defaultReadOnly = false

#driver default指定由连接池创建的连接的事无级别(TransactionIsolation)
#可用值为下列之一:(详情可见javadoc)NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE
defaultTransactionIsolation = READ_UNCOMMITTED

工具类

package com.wang.lesson05.utils;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_DBCP {

    private static BasicDataSource dataSource = null;

    static {
        try {
            InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("./dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //创建数据源     工厂模式 --> 创建
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();      //从数据库中获取连接
    }

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

        if (st != null) {
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

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

利用DBCP实现insert,与不使用连接池类似,只是换了工具类

package com.wang.lesson05;

import com.wang.lesson05.utils.JdbcUtils_DBCP;

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

public class TestDBCP {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils_DBCP.getConnection();

            //区别
            //使用?占位符代替参数
            String sql = "insert into users(id,`name`,`password`,`email`,`birthday`) values(?, ?, ?, ?, ?)";

            st = conn.prepareStatement(sql);   //预编译SQL:先写SQL,不执行

            //手动给参数赋值
            st.setInt(1, 5);
            st.setString(2, "wang");
            st.setString(3, "456789");
            st.setString(4, "456789@qq.com");
            //注意点:sql.Date   SQL     java.sql.Date()传入时间戳获得SQL的Date
            //      util.Date   Java    new Date().getTime()获得时间戳
            st.setDate(5, new java.sql.Date(new Date().getTime()));

            //执行
            int i = st.executeUpdate();
            if (i >0)
                System.out.println("插入成功!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils_DBCP.release(conn,st,null);
        }
    }
}

2. C3P0

配置文件

<?xml version="1.0" encoding="UTF-8" ?>

<c3p0-config>
    <!--
    C3P0的缺省(默认)配置
    如果在代码中"ComoPooledDataSource ds = new ComboPooledDataSource();"这样写就表示使用的是C3P0的缺省(默认)配置
    -->
    <default-config>
        <property name = "driverClass">com.mysql.jdbc.Driver</property>
        <property name= "jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=true&amp;serverTimezone=UTC</property>
        <property name= "user">root</property>
        <property name= "password">123456</property>

        <property name= "acquireIncrement">5</property>
        <property name= "initialPoolSize">10</property>
        <property name= "minPoolSize">5</property>
        <property name= "maxPoolSize">20</property>
    </default-config>

    <!--
    C3P0的命名配置
    如果在代码中"ComoPooledDataSource ds = new ComboPooledDataSource("MySQL");"这样写就表示使用的是name是MySQL的数据源
    这样就可以配置多个数据源
    -->
    <named-config name = "MySQL">
        <property name = "driverClass">com.mysql.jdbc.Driver</property>
        <property name= "jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=true&amp;serverTimezone=UTC</property>
        <property name= "user">root</property>
        <property name= "password">123456</property>

        <property name= "acquireIncrement">5</property>
        <property name= "initialPoolSize">10</property>
        <property name= "minPoolSize">5</property>
        <property name= "maxPoolSize">20</property>
    </named-config>

</c3p0-config>

C3P0工具类写法

package com.wang.lesson05.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

public class JdbcUtils_C3P0 {

    private static ComboPooledDataSource dataSource = null;

    static {
        try {
            //代码版配置
//            dataSource = new ComboPooledDataSource();
//            dataSource.setDriverClass();
//            dataSource.setUser();
//            dataSource.setPassword();
//            dataSource.setJdbcUrl();
//
//            dataSource.setMaxPoolSize();
//            dataSource.setMinPoolSize();


            //创建数据源     工厂模式 --> 创建
            //注意,此种写法中,XML文件要在src目录下,且必须命名为c3p0-config!
            dataSource = new ComboPooledDataSource("MySQL");    //使用配置文件(XML)的写法
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();      //从数据库中获取连接
    }

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

        if (st != null) {
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

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

利用C3P0实现insert

package com.wang.lesson05;

import com.wang.lesson05.utils.JdbcUtils_C3P0;

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

public class TestC3P0 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils_C3P0.getConnection();

            //区别
            //使用?占位符代替参数
            String sql = "insert into users(id,`name`,`password`,`email`,`birthday`) values(?, ?, ?, ?, ?)";

            st = conn.prepareStatement(sql);   //预编译SQL:先写SQL,不执行

            //手动给参数赋值
            st.setInt(1, 5);
            st.setString(2, "wang");
            st.setString(3, "456789");
            st.setString(4, "456789@qq.com");
            //注意点:sql.Date   SQL     java.sql.Date()传入时间戳获得SQL的Date
            //      util.Date   Java    new Date().getTime()获得时间戳
            st.setDate(5, new java.sql.Date(new Date().getTime()));

            //执行
            int i = st.executeUpdate();
            if (i >0)
                System.out.println("插入成功!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JdbcUtils_C3P0.release(conn,st,null);
        }
    }
}

3. 结论

无论使用什么数据源,本质还是一样的,接口DataSource接口不会变,方法就不会变!

原文地址:https://www.cnblogs.com/wang-sky/p/13503752.html