首页 > 数据库 >JDBC与数据库连接池

JDBC与数据库连接池

时间:2024-03-27 17:24:51浏览次数:14  
标签:password JDBC String 数据库 连接池 null public conn

JDBC

1 JDBC概述

JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API)

简单理解为:JDBC,是SUN提供的一套 API,使用这套API可以实现对具体数据库的操作(获取连接、关闭连接、DML、DDL、DCL)

数据库的驱动:数据库厂商针对于JDBC这套接口,提供的具体实现类的集合。

面向接口编程的思想:

  • JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。
  • 不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。

数据库创建

CREATE DATABASE `jdbcstudy` /*!40100 DEFAULT CHARACTER SET utf8 */;

-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `money` int(255) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for photos
-- ----------------------------
DROP TABLE IF EXISTS `photos`;
CREATE TABLE `photos` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `photo` longblob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `NAME` varchar(40) DEFAULT NULL,
  `PASSWORD` varchar(40) DEFAULT NULL,
  `email` varchar(60) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

通过Driver接口获取数据库连接

准备工作:

Driver是一个接口,数据库厂商必须提供实现的接口,从而获取到数据库连接,可以通过Driver的实现类的对象获取连接

加入mysql驱动

  • 方法一:导入jar包
    1. 下载并解压mysql-connector-java-5.1.18.zip
    2. 在当前目录下新建lib目录
    3. 把mysql-connector-java-5.1.18-bin.jar复制到lib目录
    4. 右键->build-path->add build path加载到类路径下
  • 方法二:Maven配置
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    

1、创建一个Driver实现类的对象

    Driver driver=new com.mysql.jdbc.Driver();

2、准备连接数据库的基本信息,url,user,password

    url=jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=false;
    String user = "root";
    String password = "123456"; 

3、调用DriverManager.getConnection获取连接

    Connection connection = DriverManager.getConnection(url, user, password);

4、关闭数据库连接

   connection.close(); 

代码实现:

public class BestConnection {

    public static void main(String[] args) throws SQLException, ClassNotFoundException {

        // 1、加载驱动 DriverManager
        Class.forName("com.mysql.jdbc.Driver");

        // 2、参数配置
        String  url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&userSSL=false";
        String  username = "root";
        String  password = "123456";

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

        // 4、数据库执行对象获取
        Statement statement = connection.createStatement();

        // 5、执行sql
        String sql = "select * from users";
        ResultSet resultSet = statement.executeQuery(sql);
        while(resultSet.next()){
            System.out.println(resultSet.getObject("id"));
            System.out.println(resultSet.getObject("NAME"));
            System.out.println(resultSet.getObject("PASSWORD"));
            System.out.println(resultSet.getObject("email"));
            System.out.println(resultSet.getObject("birthday"));
            System.out.println("=========================================");
        }

        // 6、释放资源
        resultSet.close();
        statement.close();
        connection.close();

    }
}  

连接数据库最佳方法:
上面这种方式不太理想,对于数据库的信息起不到保护作用!
首先,我们新建一个配置文件名字叫做jdbc.Properties(最好放在src下面,方便引用),里面添加我们连接数据库需要的信息

注意:配置文件中不要加空格,不要加双引号

url=jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
driver=com.mysql.jdbc.Driver   

完整代码:

public class BestConnection {
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
        // 1、获得类加载器
        ClassLoader classLoader = BestConnection.class.getClassLoader();
        // 2、读取配置文件信息
        InputStream is = classLoader.getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        // 3、加载对应的输入流
        properties.load(is);
        // 4、拿到配置文件的具体值,getProperty里的值必须和配置文件的一致
        String user = properties.getProperty("user");
        String url = properties.getProperty("url");
        String password = properties.getProperty("password");
        String driverClass = properties.getProperty("driverClass");
        // 5、加载数据库驱动程序
        Class.forName(driverClass);
        // 6、建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);
        // 7、关闭连接
        connection.close();
    }
}    

2 JDBCUtils

说明:

为了方便操作,将连接(关闭)数据库封装成一个工具类

/**
 * jdbc 工具类
 */
public class JdbcUtil {

