使用数据库连接池的方式连接数据库
可以把连接池当做一个容器,当我们需要访问数据库时,从连接池中取出一个连接对象。当使用完后,会将连接对象归还给容器。
这种方式比较节省资源:避免了频繁建立连接与关闭连接,使得用户访问比较高效。
在这里介绍两种数据库连接池:
1.C3P0:数据库连接池技术
步骤:
-
导入jar包
-
定义配置文件,c3p0.properties或者c3p0-config.xml。将其放到src目录下
-
创建核心对象 数据库连接池对象 ComboplloedDateSource
-
获取连接
测试代码:
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class C3P0ConnectionTest {
public static void main(String[] args) throws SQLException {
//1.创建核心对象,数据库连接池对象 ComboPooledDataSource
//去找默认名称的配置文件
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2.获取连接
Connection connection = dataSource.getConnection();
PreparedStatement stat = null;
String sql = "select * from c";
stat = connection.prepareStatement(sql);
ResultSet result = stat.executeQuery();
List list = new ArrayList();
while (result.next()){
String no = result.getString("cno");
String name = result.getString("cname");
String teacher = result.getString("cteacher");
list.add(no);
list.add(name);
list.add(teacher);
}
for (Object o:list){
System.out.print(o);
}
}
}
c3p0-config.xml
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/student</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
c3p0.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student
user=root
password=123456
此时还有比较费事的地方是需要自己定义ResultSet 集合来接收查询结构,如果是有条件查询时,同时还需要定义一个变量来接收变量,比较费事。
2.Druid 数据库连接池技术 阿里巴巴提供的
步骤
- 导入jar包
- 定义配置文件 是properties形式的,建议放在src路径下,可以叫任意名称,放在任意目录下
- 加载配置文件 properties
-
获取数据连接池对象,通过工厂获取 DruidDataSourceFactory
- 获取连接
测试代码:
package Nov13th.DataBasePool.Druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import util.JDBCUtil;
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;
public class DruidTest {
public static void main(String[] args) throws SQLException {
PreparedStatement stat = null;
try {
//读取资源文件
Properties pro = new Properties();
//拿到关联匹配文件的流
InputStream in = JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
//加载流中的数据
pro.load(in);
//连接池对象
dataSource = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
String sql = "select * from c";
stat = con.prepareStatement(sql);
ResultSet result = stat.executeQuery();
List list = new ArrayList();
while (result.next()){
String no = result.getString("cno");
String name = result.getString("cname");
String teacher = result.getString("cteacher");
list.add(no);
list.add(name);
list.add(teacher);
}
for (Object o:list){
System.out.print(o);
}
}
}
Druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/student
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
相同的时这个也需要自己新建ResultSet集合来接收查询结果,这里可以使用一个SpringJDBC插件来简化这个操作 曹,敲个屁的代码。
SpringJDBC
Spring框架对JDBC的简单封装,提供了一个JDBCTemplate对象简化JDBC的开发
步骤:
- 导入jar包
- 创建jdbcTemplate对象,依赖于源数据DataSource
JdbcTemplate template = new JdbcTemplate(datasource)
3.调用JdbcTmplate的方法来完成CRUD的操作
演示一下
先创建一个实体类:
public class C {
private Integer cno;
private String cname;
private String cteacher;
public C() {
}
public C(Integer cno, String cname, String cteacher) {
this.cno = cno;
this.cname = cname;
this.cteacher = cteacher;
}
public Integer getCno() {
return cno;
}
public void setCno(Integer cno) {
this.cno = cno;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCteacher() {
return cteacher;
}
public void setCteacher(String cteacher) {
this.cteacher = cteacher;
}
@Override
public String toString() {
return "C{" +
"cno=" + cno +
", cname='" + cname + '\'' +
", cteacher='" + cteacher + '\'' +
'}';
}
}
SpringJDBC测试类
import Nov13th.DataBasePool.util.JdbcUtils;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.Map;
public class SpringJDBCTest {
private JdbcTemplate template = null;
//测试之前先进行初始化
@Before
public void init(){
template = new JdbcTemplate(JdbcUtils.getDataSource());
}
//更新操作
@Test
public void Update(){
String sql = "update c set cname = '憨批' where cno= ?";
int i = template.update(sql,1);
if (i>0)
System.out.println("更新成功");
}
插入操作
@Test
public void Insert(){
String sql = "insert into c(cno,cname,cteacher) values(?,?,?)";
int i = template.update(sql, 6, "哲学 ", "佩");
if (i>0)
System.out.println("添加成功");
}
//删除操作
@Test
public void delete(){
String sql = "delete from c where cno = 6";
int i = template.update(sql);
if (i>0)
System.out.println("删除成功");
}
//查询一个结果
@Test
public void QueryForOne(){
String sql = "select * from emp where empno =?";
//queryFormap 只能查询一条记录,返回的是一个Map集合,可以在方法内添加不定量的参数
Map<String, Object> map = template.queryForMap(sql,7369);
System.out.println(map);
}
//查询所有记录,将其封装为List
@Test
public void QueryForAll(){
String sql = "select * from emp";
//queryForList 查询所有,返回所有的查询记录 返回的一个List集合,
//每一条记录以Map集合的形式存在,key是元素名,value是内容
List<Map<String, Object>> list = template.queryForList(sql);
for (Map<String,Object> map:list){
System.out.println(map);
}
}
@Test
//比较常用方式,以List的形式返回,每一条记录一个JavaBean对象
public void QueryForEntity(){
String sql = "select * from c";
//query()的参数RowMapper
//一般我们使用BeanPropertyRowMapper实现类,可以完成数据搭配JavaBean的自动封装
List<C> list = template.query(sql,new BeanPropertyRowMapper<C>(C.class));
for (C emp:list){
System.out.println(emp);
}
}
@Test
public void QueryForGroup(){
String sql = "select sum(sal) from emp ";
//一般用于分组函数
Object o = template.queryForObject(sql,Object.class);
System.out.println(o);
}
}
上面用到的工具类:
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
private static DataSource source;
static {
try {
Properties pro = new Properties();
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(in);
source = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
//返回数据源
public static DataSource getDataSource(){
return source;
}
//获取连接
public static Connection getConnection() throws SQLException {
return source.getConnection();
}
//关闭资源
public static void closeAll(AutoCloseable...all){
for (AutoCloseable a: all){
try {
a.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
SpringJDBC方法简介
- Update(sql,sql语句的条件参数) 可以用于增加、删除、修改等操作,返回的是一个int类型的数据,应该表示的是影响的几条数据
- queryForMap(Sql,sql语句的参数)只能查询一条数据,返回的是一个Map<String,Object> key 是元素名,values是内容
- queryForList(Sql,sql语句的条件参数) 查询多条记录 返回的一个List集合,每一条记录以Map集合的形式存在,key是元素名,value是内容
List<Map<String,Object>>
query(Sql,new BeanPropertyRowMapper<C>(实体类.class),sql语句的条件参数)
比较常用方式,以List的形式返回,每一条记录一个JavaBean对象
List<Map<String, Object>> list = template.queryForList(sql);
- query(Sql,Objct.class) 一般用于分组函数