hive durid连接池 hive jdbc连接池
转载
连接池
一、预编译对象
0. SQL注入漏洞
- SQL注入:通过输入一些特殊的参数值,在拼接SQL时,导致SQL语句的结构发生变化,绕过了SQL的条件
- 解决方案:使用预编译对象preparedStatement代替Statement
1. 什么是预编译对象
- 预编译对象:
PreparedStatement
是Statement
的子接口,是另外一种SQL执行平台,用来执行SQL语句的
2. ==怎样使用预编译对象==
//1.注册驱动
//2.获取连接
//3.创建SQL执行平台:预编译对象PreparedStatement
//3.1 改造SQL:SQL语句里的参数要使用?代替
//3.2 使用connection的方法,预编译SQL,得到预编译对象
//3.3 设置SQL参数值
//4 执行SQL语句
//5.处理结果
//6.释放资源
3. 预编译对象的原理和好处
- 减少编译次数,提高效率
- 解决SQL注入漏洞
- 提高程序可读性(SQL语句的可读性)
二、连接池
1. 什么是连接池
- 连接池:存储了一堆连接对象的容器。当我们要使用Connection时,不需要创建,而是从连接池中取出一个使用;当使用完成之后,要把Connection对象归还到连接池里。
- 好处:
- 少量连接,就可以支持大量的数据库操作
- 只要少量连接,避免了数据库可用连接被占用完
- 只要少量连接,避免了创建的Connection过多造成的内存溢出
2. 自定义连接池
3. 装饰者模式
3.1 可以对某一对象的方法增强的方式
- 继承重写父类方法
- 动态代理:调用代理对象,让代理对象调用目标对象;代理对象里进行增强(依赖于反射技术)
- 装饰者模式:包装类
3.2 装饰者模式
- 之前使用过的:
new BufferedReader(new FileReader())
:BufferedReader,对FileReader对象进行了功能增强 - 原理:见图
- 示例:有一个接口Man,有实现类普通人CommonMan,要进行功能增强,创建包装类:IronMan
public interface Man {
void eat();
void fight();
}
public class CommonMan implements Man {
@Override
public void eat() {
System.out.println("吃2碗");
}
@Override
public void fight() {
System.out.println("战斗力:5");
}
}
public class IronMan implements Man {
private Man commanMan;
public IronMan(Man commanMan) {
this.commanMan = commanMan;
}
@Override
public void eat() {
this.commanMan.eat();
}
@Override
public void fight() {
System.out.println("战斗力:99999");
}
}
public class WrapperTest {
public static void main(String[] args) {
//先有一个被包装的目标对象
Man man = new CommonMan();
//不增强,直接调用目标对象
man.eat();
man.fight();
System.out.println("-------------------------");
//创建一个包装类对象,进行功能增强
Man ironMan = new IronMan(man);
ironMan.eat();
ironMan.fight();
}
}
4. ==常见连接池的使用==
4.1 介绍
- 在实际开发中,不需要自己写连接池。市面上有一些成熟的连接池工具,功能更强大
- 所有的连接池,都实现了JDBC规范的一个接口:
javax.sql.DataSource
。所有连接池使用的基本步骤:
- 创建连接池对象:连接池的类名不同
- 从连接池中获取连接:
getConnection()
- 使用连接操作数据库
- 操作完成归还到连接池:
close()
- dbcp:Apache提供的开源、免费的连接池工具
- c3p0:是一个开源的、免费的连接池工具,使用的很多,方便,功能比dbcp要强
- druid:Alibaba的开源的、免费的、高效的连接池工具。
4.2 c3p0连接池的使用
4.2.1 c3p0使用步骤
- 导入jar包
- 提供配置文件
- 编写代码,使用连接池
4.2.2 c3p0的配置文件
- 名称必须是:c3p0-config.xml
- 位置必须在:src下(类加载路径下)
- 配置示例
<c3p0-config>
<default-config>
<!--前边四项是必须配置的-->
<!--驱动类名-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!--数据库url地址-->
<property name="jdbcUrl">jdbc:mysql:///heima62</property>
<!--数据库登录名-->
<property name="user">root</property>
<!--数据库密码-->
<property name="password">root</property>
<!--以下非必须配置项-->
<!--最大等待时间-->
<property name="checkoutTimeout">30000</property>
<!--初始化容量-->
<property name="initialPoolSize">10</property>
<!--连接的最大空闲时间-->
<property name="maxIdleTime">30</property>
<!--连接池最大容量-->
<property name="maxPoolSize">100</property>
<!--连接池最小容量-->
<property name="minPoolSize">10</property>
</default-config>
<!-- This app is massive! -->
<named-config name="heima">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///heima</property>
<property name="user">root</property>
<property name="password">root</property>
</named-config>
</c3p0-config>
4.2.3 编写代码,使用c3p0连接池
public class DemoC3p0 {
/**
* 无参构造,加载的是配置文件中的默认配置:default-config
*/
@Test
public void test1() throws SQLException {
//1. 创建连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2.从连接池中获取连接
Connection connection = dataSource.getConnection();
//3.创建SQL执行平台
PreparedStatement preparedStatement = connection.prepareStatement("select * from emp");
//4.执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
//5.处理结果
while (resultSet.next()) {
String ename = resultSet.getString("ename");
double salary = resultSet.getDouble("salary");
System.out.println("ename:" + ename + ", salary:" + salary);
}
//6.释放资源
resultSet.close();
preparedStatement.close();
connection.close();//归还到连接池
}
/**
* 加载配置文件中,heima的配置
*/
@Test
public void test2() throws SQLException {
//1.创建连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource("heima");
//2.获取连接
Connection connection = dataSource.getConnection();
//3.创建SQL执行平台
PreparedStatement preparedStatement = connection.prepareStatement("select * from account");
//4.执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
//5.处理结果
while (resultSet.next()) {
String name = resultSet.getString("name");
double money = resultSet.getDouble("money");
System.out.println("name:" + name + ", money: " + money);
}
//6.释放资源
resultSet.close();
preparedStatement.close();
connection.close();
}
}
4.3 druid连接池的使用
4.3.1 使用步骤
- 导入jar包:
- 提供配置文件
- 编写代码,使用连接池
4.3.2 提供配置文件
- 文件名:xxx.properties
- 文件位置:建议放在src下(类加载路径下)
- 示例
#数据库的url地址
url=jdbc:mysql:///heima62
#数据库的用户名
username=root
#数据库密码
password=root
#数据库的驱动类名
driverClassName=com.mysql.jdbc.Driver
#连接池初始化容量
initialSize=30
#连接池最大容量
maxActive=50
#连接池最小容量
minIdle=10
4.3.3 编写代码,使用druid连接池
public class DemoDruid {
/**
* 读取配置文件,使用druid连接池
*/
@Test
public void test() throws Exception {
//0.自己读取配置文件,得到properties对象
Properties properties = new Properties();
InputStream inputStream = DemoDruid.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(inputStream);
//1.得到一个连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//2.得到一个连接对象
Connection connection = dataSource.getConnection();
//3.创建SQL执行平台
PreparedStatement preparedStatement = connection.prepareStatement("select * from emp");
//4.执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
//5.处理结果
while (resultSet.next()) {
String ename = resultSet.getString("ename");
double salary = resultSet.getDouble("salary");
System.out.println("ename:" + ename + ", salary:" + salary);
}
//6.释放资源
resultSet.close();
preparedStatement.close();
connection.close();//已经增强了:归还到连接池
inputStream.close();
}
}
5. 封装工具类
- 连接池对象,一个项目中只要一个就可以了,通常设置成某个类的静态变量
- 对JdbcUtils进行改造
- 静态代码块里:读取配置文件,得到配置信息
- 提供getConnection方法:使用配置信息,创建连接
- 提供close方法:释放资源
- 提供一个静态变量:连接池对象
- 提供getConnection方法:从连接池里获取连接
- 提供close方法:释放资源
内容总结
- 掌握预编译对象的使用
- 改造SQL语句:把参数写成占位符
?
- 编译SQL,得到预编译对象:
PreparedStatement pstmt = connection.prepareStatement(sql)
- 设置SQL的参数值:
pstmt.setXXX(参数序号, 参数值)
- 执行SQL语句:
pstmt.executeQuery()
;pstmt.executeUpdate()
- 预编译对象的好处:
- 解决了SQL注入漏洞
- 性能高:同一语句,只要编译一次,可以执行多次
- 提高可读性:SQL语句易读
- 理解装饰者模式:进行方法的功能增强
- 理解连接池的原理:
- 理解连接池的好处:
- 效率高
- 连接循环使用:
- 少量连接,可以支持大量的数据库操作;不用创建大量的Connection对象,避免内存溢出
- 创建的连接少了,避免数据库所有可用连接,都被占用,导致没有连接可用
- 掌握c3p0/druid连接池的使用
- 导入jar包
- 提供配置文件
- 无论什么连接池,都有一些必须的配置项:
- 数据库连接地址
- 数据库的用户名
- 数据库的密码
- 数据库的驱动类名(建议提供)
- c3p0的配置文件:c3p0-config.xml,放在src下(类加载路径下)
- druid的配置文件:xxx.properties,建议放在src下
- 编写代码,使用连接池
- 创建一个连接池对象
- c3p0连接池对象的创建:
new ComboPooledDataSource()
- druid连接池对象的创建:
DruidDataSourceFactory.createDataSource(properties对象)
- 从连接池中获取一个连接:
getConnection()
- 使用连接操作数据库
- 归还到连接池:
connection.close()
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。