    /**
     * 参数定义
     */
    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {

        try {
            InputStream is = JdbcUtil.class.getResourceAsStream("/db.properties");
            Properties properties = new Properties();
            properties.load(is);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取链接对象
     * @return
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }

    /**
     * 链接释放
     * @param conn
     * @param st
     * @param rs
     */
    public static void release(Connection conn, Statement st, ResultSet rs){

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

    }
}   

工具类调用:

public class TestSql {


    public static void main(String[] args) {

        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 = JdbcUtil.getConnection();
            st = conn.createStatement();

            String sql = "select * from users where `NAME` = " + username + " AND `password` = " + password;

            ResultSet resultSet = st.executeQuery(sql);
            while (resultSet.next()){

                System.out.println(resultSet.getObject("NAME"));
                System.out.println(resultSet.getObject("PASSWORD"));
                System.out.println("===========================");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.release(conn, st, rs);
        }
    }
}

PreparedStatement 优化SQL注入:

public class TestSql_PreparedStatement {


    public static void main(String[] args) {

        login("showger", "123456");
//        login("'' or 1=1", "'' or 1=1");
    }

    private static void login(String username, String password) {

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

        try {
            conn = JdbcUtil.getConnection();
//            conn = JdbcUtil_DBCP.getConnection();
//            conn = JdbcUtil_C3P0.getConnection();
//            conn = JdbcUtil_Druid.getConnection();

            String sql = "select * from users where `NAME` = ? AND `password` = ?";

            st = conn.prepareStatement(sql);
            st.setString(1, username);
            st.setString(2, password);

            ResultSet resultSet = st.executeQuery();
            while (resultSet.next()){

                System.out.println(resultSet.getObject("NAME"));
                System.out.println(resultSet.getObject("PASSWORD"));
                System.out.println("===========================");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.release(conn, st, rs);
        }
    }
}

3 使用PreparedStatement操作Blob(图片、音频等大型文件)类型的变量

插入blob类型数据到数据库:

public class TestPhotoInsert {

    public static void main(String[] args) {

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

        try {
            conn = JdbcUtil.getConnection();

            String sql = "insert into photos(photo) values(?);";
            st = conn.prepareStatement(sql);
            String projectPath = System.getProperty("user.dir");
            System.out.println(projectPath);
            FileInputStream fis = new FileInputStream(projectPath + "\\src\\main\\resources\\java-php.jpg");

            st.setObject(1, fis);
            boolean result = st.execute();
            if(result){
                System.out.println("数据插入成功!");
            }
        } catch (SQLException | FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.release(conn, st, rs);
        }
    }
}

查询数据库的Blob数据:

public class TestPhotoGet {

    public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        InputStream is = null;
        FileOutputStream fos = null;

        try {
            conn = JdbcUtil.getConnection();

            String sql = "select `id`, `photo` from `photos`;";
            ps = conn.prepareStatement(sql);
            ResultSet resultSet = ps.executeQuery();
            if(resultSet.next()){
                int id = resultSet.getInt("id");
                System.out.println("id === " + id);
                Blob photo = resultSet.getBlob("photo");
                is = photo.getBinaryStream();

                String projectPath = System.getProperty("user.dir");
                fos = new FileOutputStream(projectPath + "\\src\\main\\resources\\java-php-"+id+".jpg");
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1){
                   fos.write(buffer, 0, len);
                }
            }
            System.out.println("图片数据读取成功!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            JdbcUtil.release(conn, ps, rs);
        }
    }
}	

注意:

数据库,默认max_allowed_packet=4M,更根据你文件大小进行增加。

blob类型不够的话,使用longblob可以解决,xxx too long 的问题

开发中使用PreparedStatement替换Statement,Statement存在SQL注入问题

4 数据库事务

事务:

一组逻辑操作单元,使数据从一种状态变换到另一种状态。

一组逻辑操作单元:

一个或多个DML操作。

事务处理的原则:

保证所事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。

哪些操作会导致数据的自动提交?

DDL操作一旦执行,都会自动提交。set autocommit = false 对DDL操作失效

DML默认情况下,一旦执行,就会自动提交。我们可以通过set autocommit = false的方式取消DML操作的自动提交。

默认在关闭连接时,会自动的提交数据

代码实现:

public class TestTransation {

    public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtil.getConnection();

            // 关闭自动提交事务
            conn.setAutoCommit(false);

