JDBC数据库连接池

JDBC数据库连接池

1.概念

  • 其实就是一个容器(集合),存放数据库连接的容器。

    • 当系统初始化好后,容器被创建,容器中会申请一些数据库连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完数据库后回将连接归还给容器。

2.好处

  • 节约资源
  • 用户访问高效

2.实现

  • image-20211231195331341

2.1 标准接口

image-20211231195754878

  • 标准接口:DataSource java.sql包下的
  • 方法
    • 获取连接:getConnection()
    • 归还连接:Connection.close().如果Connection是从连接池中获取的,那么close()方法,则不会关闭连接。而是归还连接

2.2 C3P0数据库连接池

1.依赖jar
2.定义配置文件
  • 名称:c3p0.properties或者c3p0-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <c3p0-config>
        <default-config>
            <!-- 连接参数设置,密码与驱动 -->
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC</property>
            <property name="user">root</property>
            <property name="password">root</property>
    
            <!-- 连接池参数 -->
            <!-- 初始话申请数量 -->
            <property name="initialPoolSize">10</property>
    
    <!--        <property name="maxIdleTime">30</property>-->
            <!-- 最大连接数 -->
            <property name="maxPoolSize">100</property>
    <!--        <property name="minPoolSize">10</property>-->
            <!--设置超时时间-->
            <property name="checkoutTimeout">3000</property>
        </default-config>
    
        <named-config name="mySource">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/bookstore</property>
            <property name="user">root</property>
            <property name="password">xxxx</property>
    
            <property name="initialPoolSize">10</property>
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">100</property>
            <property name="minPoolSize">10</property>
        </named-config>
    </c3p0-config>
    
  • 路径:直接放在src目录下。

3.创建核心对象与获取连接对象
  • 创建对象ComboPooledDataSource()
  • 获取对象ds.getConnection()
package com.sql.one;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3P0Demo {
    public static void main(String[] args) throws SQLException {
        //创建数据库连接池对象
        DataSource ds=new ComboPooledDataSource();
        //获取连接对象
        Connection conn=ds.getConnection();
        //3.打印连接
        System.out.println(conn);
    }
}

image-20211231203211146

package com.sql.one;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3P0Demo {
    public static void main(String[] args) throws SQLException {
        //创建数据库连接池对象,参数可以传入xml配置文件中的name使用其他廉价
        DataSource ds=new ComboPooledDataSource();
        //获取连接对象
//        Connection conn=ds.getConnection();
        //3.打印连接
        for(int i=1;i<=10;i++){
            Connection conns=ds.getConnection();
            System.out.println(i+":"+conns);
            if(i==5){
                conns.close();//归还连接不是关闭
            }
        }
    }
}

image-20211231205047890

2.3 Druid 数据库连接池

1.依赖jar

地址:https://mvnrepository.com/artifact/com.alibaba/druid

2.定义配置文件
# 驱动加载
driverClassName=com.mysql.jdbc.Driver
# 注册驱动
url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC
# user
username=root
# password
password=password123
# 初始化时池中建立的物理连接个数。
initialSize=2
# 最大的可活跃的连接池数量
maxActive=50
# 最长等待时间单位毫秒,60*1000 =1分钟
maxWait=60000
  • 可以叫任意名称,可以放在任意目录下
3.获取数据库连接池
  • 通过工厂类来获取DruidDataSourceFactory

  • package com.sql.one;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.util.Properties;
    import java.sql.Connection;
    
    public class DruidDemo {
        public static void main(String[] args)throws Exception{
            //1.导入jar包
            //2.加载配置文件
            Properties pro =new Properties();
            InputStream is =DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            //4.获取连接池对象,使用工厂模式
            DataSource ds= DruidDataSourceFactory.createDataSource(pro);
            //5.获取连接
            Connection conn= ds.getConnection();
            System.out.println(conn);
    
        }
    }
    
    
4.获取连接

image-20220103155108296

3.工具类的封装

3.1 概述

  • 定义一个类JDBCUtils

  • 提供静态代码块加载配置文件,初始化连接池对象

  • 提供方法

    • 获取连接方法:通过对数据库连接池获取连接
    • 释放资源
    • 获取连接池的方法

3.2 测试使用

package com.sql.one;

import com.sql.jdbcutils.JDBCUtils;

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

