JDBC学习2——数据库连接池技术(C3P0、Druid)、Spring JDBC

1.数据库连接池

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

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

这样做的好处有两个:节约资源;用户访问高效。

1.1 数据库连接池的实现

标准接口:DataSource(数据源,即数据库连接池),这是javax.sql包下的,它没有对应的实现类,谁提供数据库的驱动,谁负责实现。

DataSource中有两个方法:

  • 获取连接:getConnection()
  • 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接。

这些方法(包括上面两个方法)一般我们不去实现它,有数据库厂商来实现。常用的有两个数据库厂商的实现,分别是:

  1. C3P0:数据库连接池技术
  2. Druid:数据库连接池实现技术,由阿里巴巴提供的

1.2 C3P0的数据库连接池技术

使用步骤:

  1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar(另外,不要忘记导入数据库驱动jar包)。
  2. 定义配置文件:
    有两点要注意:名称,必须为这两个名字之一, c3p0.properties 或者 c3p0-config.xml;路径,直接将文件放在src目录下即可。
  3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
  4. 获取连接: getConnection

代码:

//1.创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
//2.获取连接对象
Connection conn = ds.getConnection();

1.3 Druid

Druid数据库连接池实现技术,是由阿里巴巴提供的。

步骤:

  1. 导入jar包 druid-1.0.9.jar
  2. 定义配置文件:
    该配置文件有如下两个特点:是properties形式的;可以叫任意名称,可以放在任意目录下;
  3. 加载配置文件Properties;
  4. 获取数据库连接池对象:通过工厂来来获取: DruidDataSourceFactory;
  5. 获取连接:getConnection;

代码:

//1.导入jar包
//2.定义配置文件
//3.加载配置文件
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);

为了简化Druid数据库连接池的使用,我们还是会定义工具类的。

步骤:

  1. 定义一个类 JDBCUtils;
  2. 提供静态代码块加载配置文件,初始化连接池对象;
  3. 再提供一些方法:
    method1:获取连接方法:通过数据库连接池获取连接;
    method2:释放资源;
    method3:获取连接池的方法;

JDBCUtils类的代码:

public class JDBCUtils {
    //1.定义成员变量 DataSource
    private static DataSource ds ;
    static{
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            //2.获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
    /**
     * 释放资源
     */
    public static void close(Statement stmt,Connection conn){
       /* if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }*/

       close(null,stmt,conn);
    }
    public static void close(ResultSet rs , Statement stmt, Connection conn){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取连接池方法
     */

    public static DataSource getDataSource(){
        return  ds;
    }
}

使用新的工具类进行添加操作,给dept表添加一条记录:

public class DruidDemo2 {
    public static void main(String[] args) {
        /**
         * 完成添加操作,给account表添加一条记录
         */
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //1.获取连接
            conn = JDBCUtils.getConnection();
            //2.定义sql
            String sql = "insert into dept values(8,?)";
            //3.获取pstmt对象
            pstmt = conn.prepareStatement(sql);
            //4.给?赋值
            pstmt.setString(1,"王五");
            //5.执行sql
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
             JDBCUtils.close(pstmt,conn);
        }

    }
}

2.Spring JDBC

Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象,来简化JDBC的开发。

开发的基本步骤:

  1. 导入jar包
  2. 创建JdbcTemplate对象。依赖于数据源DataSource
    JdbcTemplate template = new JdbcTemplate(ds);
  3. 调用JdbcTemplate的方法来完成CRUD的操作。

常用的CRUD的操作:

  • update():执行DML语句。增、删、改语句
  • queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
    • 注意:这个方法查询的结果集长度只能是1
  • queryForList():查询结果将结果集封装为list集合。(注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中。)
  • query():查询结果,将结果封装为JavaBean对象,query的参数:RowMapper
    * 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
    * new BeanPropertyRowMapper<类型>(类型.class)
  • queryForObject:查询结果,将结果封装为对象
    * 一般用于聚合函数的查询

基本代码:

/**
 * JdbcTemplate入门
 */
public class JdbcTemplateDemo1 {
    public static void main(String[] args) {
        //1.导入jar包
        //2.创建JDBCTemplate对象
        JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
        //调用方法
        String sql = "update dept set NAME = '新部门' where id = ?";
        int count = template.update(sql,1);
        System.out.println(count);
    }
}

2.1 练习

需求:

