数据库连接池
## 数据库连接池
1. 概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
1. 概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
2. 好处:
1. 节约资源
2. 用户访问高效
1. 节约资源
2. 用户访问高效
3. 实现:
1. 标准接口:DataSource (javax.sql包下)
1. 方法:
* 获取连接:getConnection()
* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
1. 标准接口:DataSource (javax.sql包下)
1. 方法:
* 获取连接:getConnection()
* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
2. 一般我们不去实现它,由数据库厂商来实现
1. C3P0:数据库连接池技术
2. Druid:数据库连接池实现技术,由阿里巴巴提供的
1. C3P0:数据库连接池技术
2. Druid:数据库连接池实现技术,由阿里巴巴提供的
4. C3P0:数据库连接池技术
* 步骤:
1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,(已保存在博客文件中,包括下面的xml文件)
* 不要忘记导入数据库驱动jar包
2. 定义配置文件:
* 名称: c3p0.properties 或者 c3p0-config.xml (根据帮助文档要求,保存在类目录文件夹(str文件夹)中)
* 步骤:
1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,(已保存在博客文件中,包括下面的xml文件)
* 不要忘记导入数据库驱动jar包
2. 定义配置文件:
* 名称: c3p0.properties 或者 c3p0-config.xml (根据帮助文档要求,保存在类目录文件夹(str文件夹)中)
* 路径:直接将文件放在src目录下即可。
3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
4. 获取连接: getConnection
4. 获取连接: getConnection
1 package cn.ftf.datasource.c3p0;
2
3 import com.mchange.v2.c3p0.ComboPooledDataSource;
4
5 import javax.sql.DataSource;
6 import java.sql.Connection;
7 import java.sql.SQLException;
8
9 /**
10 * c3p0演示
11 */
12 public class C3P0Demo2 {
13
14 public static void main(String[] args) throws SQLException {
15 /* //1. 获取DataSource,使用默认配置
16 DataSource ds = new ComboPooledDataSource();
17
18 //2.获取连接
19
20 for (int i = 1; i <= 11 ; i++) {
21 Connection conn = ds.getConnection();
22 System.out.println(i+":"+conn);
23
24 if(i == 5){
25 conn.close();//归还连接到连接池中
26 }
27 }*/
28
29 //testNamedConfig();
30
31 }
32
33
34 public static void testNamedConfig() throws SQLException {
35 // 1.1 获取DataSource,使用指定名称配置
36 DataSource ds = new ComboPooledDataSource("otherc3p0");
37 //2.获取连接
38 for (int i = 1; i <= 10 ; i++) {
39 Connection conn = ds.getConnection();
40 System.out.println(i+":"+conn);
41 }
42 }
43
44 }
5. Druid:数据库连接池实现技术,由阿里巴巴提供的
1. 步骤:
1. 导入jar包 druid-1.0.9.jar (已保存在博客文件收藏中,包括下面的properties文件)
2. 定义配置文件:
* 是properties形式的
* 可以叫任意名称,可以放在任意目录下
3. 加载配置文件。Properties
4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
5. 获取连接:getConnection
1 import com.alibaba.druid.pool.DruidDataSourceFactory;
2
3 import javax.sql.DataSource;
4 import java.io.InputStream;
5 import java.sql.Connection;
6 import java.util.Properties;
7
8 public class JdbcDemo3 {
9 public static void main(String[] args) throws Exception {
10 //导入jar包
11 //加载配置文件
12 Properties pro =new Properties();
13 InputStream in=JdbcDemo3.class.getClassLoader().getResourceAsStream("druid.properties");
14 pro.load(in);
15 //获取连接池对象
16 DataSource ds= DruidDataSourceFactory.createDataSource(pro);
17 //获取连接
18 Connection conn=ds.getConnection();
19 System.out.println(conn);
20
21 }
22 }
2,定义Druid工具类
1. 定义一个类 JDBCUtils
2. 提供静态代码块加载配置文件,初始化连接池对象
3. 提供方法
1. 获取连接方法:通过数据库连接池获取连接
2. 释放资源
3. 获取连接池的方法
1 import com.alibaba.druid.pool.DruidDataSourceFactory;
2
3 import javax.sql.DataSource;
4 import java.sql.Connection;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.sql.Statement;
8 import java.util.Properties;
9
10 public class JdbcUtils {
11
12 public static DataSource ds;
13
14 static {
15 try {
16 Properties pro =new Properties();
17 pro.load(JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
18 ds=DruidDataSourceFactory.createDataSource(pro);
19 }catch (Exception e) {
20 e.printStackTrace();
21 }
22 }
23 //获取连接池
24 public static DataSource getDataSource(){
25 return ds;
26 }
27 //获取连接
28 public static Connection getConnection() throws SQLException {
29 return ds.getConnection();
30 }
31 //关闭资源
32 public static void close(Statement stmt,Connection conn){
33 close(null,stmt,conn);
34 }
35 public static void close(ResultSet re,Statement stmt, Connection conn){
36 if (re!=null){
37 try {
38 re.close();
39 } catch (SQLException e) {
40 e.printStackTrace();
41 }
42 }
43 if (stmt!=null){
44 try {
45 stmt.close();
46 } catch (SQLException e) {
47 e.printStackTrace();
48 }
49 }
50 if (conn!=null){
51 try {
52 conn.close();
53 } catch (SQLException e) {
54 e.printStackTrace();
55 }
56 }
57 }
58 }
使用自定义的工具类简化数据库操作:
1 package cn.ftf.datasource.druid;
2
3 import cn.itcast.utils.JDBCUtils;
4
5 import java.sql.Connection;
6 import java.sql.PreparedStatement;
7 import java.sql.ResultSet;
8 import java.sql.SQLException;
9
10 /**
11 * 使用新的工具类
12 */
13 public class DruidDemo2 {
14
15 public static void main(String[] args) {
16 /*
17 * 完成添加操作:给account表添加一条记录
18 */
19 Connection conn = null;
20 PreparedStatement pstmt = null;
21 try {
22 //1.获取连接
23 conn = JDBCUtils.getConnection();
24 //2.定义sql
25 String sql = "insert into account values(null,?,?)";
26 //3.获取pstmt对象
27 pstmt = conn.prepareStatement(sql);
28 //4.给?赋值
29 pstmt.setString(1,"王五");
30 pstmt.setDouble(2,3000);
31 //5.执行sql
32 int count = pstmt.executeUpdate();
33 System.out.println(count);
34 } catch (SQLException e) {
35 e.printStackTrace();
36 }finally {
37 //6. 释放资源
38 JDBCUtils.close(pstmt,conn);
39 }
40 }
41
42 }
## Spring JDBC
* Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
* 步骤:
1. 导入jar包 (已上传到博客文件中)
2. 创建JdbcTemplate对象。依赖于数据源DataSource
* JdbcTemplate template = new JdbcTemplate(ds);
* Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
* 步骤:
1. 导入jar包 (已上传到博客文件中)
2. 创建JdbcTemplate对象。依赖于数据源DataSource
* JdbcTemplate template = new JdbcTemplate(ds);
3. 调用JdbcTemplate的方法来完成CRUD的操作
* update():执行DML语句。增、删、改语句
* queryForMap():查询结果
* update():执行DML语句。增、删、改语句
* queryForMap():查询结果
将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
* 注意:这个方法查询的结果集长度只能是1
* queryForList():查询结果将结果集封装为list集合
* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)
* queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询
* 注意:这个方法查询的结果集长度只能是1
* queryForList():查询结果将结果集封装为list集合
* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)
* queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询
1 package cn.ftf.jdbctemplate;
2
3 import cn.itcast.utils.JDBCUtils;
4 import org.springframework.jdbc.core.JdbcTemplate;
5
6 /**
7 * JdbcTemplate入门
8 */
9 public class JdbcTemplateDemo1 {
10
11 public static void main(String[] args) {
12 //1.导入jar包
13 //2.创建JDBCTemplate对象
14 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
15 //3.调用方法
16 String sql = "update account set balance = 5000 where id = ?";
17 int count = template.update(sql, 3);
18 System.out.println(count);
19 }
20 }
4. 练习:
* 需求:
1. 修改1号数据的 salary 为 10000
2. 添加一条记录
3. 删除刚才添加的记录
4. 查询id为1的记录,将其封装为Map集合
5. 查询所有记录,将其封装为List
6. 查询所有记录,将其封装为Emp对象的List集合
7. 查询总记录数
1 package cn.itcast.domain;
2
3 import java.util.Date;
4
5 public class Emp {
6 private Integer id;
7 private String ename;
8 private Integer job_id;
9 private Integer mgr;
10 private Date joindate;
11 private Double salary;
12 private Double bonus;
13 private Integer dept_id;
14
15
16 public Integer getId() {
17 return id;
18 }
19
20 public void setId(Integer id) {
21 this.id = id;
22 }
23
24 public String getEname() {
25 return ename;
26 }
27
28 public void setEname(String ename) {
29 this.ename = ename;
30 }
31
32 public Integer getJob_id() {
33 return job_id;
34 }
35
36 public void setJob_id(Integer job_id) {
37 this.job_id = job_id;
38 }
39
40 public Integer getMgr() {
41 return mgr;
42 }
43
44 public void setMgr(Integer mgr) {
45 this.mgr = mgr;
46 }
47
48 public Date getJoindate() {
49 return joindate;
50 }
51
52 public void setJoindate(Date joindate) {
53 this.joindate = joindate;
54 }
55
56 public Double getSalary() {
57 return salary;
58 }
59
60 public void setSalary(Double salary) {
61 this.salary = salary;
62 }
63
64 public Double getBonus() {
65 return bonus;
66 }
67
68 public void setBonus(Double bonus) {
69 this.bonus = bonus;
70 }
71
72 public Integer getDept_id() {
73 return dept_id;
74 }
75
76 public void setDept_id(Integer dept_id) {
77 this.dept_id = dept_id;
78 }
79
80 @Override
81 public String toString() {
82 return "Emp{" +
83 "id=" + id +
84 ", ename='" + ename + '\'' +
85 ", job_id=" + job_id +
86 ", mgr=" + mgr +
87 ", joindate=" + joindate +
88 ", salary=" + salary +
89 ", bonus=" + bonus +
90 ", dept_id=" + dept_id +
91 '}';
92 }
93 }
1 package cn.itcast.jdbctemplate;
2
3 import cn.itcast.domain.Emp;
4 import cn.itcast.utils.JDBCUtils;
5 import org.junit.Test;
6 import org.springframework.jdbc.core.BeanPropertyRowMapper;
7 import org.springframework.jdbc.core.JdbcTemplate;
8 import org.springframework.jdbc.core.RowMapper;
9
10 import java.sql.Date;
11 import java.sql.ResultSet;
12 import java.sql.SQLException;
13 import java.util.List;
14 import java.util.Map;
15
16 public class JdbcTemplateDemo2 {
17
18 //Junit单元测试,可以让方法独立执行
19
20
21 //1. 获取JDBCTemplate对象
22 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
23 /**
24 * 1. 修改1号数据的 salary 为 10000
25 */
26 @Test
27 public void test1(){
28
29 //2. 定义sql
30 String sql = "update emp set salary = 10000 where id = 1001";
31 //3. 执行sql
32 int count = template.update(sql);
33 System.out.println(count);
34 }
35
36 /**
37 * 2. 添加一条记录
38 */
39 @Test
40 public void test2(){
41 String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
42 int count = template.update(sql, 1015, "郭靖", 10);
43 System.out.println(count);
44
45 }
46
47 /**
48 * 3.删除刚才添加的记录
49 */
50 @Test
51 public void test3(){
52 String sql = "delete from emp where id = ?";
53 int count = template.update(sql, 1015);
54 System.out.println(count);
55 }
56
57 /**
58 * 4.查询id为1001的记录,将其封装为Map集合
59 * 注意:这个方法查询的结果集长度只能是1
60 */
61 @Test
62 public void test4(){
63 String sql = "select * from emp where id = ? or id = ?";
64 Map<String, Object> map = template.queryForMap(sql, 1001,1002);
65 System.out.println(map);
66 //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
67
68 }
69
70 /**
71 * 5. 查询所有记录,将其封装为List
72 */
73 @Test
74 public void test5(){
75 String sql = "select * from emp";
76 List<Map<String, Object>> list = template.queryForList(sql);
77
78 for (Map<String, Object> stringObjectMap : list) {
79 System.out.println(stringObjectMap);
80 }
81 }
82
83 /**
84 * 6. 查询所有记录,将其封装为Emp对象的List集合
85 */
86
87 @Test
88 public void test6(){
89 String sql = "select * from emp";
90 List<Emp> list = template.query(sql, new RowMapper<Emp>() {
91
92 @Override
93 public Emp mapRow(ResultSet rs, int i) throws SQLException {
94 Emp emp = new Emp();
95 int id = rs.getInt("id");
96 String ename = rs.getString("ename");
97 int job_id = rs.getInt("job_id");
98 int mgr = rs.getInt("mgr");
99 Date joindate = rs.getDate("joindate");
100 double salary = rs.getDouble("salary");
101 double bonus = rs.getDouble("bonus");
102 int dept_id = rs.getInt("dept_id");
103
104 emp.setId(id);
105 emp.setEname(ename);
106 emp.setJob_id(job_id);
107 emp.setMgr(mgr);
108 emp.setJoindate(joindate);
109 emp.setSalary(salary);
110 emp.setBonus(bonus);
111 emp.setDept_id(dept_id);
112
113 return emp;
114 }
115 });
116
117
118 for (Emp emp : list) {
119 System.out.println(emp);
120 }
121 }
122
123 /**
124 * 6. 查询所有记录,将其封装为Emp对象的List集合
125 */
126
127 @Test
128 public void test6_2(){
129 String sql = "select * from emp";
130 List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
131 for (Emp emp : list) {
132 System.out.println(emp);
133 }
134 }
135
136 /**
137 * 7. 查询总记录数
138 */
139
140 @Test
141 public void test7(){
142 String sql = "select count(id) from emp";
143 Long total = template.queryForObject(sql, Long.class);
144 System.out.println(total);
145 }
146
147 }
加油!期待明天更好的自己!