zoukankan      html  css  js  c++  java
  • 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循环。

    继续努力,终成大器!

  • 相关阅读:
    PAT1124:Raffle for Weibo Followers
    Pat1071: Speech Patterns
    PAT1032: Sharing (25)
    Pat1128:N Queens Puzzle
    C++相关:C++的IO库
    Pat1108: Finding Average
    PAT1070:Mooncake
    乐港游戏校招面试总结
    并发编程005 --- future &&futureTask
    并发编程004 --- 线程池的使用
  • 原文地址:https://www.cnblogs.com/Blogwj123/p/15760125.html
Copyright © 2011-2022 走看看