  1. 修改1号数据的 salary 为 10000
  2. 添加一条记录
  3. 删除刚才添加的记录
  4. 查询id为1的记录,将其封装为Map集合
  5. 查询所有记录,将其封装为List
  6. 查询所有记录,将其封装为Emp对象 的List集合
  7. 查询总记录数

代码:

package cn.itcast.datasource.domain;

import java.util.Date;

public class Emp {
    private int id; 
    //这里包括下面,最好都用包装类,防止读到null的情况报错
    private String name;
    private String gender;
    private int salary;
    private Date joindate;
    private int deptid;
   //以及一些set和get函数,还有toString函数;
}

各个需求的实现

public class JdbcTemplateDemo2 {
    //1.获取JDBCTemplate对象
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    //Junit单元测试,可以让方法独立执行
    /**
     * 修改1号数据的salary为200
     */
    @Test//用@Test,就可以独立的执行这代码
    public void test1() {
        //1.获取JDBCTemplate对象

        //2.定义sql
        String sql = "update emp set salary = 1000 where id = 1";
        //3.执行sql
        int count = template.update(sql);
        System.out.println(count);
    }

    /**
     * 修改2添加一条记录
     */
    @Test
    public void test2() {
        //1.获取JDBCTemplate对象
        String sql = "insert into emp(id,NAME,dept_id) values (?,?,?)";
        int count = template.update(sql, 9, "郭蝈蝈", 2);
        System.out.println(count);
    }

    /**
     * 修改三:删除刚才添加的记录
     */
    @Test
    public void test3() {
        String sql = "delete from emp where id = ?";
        int count = template.update(sql,9);
        System.out.println(count);
    }

    /**
     * 修改四:查询id为1的记录,封装成Map集合
     * 注意,这个方法查询的结果集,长度只能是1
     * 将列名作为key,值作为value
     */
    @Test
    public void test4() {
        String sql = "select * from emp where id = ?";
        Map<String, Object> map = template.queryForMap(sql, 2);
        System.out.println(map);
        //{id=2, NAME=猪八戒, gender=男, salary=3600.0, join_date=2010-12-02, dept_id=2}
    }


    /**
     *修改五,查询所有记录,封装为list
     */
    @Test
    public void test5() {
        String sql = "select * from emp";
        List<Map<String, Object>> list = template.queryForList(sql);
        for (Map<String, Object> stringObjectMap : list) {
            System.out.println(stringObjectMap);

        }
    }

    /**
     * 修改六,查询所有记录,将其封装为Emp对象的List集合
     */
    @Test
    public void test6() {
        String sql = "select * from emp";
        List<Emp> query = template.query(sql,
                new RowMapper<Emp>() {
                    @Override
                    public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
                        Emp emp1 = new Emp();
                        int id = resultSet.getInt("id");
                        String NAME = resultSet.getString("NAME");
                        String gender = resultSet.getString("gender");
                        int salary = resultSet.getInt("salary");
                        Date join_date = resultSet.getDate("join_date");
                        int dept_id = resultSet.getInt("dept_id");
                        emp1.setId(id);
                        emp1.setName(NAME);
                        emp1.setGender(gender);
                        emp1.setSalary(salary);
                        emp1.setJoindate(join_date);
                        emp1.setDeptid(dept_id);
                        return emp1;
                    }
                });
        for (Emp emp : query) {
            System.out.println(emp);
        }
    }

    /**
     * 修改六_2,查询所有记录,将其封装为Emp对象的List集合
     */
    @Test
    public void test6_2() {
        String sql = "select * from emp";
        List<Emp> list = template.query(sql, new BeanPropertyRowMapper<>(Emp.class));
        for (Emp emp : list) {
            System.out.println(emp);
        }
    }

    /**
     * 修改7,查询总记录数
     */
    @Test
    public void test7() {
        String sql = "select count(id) from emp";
        Long total = template.queryForObject(sql,Long.class);
        //queryForObjcet,一般是用来查询聚合函数的。
        System.out.println(total);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值