文章目录
C3P0连接池
步骤:
- 导c3p0的jar包
- 创建配置文件并配置
- 创建核心对象 ComboPooledDataSource
- 获取连接 getConnection
C3P0初始化:
-
先导入两个包:(MySQL的驱动要确保已经导入,否则用不了)
- c3p0-0.9.5.2.jar
- mchange-commons-java-0.2.12.jar
-
创建配置文件:
-
在src目录下直接创建C3P0的配置文件,文件可以是c3p0-config.xml或c3p0.properties**(文件名及扩展名一定要一样,否则识别不了)**使用这两种方式进行配置时,只要将配置好的文件放入classpath文件夹下即可,在java代码当中不用显示的给出访问配置方式的代码,c3p0会自动识别
-
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://localhost:3306/databaseName</property> <property name="user">root</property> <property name="password">admin</property> <!-- 连接池参数 --> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数--> <property name="acquireIncrement">3</property> <!-- 关闭自动提交 --> <property name="autoCommitOnClose">false</property> <property name="initialPoolSize">5</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> <!-- 最大等待时间 --> <property name="checkoutTimeout">3000</property> <!-- 最大空闲回收时间 --> <property name="maxIdleTime">1000</property> </default-config> <!-- 使用自定义的配置读取连接池对象,如果要使用named-config里面配置初始化数据源,则只要使用一个带参数的ComboPooledDataSource构造器就可以了 --> <named-config name="oracle"> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/databaseName</property> <property name="user">root</property> <property name="password">admin</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">8</property> <property name="checkoutTimeout">1000</property> </named-config> </c3p0-config>
-
c3p0.properties:
#连接参数 c3p0.jdbcUrl=jdbc:mysql://localhost:3306/databaseName c3p0.driverClass=com.mysql.jdbc.Driver c3p0.user=root c3p0.password=admin #连接池参数 c3p0.acquireIncrement=3 c3p0.autoCommitOnClose=false c3p0.initialPoolSize=5 c3p0.minPoolSize=2 c3p0.maxPoolSize=10 c3p0.checkoutTimeout=3000 c3p0.maxIdleTime=1000
-
通过setters方法一个个地设置各个配置项(不推荐):
ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("com.mysql.jdbc.Driver"); cpds.setJdbcUrl("jdbc:mysql:///users"); cpds.setUser("root"); cpds.setPassword("admin");
-
创建C3P0工具类:
package top.linzeliang.web.dataSource.c3p0;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class C3P0Util {
private static DataSource ds = null;
static {
//仅仅在类被加载时系统创建一个连接池,自动识别配置文件
ds = new ComboPooledDataSource();
}
public static Connection getConnection() {
try {
//获取一个连接,已经存在的
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("获取连接失败!");
return null;
}
}
public static void closeConnection(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
//将连接返回连接池
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
创建C3P0测试类:
package top.linzeliang.web.dataSource.c3p0;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;
public class C3P0Demo {
@Test
public void test() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "CREATE TABLE user(id INT NOT NULL, username VARCHAR(18) NOT NULL, password VARCHAR(16) NOT NULL, PRIMARY KEY (id))";
try {
conn = C3P0Util.getConnection();
pstmt = conn.prepareStatement(sql);
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
C3P0Util.closeConnection(pstmt, conn);
}
}
}
好了,这就是C3P0的基本使用了
Druid连接池(由阿里巴巴提供的数据库连接池实现技术)
步骤:
- 导包
- 创建定义配置文件
- 加载配置文件
- 获取数据库连接池对象,通过工厂来获取DruidDataSourceFactory
- 获取连接 getConnection
Druid初始化:
-
同样,先导入包:(MySQL的驱动也要确保导入)
- druid-1.1.23.jar
-
创建配置文件:
-
要以properties后缀名结尾,我的是 druid.properties
-
druid.properties
driverClassName=com.mysql.jdbc.Driver //驱动加载 url=jdbc:mysql://127.0.0.1:3306/student?characterEncoding=utf-8 //注册驱动 username=root //连接数据库的用户名 password=admin //连接数据库的密码。 filters=stat //属性类型的字符串,通过别名的方式配置扩展插件, 监控统计用的stat 日志用log4j 防御sql注入:wall initialSize=2 //初始化时池中建立的物理连接个数。 maxActive=300 //最大的可活跃的连接池数量 maxWait=60000 //获取连接时最大等待时间,单位毫秒,超过连接就会失效。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 timeBetweenEvictionRunsMillis=60000 // 连接回收器的运行周期时间,时间到了清理池中空闲的连接,testWhileIdle根据这个判断 minEvictableIdleTimeMillis=300000 validationQuery=SELECT 1 //用来检测连接是否有效的sql,要求是一个查询语句。 testWhileIdle=true //建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis, 执行validationQuery检测连接是否有效。 testOnBorrow=false //申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。设置为false testOnReturn=false //归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能,设置为flase poolPreparedStatements=false //是否缓存preparedStatement,也就是PSCache。 maxPoolPreparedStatementPerConnectionSize=200 // 池中能够缓冲的preparedStatements语句数量
-
-
可以放在任意位置(通过反射来获取该文件)
-
加载配置文件:
//加载配置文件 Properties pro = new Properties(); InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); //获取连接对象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); //获取连接 Connection conn = ds.getConnection();
-
创建Druid工具类:
package top.linzeliang.web.dataSource.druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.io.InputStream;
import java.sql.Connection;
public class DruidUtil {
private static DataSource ds = null;
static {
try {
//加载配置文件
Properties pro = new Properties();
InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//获取连接对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("获取连接失败");
return null;
}
}
public static void closeConnection(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
//将连接返回给连接池
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
创建Druid测试类:
package top.linzeliang.web.dataSource.druid;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DruidDemo {
@Test
public void test() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "UPDATE product SET product_name=? WHERE product_id=?";
try {
conn = DruidUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "6666");
pstmt.setString(2, "0009");
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtil.closeConnection(pstmt, conn);
}
}
}
Spring JDBC
Spring JDBC:Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
步骤:
- 导包:
- commons-logging-1.2.jar
- spring-beans-5.1.5.RELEASE.jar
- spring-core-5.1.5.RELEASE.jar
- spring-jdbc-5.1.5.RELEASE.jar
- spring-tx-5.1.5.RELEASE.jar
- 创建JdbcTemplate对象(依赖于DataSource对象):
- JdbcTemplate template = new JdbcTemplate(dataSource)
- 调用JdbcTemplate的方法来完成CRUD操作
常用方法:
-
update():执行DML语句,及对数据的增、删、改(查是DQL语句)
-
queryForMap():将列名作为key、值作为value将这条记录封装为一个Map集合**(这个方法查询的结果只能有一条记录,如果出现了两条就会报错)**
-
queryForList():将结果集封装为List集合**(一个Map对应一个记录,List将这些Map装起来)**
-
query():将结果封装为JavaBean对象
-
query的参数:RowMapper
package top.linzeliang.web.dataSource.SpringJDBC; import java.util.Date; public class Product { private String product_id; private String product_name; private String product_type; private Integer sale_price; private Integer purchase_price; private Date regist_date; public String getProduct_id() { return product_id; } public void setProduct_id(String product_id) { this.product_id = product_id; } public String getProduct_name() { return product_name; } public void setProduct_name(String product_name) { this.product_name = product_name; } public String getProduct_type() { return product_type; } public void setProduct_type(String product_type) { this.product_type = product_type; } public Integer getSale_price() { return sale_price; } public void setSale_price(Integer sale_price) { this.sale_price = sale_price; } public Integer getPurchase_price() { return purchase_price; } public void setPurchase_price(Integer purchase_price) { this.purchase_price = purchase_price; } public Date getRegist_date() { return regist_date; } public void setRegist_date(Date regist_date) { this.regist_date = regist_date; } @Override public String toString() { return "Product{" + "product_id='" + product_id + '\'' + ", product_name='" + product_name + '\'' + ", product_type='" + product_type + '\'' + ", sale_price=" + sale_price + ", purchase_price=" + purchase_price + ", regist_date=" + regist_date + '}'; } }
然后:
package top.linzeliang.web.dataSource.SpringJDBC; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import top.linzeliang.web.util.DruidUtil; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; public class JDBCTemplate { @Test public void test() { JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource()); String sql = "SELECT * FROM product"; //使用匿名内部类,重写mapRow方法 List<Product> list = template.query(sql, new RowMapper<Product>() { @Override public Product mapRow(ResultSet rs, int i) throws SQLException { Product product = new Product(); product.setProduct_id(rs.getString(1)); product.setProduct_name(rs.getString(2)); product.setProduct_type(rs.getString(3)); product.setSale_price(rs.getInt(4)); product.setPurchase_price(rs.getInt(5)); product.setRegist_date(rs.getDate(6)); return product; } }); for (Product p : list) { System.out.println(p); } } } 结果: 九月 14, 2020 12:33:40 上午 com.alibaba.druid.pool.DruidDataSource info 信息: {dataSource-1} inited Product{product_id='0001', product_name='T恤衫', product_type='衣服', sale_price=1000, purchase_price=500, regist_date=2009-09-20} Product{product_id='0002', product_name='打孔器', product_type='办公用品', sale_price=500, purchase_price=320, regist_date=2009-09-11} Product{product_id='0003', product_name='运动T恤', product_type='衣服', sale_price=4000, purchase_price=2800, regist_date=null} Product{product_id='0004', product_name='菜刀', product_type='厨房用具', sale_price=3000, purchase_price=2800, regist_date=2009-09-20} Product{product_id='0005', product_name='高压锅', product_type='厨房用具', sale_price=6800, purchase_price=5000, regist_date=2009-01-15} Product{product_id='0006', product_name='叉子', product_type='厨房用具', sale_price=500, purchase_price=0, regist_date=2009-09-20} Product{product_id='0007', product_name='擦菜板', product_type='厨房用具', sale_price=880, purchase_price=790, regist_date=2008-04-28} Product{product_id='0008', product_name='圆珠笔', product_type='办公用品', sale_price=100, purchase_price=0, regist_date=2009-11-11} Product{product_id='0009', product_name='123456789', product_type='2', sale_price=3, purchase_price=4, regist_date=null}
-
但是这样子写有没有感觉还是太繁琐了,所以一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装,同样,可得到一样的结果
-
new BeanPropertyRowMapper<类型>(类型.class)
package top.linzeliang.web.dataSource.SpringJDBC; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import top.linzeliang.web.util.DruidUtil; import java.util.List; public class JDBCTemplate { @Test public void test() { JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource()); String sql = "SELECT * FROM product"; List<Product> list = template.query(sql, new BeanPropertyRowMapper<Product>(Product.class)); for (Product p : list) { System.out.println(p); } } }
-
-
-
queryForObject():将聚合查询结果封装为指定类型的对象(一般用于聚合函数的查询)
package top.linzeliang.web.dataSource.SpringJDBC; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate; import top.linzeliang.web.util.DruidUtil; public class JDBCTemplate { @Test public void test() { JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource()); String sql = "SELECT COUNT(*) FROM product"; int count = template.queryForObject(sql, Integer.class); /*这里填写的Integer.class是将来你的结果封装的类型,因为我们COUNT(*)查询结果是整数,所以我们使用Integer类型*/ System.out.println(count); } }