public class DuridDemo2 {
    public static void main(String[] args) {
        try {
            Connection conn= JDBCUtils.getConnection();
            String sql="insert into t1 values(null,?,?)";
            PreparedStatement pstmt= conn.prepareStatement(sql);
            //给SQL中的?赋值
            pstmt.setString(1,"逻辑");
            pstmt.setInt(2,30);
            int count=pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

image-20220103162342692

4.Spring JDBC

4.1 概述

image-20220103162941262

调用JdbcTemplate的方法来完成CRUD操作

  • update():执行DML语句。增、删、改语句。

  • queryForMap():查询结果,将结果集封装为map集合

  • queryForList():查询结果封装为list集合

  • query():查询结果返回为JavaBean对象

  • queryForObject:查询结果,将结果封装为对象。

4.2 简单使用

  • 导入相关jar

    image-20220103163935361

  • 简单使用,但前提是要有数据库连接池DataSource

  • package com.sql.jdbctemplate;
    
    import com.sql.jdbcutils.JDBCUtils;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    public class JDBCTemplate {
        public static void main(String[] args) {
            //1.导入jar包
            //2.创建JDBCTemplate对象
    
            JdbcTemplate template =new JdbcTemplate(JDBCUtils.getDataSource());
            //3.调用方法
            String sqlstr="insert into t1 values(null,?,?)";
            int count = template.update(sqlstr, "史强", 30);
            System.out.println("插入"+count+"条数据成功");
        }
    }
    
    

    image-20220103165600610

4.3 测试模块的简单使用

  • 在函数名上加上注解@Test,则改函数可以独立执行,不依赖主方法。

    image-20220103173051671

4.4 常用方法的介绍

1. update() 方法
  • 返回插入数据库的条数。
package com.sql.jdbctemplate;

import com.sql.jdbcutils.JDBCUtils;
import org.testng.annotations.Test;
import org.springframework.jdbc.core.JdbcTemplate;

public class JdbcTemplateDemo2 {
    //实例化JdbcTemplate
    JdbcTemplate template= new JdbcTemplate(JDBCUtils.getDataSource());
    //Junit 单元测试,可以让方法独立执行,使用@Test注解,
    @Test
    public void test1(){
        String sqlstr="insert into t1 values(null,?,?)";
        int count = template.update(sqlstr, "艾AA", 30);
        System.out.println("插入"+count+"条数据成功");
        //System.out.println("我被执行了");
    }
}

image-20220103173051671

2. queryForMap () 方法
  • 返回map集合,只能有一个结果。

  • 	@Test
        public void test2(){
            String sqlstr="select * from t1 where id=1";
            Map<String, Object> map = template.queryForMap(sqlstr);
            System.out.println(map);
        }
    
    	//{id=1, username=东方, age=21}
    
  • image-20220103174134006

  • 两条返回结果就报错。因为map的键具有唯一性。

    image-20220103174306232

  • 没有返回的结果也会报错。

    image-20220103174503394

3. queryForList ()方法
  • 查询结果封装为list集合,其中每条记录都会被封装在map集合,在封装在list中。

  • 	@Test
        public void test3(){
            String sqlstr="select * from t1";
            List<Map<String, Object>> maps = template.queryForList(sqlstr);
    
            for (Map<String, Object> map : maps) {
                System.out.println(map);
            }
        }
    

    image-20220103175736952

4. query()方法
  • 该方法最为常用。

    • new BeanPropertyRowMapper<类>(类.class)
      
  • 返回JavaBean封装的对象。

  • 首先创建好对应的类

    package com.sql.jdbctemplate;
    
    public class Role {
        private Integer id;
        private String username;
        private Integer age;//使用引用的数据类型防止出现数据库中存在空值(null)的数据情况
    
        public Role(Integer id, String username, Integer age) {
            this.id = id;
            this.username = username;
            this.age = age;
        }
    
        public Role() {
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Role{" +
                    "id=" + id +
                    ", username='" + username + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
  • 第一种方法(比较繁琐,不建议使用)。

    image-20220103180216633

  • 第二种方法

        @Test
        public void test4(){
            String sqlstr="select * from t1";
            //使用泛型和反射将对应的JavaBean加载进内存进行使用
            List<Role> list= template.query(sqlstr,new BeanPropertyRowMapper<Role>(Role.class));
            for(Role r : list){
                System.out.println(r);
            }
        }
    

    image-20220103180842247

  • 注:如果字段和bean中的字段不匹配,可以在SQL语句中起别名。

5. queryForObject()方法
  • 一般用来执行聚合函数sql语句,例如count,sum,avg

  •     @Test
        public void test5(){
            String sqlstr="select count(1) from t1";
            //除了SQL语句还要传入返回值的类型,返回值用指定的类型进行接收
            Long count=template.queryForObject(sqlstr,Long.class);
            System.out.println(count);
        }
    

    image-20220103181455032

5.快捷键的补充

  • 返回值ideactrl+Alt+V快速生成返回值。
  • for循环:iter增强for循环,fori普通for循环。

继续努力,终成大器!

posted @ 2022-01-03 18:22  紫青宝剑  阅读(116)  评论(0编辑  收藏  举报