我的 JDBC 学习笔记总结 第二部分,数据库连接池,JdbcTemplate

上期回顾

改进后的JDBC 帮助类

package com.chen.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JdbcHelper {
	
	private static String url = "jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
	private static String driver = "com.mysql.jdbc.Driver";
	private static String user = "root";
	private static String pwd = "root";
	
	static {
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 获取数据库连接
	 * @return connection 
	 */
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, user, pwd);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
}

我们可以看到,每次请求连接的时候,都需要重新获取连接DriverManager.getConnection(url, user, pwd);
这样一个过程非常耗费资源,所以我们使用了数据库连接池来优化

今日知识学习 数据库连接池,JdbcTemplate

数据库连接池

  1. 初始化后创建数据库连接池,
  2. 每次请求,不想数据库申请连接,改向数据库连接池来申请(租借)连接来节约资源、更加高效的获取
  3. 连接结束后,将连接归还给数据库连接池

数据库连接池实现接口 javax.sql.DataSource


package javax.sql;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Wrapper;

public interface DataSource  extends CommonDataSource, Wrapper {
	//不带参数的获取连接
	  Connection getConnection() throws SQLException;
  //带参数的获取连接
	  Connection getConnection(String username, String password) throws SQLException;
}

下面是我模拟实现的数据库连接池

package cheng.jdbc;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

import javax.sql.DataSource;

/**
 * 自定义的数据库连接池
 * @author newChenyingtao
 */
public class DataSourceUtil implements DataSource {
	// 数据库连接池集合
	private List<Connection> pool;

	private String url = "jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
	private String driver = "com.mysql.jdbc.Driver";
	private String user = "root";
	private String pwd = "root";

