发表于: 2017-11-30 21:44:15
1 760
今天完成的事情:
今天补了一下连接池的东西.
为什么必须使用数据库连接池:
普通的JDBC数据库连接(Connectiond对象)使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间),数据库的连接是比较昂贵的(创建的成本比较大)。
需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。
数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。
对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。
这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃.
在Java中,连接池使用javax.sql.DataSource接口来表示连接池.
DataSource(数据源)和连接池(Connection Pool)是同一个.
注意:DataSource仅仅只是一个接口,由各大服务器厂商来实现(Tomcat,JBoss).
常用的DataSource的实现:
C3P0: Hibernate框架推荐的(07年后不再更新,已经淘汰了)
DBCP: Spring框架推荐的
druid: 阿里巴巴的连接池(号称Java语言中性能最好的连接池)
==========================================================
使用连接池和不使用连接池的区别在哪里?
如何获取Connection对象:
未使用连接池:Connection conn = DriverManager.getConnection(url,username,password);
使用了连接池:
只要获取了Connection对象,接下来的操作和以前是一模一样的.
关键在于:如何创建DataSource对象.
如何释放Connection对象(Connection对象.close()):
未使用连接池: 是和数据库服务器断开.
在配置文件中添加druid连接池的配置文件.
连接池配置属性:
#key=value
#连接池配置文件必须按照格式来,不能乱写.
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/task1?useSSL=false
username=root
password=java
initalSize=5
因为看的教程是JDBC的,所以现在JDBC中使用连接池获取连接对象.将JdbcUtil工具更改为DruidUtil.
package com.myJDBC.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author Arike
* Create_at 2017/11/30 18:30
*/
public class DruidUtil {
private static DataSource ds;
static {
try {
Properties properties = new Properties();
InputStream in = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(in);
in.close();
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static void close(Connection con, Statement st, ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (st != null) {
st.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
和JDBC没有用连接池的区别就是,之前的连接从DriverManager()获取连接,更改之后从连接池DataSource获取.
配置到Spring配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--system-properties-mode="NEVER"是为了防止配置文件中的属性名称和系统的属性名称重复.-->
<context:property-placeholder location="classpath:druid.properties" system-properties-mode="NEVER"/>
<bean id="ds" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="initialSize" value="${initalSize}"/>
</bean>
</beans>
使用Spring配置文件获取到连接:
package com.myspring.di.context;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
/**
* @author Arike
* Create_at 2017/11/30 14:35
*/
public class PropertiesPlaceHolder {
public static void main(String[] args)throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/myspring/di/context/PropertiesPlaceHolderSpring.xml");
DataSource ds = ctx.getBean("ds", DataSource.class);
Connection con =ds.getConnection();
String sql = "SELECT * FROM t_student";
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
List<Student> list = new ArrayList<>();
while (rs.next()){
Student s = new Student(rs.getLong("id"),rs.getString("name"),rs.getInt("age"));
list.add(s);
}
System.out.println(list);
}
}
这里使用的是JDBC和预编译的方式执行SQL语句.
Spring和Mybatis怎么结合还没有看,先到这里
明天计划的事情:
将Mybatis和Spring结合,结束任务一.
遇到的问题:
JdbcTemplate 使用了反射比较多的东西,抽取通用集合集的方式没怎么看懂.以后用到再看,跳过了.
收获:
对第三方连接池,DBCP,druid有了了解和基本使用的认知.
禅道:
http://task.ptteng.com/zentao/project-burn-414.html
评论