JDBC数据库连接池
1.概念
-
其实就是一个容器(集合),存放数据库连接的容器。
- 当系统初始化好后,容器被创建,容器中会申请一些数据库连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完数据库后回将连接归还给容器。
2.好处
- 节约资源
- 用户访问高效
2.实现
2.1 标准接口
- 标准接口:
DataSource
java.sql
包下的 - 方法
- 获取连接:
getConnection()
- 归还连接:
Connection.close().如果Connection是从连接池中获取的,那么close()方法,则不会关闭连接。而是归还连接
- 获取连接:
2.2 C3P0数据库连接池
1.依赖jar
包
- 地址连接:Mchange Commons Java,C3P0
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);
}
}
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();//归还连接不是关闭
}
}
}
}
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.获取连接
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();
}
}
}
4.Spring JDBC
4.1 概述
调用JdbcTemplate的方法来完成CRUD操作
-
update():执行DML语句。增、删、改语句。
-
queryForMap():查询结果,将结果集封装为map集合
-
queryForList():查询结果封装为list集合
-
query():查询结果返回为JavaBean对象
-
queryForObject:查询结果,将结果封装为对象。
4.2 简单使用
-
导入相关
jar
包 -
简单使用,但前提是要有数据库连接池
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+"条数据成功"); } }
4.3 测试模块的简单使用
-
在函数名上加上注解
@Test
,则改函数可以独立执行,不依赖主方法。
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("我被执行了");
}
}
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}
-
两条返回结果就报错。因为map的键具有唯一性。
-
没有返回的结果也会报错。
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); } }
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 + '}'; } }
-
第一种方法(比较繁琐,不建议使用)。
-
第二种方法
@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); } }
-
注:如果字段和
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); }
5.快捷键的补充
-
返回值:idea中
ctrl
+Alt
+V
快速生成返回值。 -
for循环:
iter
增强for循环,fori
普通for循环。
继续努力,终成大器!