	public Connection getOneConnection(){
		Connection conn = null;
		try {
			// 1. 过程1 加载数据库驱动
			Class.forName(driver);
			// 2 过程2  向数据库申请连接
			conn = DriverManager.getConnection(url, user, pwd);
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	@Override
	public Connection getConnection(){
		Connection conn = null;
		if(pool == null) {
			// 如果第一次访问,新建数据库
			pool = new LinkedList<>();
			for(int i = 0; i < 5; i++) {
				pool.add(getOneConnection());
			}
		} 
		if(pool.size() <= 0) {
			//当前数据库线程池连接用尽,需要等待
		}
		if(pool.size() > 0) {
			//数据库连接足够,分配到一个返回
			conn = pool.get(0);
			pool.remove(0);
		}
		return conn;
	}
	//自己写的,模拟方法
	public void close(Connection conn) {
		//归还连接的方法
		pool.add(conn);
	}

/*其他方法 因为没有重写,所以在此删除 自己写的时候,会要求继承很多方法
但只要具体关注  getConnection()方法即可*/
  • 使用C3P0:数据库连接池技术
    jar包两个:
    配置文件
  • Druid:数据库连接池技术
  • 导入jar包 com.alibaba.druid.pool.DruidDataSource
<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
</dependency>

定义工具类

package com.chen.jdbc;

import com.alibaba.druid.pool.DruidDataSource;
import javax.sql.DataSource;

/**
 * @ClassName DataSourceUtil
 * @Description TODO
 * @Author newChenyingtao
 * @Date 2020/6/20 10:51
 * @Version 1.0
 */
public class DataSourceUtil {

	// 定义配置文件 properties 任意名称和位置
	private static String url = "jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
	private static String driver = "com.mysql.jdbc.Driver";
	private static String user = "root";
	private static String pwd = "root";

	public static DataSource getDataSource(){
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setPassword(pwd);
		dataSource.setUsername(user);
		dataSource.setDriverClassName(driver);
		dataSource.setUrl(url);
		return dataSource;
	}
}

实现类

package com.chen.jdbc.dal;

import com.chen.jdbc.CloseHelper;
import com.chen.jdbc.DataSourceUtil;
import com.chen.jdbc.JdbcHelper;
import com.chen.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName UserDal
 * @Description 使用jdbc 实现的数据库操作层
 * @Author newChenyingtao
 * @Date 2020/6/19 16:08
 * @Version 1.0
 */

public class UserDal {

	// 无线程池,使用Jdbc帮助类,申请连接
	public List<User> findAll() throws SQLException {
		Connection conn = JdbcHelper.getConnection();
		String sql = "select * from sys_user";
		PreparedStatement ps = conn.prepareStatement(sql);
		List<User> list = new ArrayList<>();
		ResultSet rs = ps.executeQuery();
		while (rs.next()){
			User user = new User();
			user.setUser_id(rs.getInt(1));
			user.setUser_code( rs.getString(2));
			user.setUser_name(rs.getString(3));
			user.setUser_password( rs.getString(4));
			user.setUser_state( rs.getInt(5));
			list.add(user);
		}
		CloseHelper.close(conn, ps, rs);
		return list;
	}
	
	/**
	 * 使用了 dataSource  只修改了两句话
	 */
	public List<User> findAllByDataSource() throws SQLException {
	
		// 以下两句话改变
		DataSource dataSource = DataSourceUtil.getDataSource();
		Connection conn = dataSource.getConnection();
		
		// 以下未改变
		String sql = "select * from sys_user";
		PreparedStatement ps = conn.prepareStatement(sql);
		List<User> list = new ArrayList<>();
		ResultSet rs = ps.executeQuery();
		while (rs.next()){
			User user = new User();
			user.setUser_id(rs.getInt(1));
			user.setUser_code( rs.getString(2));
			user.setUser_name(rs.getString(3));
			user.setUser_password( rs.getString(4));
			user.setUser_state( rs.getInt(5));
			list.add(user);
		}
		return list;
	}
}

可以看到,使用数据库连接池,改变了我们获取Connection 的方法,提高了程序性能,但是,代码量好像并没有减少多少,所以我们使用

JdbcTemplate 简介

jdbcTemplate类似人DBUtils,用于操作Jdbc的工具类,它需要依赖于连接池DataSource(数据源)
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API
ODBC(Open Database Connectivity,ODBC)开放数据库连接,是微软公司开提供了一组对数据库访问的标准API(应用程序编程接口)
DBCP(DataBase Connection Pool)数据库连接池,是java数据库连接池的一种,由Apache开发
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

c3p0与dbcp区别
dbcp没有自动回收空闲连接的功能
c3p0有自动回收空闲连接功能

JdbcTemplate简介

Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
JdbcTemplate位于中。简化 JDBC的配置

步骤;

  1. 导入jar包:
  2. 创建jdbcTemplate对象,依赖于数据源datasource
    jdbcTemplate template = new jdbcTemplate(ds);
  3. 调用jdbctemplate来进行增删改查
    1. update(); 执行dml语句 增删改
    2. query() 查询 可以添加转换模式
    3. queryForObject() 用于聚合函数的查询 比如统计记录
    4. queryForMap() 封装为map 只能一条
    5. queryForList() 记录封装为map,再封装为List
package com.chen.jdbc.dal;

import com.chen.jdbc.CloseHelper;
import com.chen.jdbc.DataSourceUtil;
import com.chen.jdbc.JdbcHelper;
import com.chen.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName UserDal
 * @Description 使用jdbc 实现的数据库操作层
 * @Author newChenyingtao
 * @Date 2020/6/19 16:08
 * @Version 1.0
 */

@Repository
public class UserDal {
	
	// queryForObject 函数 统计总记录的条数
	public int count(){
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		String sql = "select count(sys_user.user_id) from sys_user";
		return jdbcTemplate.queryForObject(sql, Integer.class);
	}
	// 只能查询单个记录 queryForMap将结果封装到 Map 
	public Map selectOne(){
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		String sql = "select * from sys_user where user_id = ?";
		Map map = jdbcTemplate.queryForMap(sql, 12);
		System.out.println(map);
		return map;
	}
	// queryForList 将结果封装到 Map 中再封装到List
	public List selectAll(){
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		String sql = "select * from sys_user";
		List list = jdbcTemplate.queryForList(sql);
		return list;
	}
	
	// query函数  将记录封装到 Java 对象,需要实现RowMapper<User>接口,看上去代码和原生的一样多
	public List<User> selectAll2(){
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		String sql = "select * from sys_user";
		List<User> list = jdbcTemplate.query(sql, new RowMapper<User>() {
			@Override
			public User mapRow(ResultSet resultSet, int i) throws SQLException {
				User user = new User();
				user.setUser_id(resultSet.getInt("user_id"));
				user.setUser_code(resultSet.getString(2));
				user.setUser_name(resultSet.getString(3));
				user.setUser_password(resultSet.getString(4));
				user.setUser_state(resultSet.getInt(5));
				return user;
			}
		});
		return list;
	}
	//升级版本 new BeanPropertyRowMapper<User>(User.class)) 该对象是RowMapper的实现类,可以实现对象的转换 这才是我们使用 Jdbc Template 后的简化操作
	public List<User> selectAll3(){
		// 1. 获取数据库连接池
		// 2. 注入到 Jdbc Template 中
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		// 3. 注入sql语句
		String sql = "select * from sys_user";
		// 4. 执行 sql 语句,转换对象
		List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
		// 5. 返回对象
		return list;
	}

	// update 语句  增、删、改
	public int updateUser(){
		DataSource dataSource = DataSourceUtil.getDataSource();
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		String sql = "update base_dict set ";
		int x = jdbcTemplate.update(sql);
		return x;
	}
	/
	public int insertUser(){
		JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtil.getDataSource());
		String sql = "insert into sys_user values (?,?,?,?,?)";
		int x = jdbcTemplate.update(sql, "12","2015","Jacket","1234","1");
		return x;
	}
}

既然提到了依赖注入,我们就可以使用 spring来实现

配置思路
1. 配置数据库连接池
2. 配置JdbcTemplate,并且注入数据库连接池
3. 配置 Dao 操作语句
4. 执行

具体的实现,就放到下一期吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值