            String sql1 = "update account set money = money - 100 where name = 'xiaogang'";
            ps = conn.prepareStatement(sql1);
            ps.executeUpdate();

            String sql2 = "update account set money = money + 100 where name = 'showger'";
            ps = conn.prepareStatement(sql2);
            ps.executeUpdate();

            // 提交事务
            conn.commit();

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


        } catch (SQLException e) {
            try {
                // 回滚 (默认)
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            JdbcUtil.release(conn, ps, rs);
        }

    }
}

5 通用的增删改查

实体定:

public class User {

    private int id;
    private String name;
    private String  password;
    private String email;
    private Date birthday;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

通用的增删改:

public static void CommonCRD(String sql, Object... args) {

    Connection conn = null;
    PreparedStatement ps = null;

    try {
        // 1、 建立数据库连接
        conn = JdbcUtil.getConnection();
        // 2、预编译sql语句
        ps = conn.prepareStatement(sql);
        // 3、占位符填充参数
        for (int i = 0; i < args.length; i++) {
            ps.setObject(i+1, args[i]);
        }
        // 4、执行
        ps.execute();
        System.out.println("操作成功!");

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.release(conn, ps);
    }
}

测试代码:

String updateSql = "UPDATE users SET `name` = ?, `password` = ?, `email` = ?, `birthday` = ? WHERE id = ?";
CommonUtil.CommonCRD(updateSql, "xiaogang", "999999", "[email protected]", "2024-02-02", 1);

通用的返回表中所有数据:

public static <T> List<T> commonGetList(Class<T> clazz, String sql, Object... args){

    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<T> dataList = null;

    try {
        // 1、 建立数据库连接
        conn = JdbcUtil.getConnection();
        // 2、预编译sql语句
        ps = conn.prepareStatement(sql);
        // 3、占位符填充参数
        for (int i = 0; i < args.length; i++) {
            ps.setObject(i+1, args[i]);
        }
        // 4、执行并且获得结果集
        rs = ps.executeQuery();
        // 5、获取结果集元数据
        ResultSetMetaData rsmd = rs.getMetaData();
        // 6、获取结果集字段数量
        int columnCount = rsmd.getColumnCount();
        dataList = new ArrayList<>();
        while(rs.next()){
            T t = clazz.newInstance();
            // 8、处理结果集一行数据的每一个字段
            for (int i = 0; i < columnCount; i++) {
                int columNum = i + 1;
                // 9、获取列值
                Object columValue = rs.getObject(columNum);
                // 10、获取列名
                String columName = rsmd.getColumnClassName(columNum);
                String columName2 = rsmd.getColumnName(columNum);
                String columnLabel = rsmd.getColumnLabel(columNum);
                // 11、赋值:通过反射
                Field field = clazz.getDeclaredField(columnLabel);
                field.setAccessible(true);
                field.set(t, columValue);
            }
            dataList.add(t);
        }
        System.out.println("查询成功!");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.release(conn, ps, rs);
    }
    return dataList;
}

测试代码:

String querySql = "select * from users";
List<User> users = CommonUtil.commonGetList(User.class, querySql);
for (User user : users) {
    if(user != null){
        System.out.println(user.toString());
    }
}

通用的单条查询:

public static <T> T commonGetOne(Class<T> clazz, String sql, Object... args){

    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // 1、 建立数据库连接
        conn = JdbcUtil.getConnection();
        // 2、预编译sql语句
        ps = conn.prepareStatement(sql);
        // 3、占位符填充参数
        for (int i = 0; i < args.length; i++) {
            ps.setObject(i+1, args[i]);
        }
        // 4、执行并且获得结果集
        rs = ps.executeQuery();
        // 5、获取结果集元数据
        ResultSetMetaData rsmd = rs.getMetaData();
        // 6、获取结果集字段数量
        int columnCount = rsmd.getColumnCount();

        if(rs.next()){
            T t = clazz.newInstance();
            // 8、处理结果集一行数据的每一个字段
            for (int i = 0; i < columnCount; i++) {
                int columNum = i + 1;
                // 9、获取列值
                Object columValue = rs.getObject(columNum);
                // 10、获取列名
                String columnLabel = rsmd.getColumnLabel(columNum);
                // 11、赋值:通过反射
                Field field = clazz.getDeclaredField(columnLabel);
                field.setAccessible(true);
                field.set(t, columValue);
            }
            return t;
        }
        System.out.println("查询成功!");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.release(conn, ps, rs);
    }
    return null;
}

