什么是连接池?
连接池就是一个存放数据连接的容器;当系统初始化完毕后;容器被创建;容器中会申请一些连接器对象;当当用户访问数据库是就会从连接池中获取连接池对象;当用户访问完毕后就会将连接器对象归还给连接池
用连接池有什么好处?
首先是可以节约资源;其次是可以令用户高效访问
连接池该如何实现?
在javax.sql包下有一个DataSoure
接口;该接口就称为连接池;可以使用该接口获取连接getConnection()
;
也可以归还连接Connection.close()
另外如果连接对象是从连接池中获取的;那么调用close()
时不会关闭连接而是将连接对象归还到连接池
一般是由数据库厂商来实现的;而我们只需要使用他们实现的技术
首先要导入两个jar包;c3p0-0.9.5.2.jar ; mchange-commons-java-0.2.12.jar
第二个jar包是第一个jar包的依赖;提取码:v0pw
在项目结构中可以添加jar包
然后我们需要定义配置文件;配置文件的名称c3p0.properties 或者 c3p0-config.xml
提供了第二种的配置文件;路径就放在src目录下即可;提取码:v0pw
需要对配置文件进行修改
创建核心对象 数据库连接池对象 ComboPooledDataSource
获取连接
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class jdbc_1 {
public static void main(String[] args) throws SQLException {
DataSource ds = new ComboPooledDataSource(); //创建数据库连接池对象
Connection connection = ds.getConnection(); //获取连接对象
System.out.println(connection);
}
}
首先导入jar包 :druid-1.0.9.jar
提取码:8q10
加载配置文件
通过DruidDataSourceFactory
获取数据库连接对象
有了连接池就可以获取连接对象了
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
public class jdbc_3 {
public static void main(String[] args) throws Exception {
//加载配置文件
Properties properties = new Properties(); //创建properties类对象
InputStream resourceAsStream = jdbc_3.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(resourceAsStream);
//获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); //获取连接池对象
//获取连接对象
Connection connection = dataSource.getConnection(); //获取连接
System.out.println(connection); //输出查看该连接对象
}
}
为什么要定义工具类?
由于存在大量固定代码;那么就可以创建JDBCUtils类来将代码进行简化
代码如下:(可以看注释)
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtils { //连接池工具类
private static DataSource dataSource; //一个连接池成员变量
static { //未了实现赋值可以使用静态代码块
try {
//加载配置文件
Properties properties = new Properties();
properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//获取连接池对象
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException { //返回一个连接对象的方法
return dataSource.getConnection(); //返回一个连接对象
}
public static void close(Statement statement, Connection connection) { //释放资源的方法
close(null, statement, connection); //由于代码下面的相同;所以可以将结果集设为null从而调用下面的方法
}
public static void close(ResultSet resultSet, Statement statement, Connection connection) { //同上
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static DataSource getDataSource() { //获取连接池对象
return dataSource;
}
}
这样一个工具类就写好了;接下来就可以用到
Spring框架可以说是Java的灵魂框架;其中它提供了一个JDBCTemplate
对象简化JDBC的开发
如何操作?
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource()); //创建jdbcTemplate
JdbcTemplate
的方法来完成CRUD的操作;通常有以下几种方法方法名 | 说明 |
---|---|
update() | 执行DML语句。增、删、改语句 |
queryForMap() | 查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合 |
queryForList() | 查询结果将结果集封装为list集合 |
query() | 查询结果,将结果封装为JavaBean对象 |
queryForObject | 查询结果,将结果封装为对象 |
下面对方法进行演示
//这是需要导入的包
import day_6.util.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
public class jdbc_6 {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource()); //JdbcTemplate对象
//我们可以写各种各样的方法然后可以通过注解@Test
来进行测试
//增加一条记录的方法;使用update()
@Test
public void test1() {
String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; //预处理语句
int i = jdbcTemplate.update(sql, 1015, "小红", "10");
System.out.println(i); //返回影响行数
}
//删除一条记录的方法;使用update()
@Test
public void test2() {
String sql = "delete from emp where id =?"; //预处理语句
int i = jdbcTemplate.update(sql, 1015);
System.out.println(i); //返回影响行数
}
//修改一条记录的方法;使用update()
@Test
public void test3() {
String sql = "update emp set salary = ? where id = ? ";//预处理语句
int i = jdbcTemplate.update(sql, 10000, 1001);
System.out.println(i); //返回影响行数
}
//查询id为1001的记录,将其封装为Map集合;使用queryForMap()
需要注意的是:这个方法查询的结果集长度只能是1;也就是正能有一条记录;多了就会出错
@Test
public void test4() {
String sql = "select * from emp where id =?";
Map<String, Object> map = jdbcTemplate.queryForMap(sql, 1001);
System.out.println(map); //查看记录
}
//查询所有记录,将其封装为List;使用queryForList()
需要注意的是:这个方法是将每一条记录先装到Map集合
中然后再添加到List集合
的
@Test
public void test5() {
String sql = "select * from emp";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
System.out.println(maps); //查看所有记录
}
//查询所有记录,将其封装为Emp对象的List集合;使用query()
查询结果是将结果封装为JavaBean对象;
query的参数:RowMapper
@Test
public void test6() { //将每条封装成emp对象
String sql = "select * from emp";
List<Emp> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
for (Emp emp :
list) {
System.out.println(emp);
}
}
//查询总记录数;使用queryForObject()
;一般用于聚合函数的查询
@Test
public void test8() { //查询所有记录
String sql = "select count(id) from emp";
Long total = jdbcTemplate.queryForObject(sql, long.class);
System.out.println(total);
}
}