测试代码:

String oneSql = "select * from users where id = ?";
User user = CommonUtil.commonGetOne(User.class, oneSql, 1);
if(user != null){
    System.out.println(user.toString());
}

6 数据库连接池

数据库:

在每一次请求数据库都要经历上述过程,创建连接和释放资源也都是些重复性的动作,当请求量比较大时,资源是个很大的浪费。

假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。

连接池:

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。

几种常用的数据库连接池:

1、DBCP(Database Connection Pool)

是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。

2、C3P0

是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象,sql执行效率较低

3、Proxool

是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能,在激烈并发时会抛异常,完全不靠谱。

4、BoneCP

是一个开源的快速的 JDBC 连接池。BoneCP很小,只有四十几K

5、Druid

是阿里提供的数据库连接池,据说是集DBCP、C3P0、Proxool优点于一身的连接池,性能最好的数据库连接池

6.1 DBCP数据库连接池

准备工作 :

在项目src目录下创建dbcp.properties配置文件

# 连接配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;
characterEncoding=utf8
#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true
#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

需要引用的包 commons-dbcp-1.4.jar commons-pool-1.6.jar

<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-pool/commons-pool -->
<dependency>
    <groupId>commons-pool</groupId>
    <artifactId>commons-pool</artifactId>
    <version>1.6</version>
</dependency>

通过DBCP封装连接数据库的方法:

public class JdbcUtil_DBCP {

    /**
     * 创建一个DBCP的数据库连接池
     */
    private static DataSource dataSource;


    static {

        try {
            InputStream is = JdbcUtil_DBCP.class.getResourceAsStream("/dbcp.properties");
            Properties properties = new Properties();
            properties.load(is);
            // 创建数据源 工厂模式
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取链接对象
     * @return
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

}

6.2 C3P0数据库连接池

准备工作 :

在项目src目录下创建c3p0-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--    c3p0的缺省设置
            如果在代码中 ComboPooledDataSource ds = new ComboPooledDataSource() 这样表示的使用c3p0的默认设置
    -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="maxPoolSize">20</property>
        <property name="minPoolSize">5</property>
    </default-config>
    <!--    c3p0的命名设置
           如果在代码中 ComboPooledDataSource ds = new ComboPooledDataSource("mysql") 这样表示的使用c3p0的命名设置
        name 与 代码中名称对应
    -->
    <named-config name="MYSQL">
        <!-- 提供获取连接的4个基本信息 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <!-- & ==> &amp; -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <!-- 进行数据库连接池管理的基本信息 -->
        <!-- 当数据库连接池中的连接数不够时,c3p0一次性向数据库服务器申请的连接数 -->
        <property name="acquireIncrement">5</property>
        <!-- c3p0数据库连接池中初始化时的连接数 -->
        <property name="initialPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最少连接数 -->
        <property name="minPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最多的连接数 -->
        <property name="maxPoolSize">100</property>
        <!-- c3p0数据库连接池最多维护的Statement的个数 -->
        <property name="maxStatements">50</property>
        <!-- 每个连接中可以最多使用的Statement的个数 -->
        <property name="maxStatementsPerConnection">2</property>
    </named-config>
</c3p0-config>

导入c3p0的包

<!-- https://mvnrepository.com/artifact/com.mchange/mchange-commons-java -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>mchange-commons-java</artifactId>
    <version>0.2.19</version>
</dependency>

通过C3P0封装连接数据库的方法:

public class JdbcUtil_C3P0 {

    /**
     * 数据源配置
     */
    private static ComboPooledDataSource dataSource = null;


    static {

        try {
            // 与配置文件名称对应
           dataSource = new ComboPooledDataSource("MYSQL");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取链接对象
     * @return
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

6.3 Druid数据库连接池

准备工作:

创建druid.properties:

url=jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=10

导入Druid的jar包

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>

测试代码:

/**
 * jdbc 工具类
 */
public class JdbcUtil_Druid {

    /**
     * 数据源配置
     */
    private static DataSource dataSource = null;


    static {

        try {
            InputStream is = JdbcUtil_DBCP.class.getResourceAsStream("/druid.properties");
            Properties properties = new Properties();
            properties.load(is);
            // 创建数据源 工厂模式
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取链接对象
     * @return
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

标签:password,JDBC,String,数据库,连接池,null,public,conn
From: https://www.cnblogs.com/showger/p/18099761

相关文章

  • Qt 操作sql server数据库
    Qt操作sqlserver数据库添加qtsql的库连接数据库QSqlDatabase_db=QSqlDatabase::addDatabase("QODBC");_db.setHostName();_db.setDatabaseName();_db.setUserName();_db.setPassword();_db.setPort();_db.open();增QSqlQueryquery;query.prepare("INSER......
  • RestCloud数据集成平台-监听SqlServer数据库表,并同步数据到MongoDB数据库表详细教程(实
    上一篇:RestCloud数据集成平台-Windows全量包安装部署详细教程1.数据源管理数据源主要用来建立与用户的数据库的链接。数据源管理主要用来对用户添加的所有数据链接进行管理,主要包括新建数据源、测试链接、修改链接、复制链接、查询链接和删除链接等功能。1.1.创建链接......
  • 使用shell生成数据并插入到redis数据库中
    [root@snortredis]#catset.sh#!/bin/bash#Redis服务器地址和端口REDIS_HOST="localhost"REDIS_PORT="6379"REDIS_PASS="123456"#插入的键值对数量NUM_ENTRIES=1000000#插入的键的前缀KEY_PREFIX="testkey"#生成随机字符串的长度RANDOM_STRING_L......
  • oracle 11G 数据库归档日志清理流程。
    oracle11G数据库归档日志清理流程。链接:ORACLE11g数据库归档日志清理规程-百度文库(baidu.com)......
  • 【实战教程】Spring Boot项目集成华为openGauss数据库的关键步骤与注意事项
    引言:随着国产数据库技术的崛起,华为openGauss凭借其高性能、安全可靠及易用性成为了众多开发者的首选方案。本篇技术文章将聚焦于如何在SpringBoot项目中成功集成华为openGauss数据库,并揭示其中的一些关键步骤与注意事项,助您轻松驾驭这一强大的数据库引擎。正文:一、环境准备......
  • 【数据库】如何利用Python中的petl将PostgreSQL中所有表的外键删除,迁移数据,再重建外键
    一、简介在数据库管理中,外键是一种重要的约束,用于确保数据的一致性和完整性。然而,在某些情况下,我们可能需要删除或修改外键。本文将介绍如何使用Python中的petl库将PostgreSQL中所有表的外键删除,迁移数据,并重新建立外键。二、安装petl和psycopg2首先,我们需要安装petl和psycopg2......
  • 数据库三大范式的学习与数据库表设计的了解
    数据库三大范式的学习与数据库表设计的了解内容简单介绍对于数据库三大范式的理解以及一些设计表示要注意的方面本章内容梳理图数据库三大范式比较官方的定义数据库的三大范式(NormalForms)是关系数据库设计中用于确保数据结构化、减少数据冗余、并提高数据完整性的指导和规......
  • JDBC复习
    JDBC导入驱动jar包,注册驱动,获取连接定义sql获取执行sql的对象,执行sql处理结果:查询需要处理结果,增删改只需要判断count>0,有没有执行成功;释放资源Class.forName("com.mysql.cj.jdbc.Driver");Connectionconnection=DriverManager.getConnection(url,username,password);......
  • redis 数据库一致性策略
    参考常见的缓存更新策略共有3种:CacheAside(旁路缓存)策略;Read/WriteThrough(读穿/写穿)策略;WriteBack(写回)策略;CacheAside(旁路缓存)策略CacheAside(旁路缓存)策略是最常用的,应用程序直接与「数据库、缓存」交互,并负责对缓存的维护,该策略又可以细分为「读策略」和「写策略」......
  • 非关系型数据库和关系型数据库--一起学习吧之数据库
    非关系型数据库和关系型数据库是两种不同类型的数据库管理系统,它们在设计、数据存储、数据结构和应用场景等方面有着显著的区别。一、概念区别关系型数据库是建立在关系数据库模型基础上的数据库,通过外键关联来建立表与表之间的关系。它使用二维表的形式来存储数据,具有固定的......