数据库连接池

对一个简单的数据库应用,由于对数据库的访问不是很频繁,这时可以简单地在需要访问数据库时,就新创建一个连接,就完后就关闭它,这样做也不会带来什么性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同而,频繁的建立、关闭连接,会极大地减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。

通过建立一个数据库连接池以及一套连接使用管理策略,可以达到连接复用的效果,使得一个数据库连接可以得到安全、高效的复用,避免了数据库连接频繁建立、关闭的开销。

数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。如:外部使用者可通过getConnection方法获取连接,使用完毕后再通过releaseConnection方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。

数据库连接池技术带来的好处:

1、资源重用

由于数据库连接得到重用,避免了频繁创建、释放链接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进行/线程数量)

2、更快地系统响应速度

数据库连接池在初始化过程中,往往已经创建了若干数据库连接池置于池中备用。此时连接的初始化工作均已完成,对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间

3、统一的连接管理,避免数据库连接泄露

在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。

目前数据库连接池产品是非常多的,主要有:

1、dbcp

dbcp,即DataBase Connection PoolApache出品,Spring开发组推荐使用的数据库连接池,开发较为活跃,是一个使用极为广泛的数据库连接池产品。不过从网上

2、c3p0

Hibernate开发组推荐使用的数据库连接池,它实现了数据源和JNDI的绑定

3、Proxool

Proxool的口碑较好,没什么负面评价(比如dbcp就是因为Hibernate认为它BUG太多Hibernate才不推荐使用的),也是Hibernate开发组推荐使用的数据库连接池,不过使用者不算多,开发不够活跃。这个连接池提供了连接池监控的功能,方便易用,便于发现连接池泄露的情况

基于Spring的JDBC基本框架搭建

先讲一下使用Spring实现JDBC,数据库连接池就用Spring开发组推荐的DBCP,DBCP需要三个jar包,先下载一下:

1、commons-dbcp-1.4.jar,官方网站上有,点我下载

2、commons.pool-1.6.jar,官方网站上有,点我下载

3、commons.collections4-4.0.jar,官方网站上有,点我下载

下载了这三个jar包之后请导入自己的工程中(注意MySql的包别忘记导入了),虽然dbcp和pool都出了dbcp2和pool2的版本,Apache官网上都可以下载,但是这里提供的还是dbcp1和pool1的版本下载地址,一个原因是dbcp2和pool2都只可以在JDK1.7及JDK1.7以上的版本运行,而dbcp1和pool1则可以在JDK1.6的版本运行,考虑到MyEclipse10默认自带的JRE就是1.6版本的,所以这里下载、使用dbcp1和pool1。想要dbcp2和pool2的可以自己去Apache官网下载,不过要注意,dbcp2必须和pool2一组,dbcp1必须和pool1一组,不可以混着用。

JDBC,我之前写过一篇文章,数据库建立和实体类都是用的原文章里面的,这里只是把原生的JDBC搬到Spring JDBC下而已,看下最基础的写法,再添加功能,学生管理类为:

public class StudentManager
{
private JdbcTemplate jdbcTemplate; private static StudentManager instance = new StudentManager(); public static StudentManager getInstance()
{
return instance;
} public JdbcTemplate getJdbcTemplate()
{
return jdbcTemplate;
} public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
{
this.jdbcTemplate = jdbcTemplate;
}
}

Spring的XML配置文件命名为jdbc.xml,jdbc.xml的写法为:

<?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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!-- 驱动包名 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- 数据库地址 -->
<property name="url" value="jdbc:mysql://localhost:3306/school?useUnicode=true&amp;characterEncoding=utf8;" />
<!-- 用户名 -->
<property name="username" value="root" />
<!-- 密码 -->
<property name="password" value="root" />
<!-- 最大连接数量 -->
<property name="maxActive" value="150" />
<!-- 最小空闲连接 -->
<property name="minIdle" value="5" />
<!-- 最大空闲连接 -->
<property name="maxIdle" value="20" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="30" />
<!-- 连接被泄露时是否打印 -->
<property name="logAbandoned" value="true" />
<!-- 是否自动回收超时连接 -->
<property name="removeAbandoned" value="true" />
<!-- 超时等待时间(以秒为单位) -->
<property name="removeAbandonedTimeout" value="10" />
</bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean> <bean id="studentManager" class="com.xrq.jdbc.StudentManager" factory-method="getInstance">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
</beans>

主函数为:

public static void main(String[] args)
{
ApplicationContext ac =
new ClassPathXmlApplicationContext("jdbc.xml");
System.out.println(StudentManager.getInstance());
System.out.println(StudentManager.getInstance().getJdbcTemplate());
}

运行没什么问题,得到StudentManager的引用地址和StudentManager中属性jdbcTemplate的引用地址,说明整个连接、注入都没问题。

JDBCTemple是Spring里面最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。除了JDBCTemplate,Spring还提供了NamedParameterJdbcTemplate和SimpleJdbcTemplate两个类,前者能够在执行查询时把值绑定到SQL里的命名参数而不是使用索引,后者利用Java 5的特性比如自动装箱、泛型和可变参数列表来简化JDBC模板的使用。具体使用哪个看个人喜好,这里使用JdbcTemplate,所以把JdbcTemplate添加到学生管理类中。

另外:

1、dbcp提供很多参数给用户配置,每个参数的意思都以注释的形式写在.xml里面了,更加具体要知道每个参数的意思可以上网查询一下

2、注意dbcp的属性url,url指的是数据库连接地址,遇到特殊字符需要转义,所以这里的"&"变成了"&amp;",不然会报错

基于Spring的JDBC增删改查

上面一部分搭建了一个Spring JDBC的基础框架,下面看一下Java代码如何实现CRUD,这个过程中jdbc.xml都不需要变化。

1、添加一个学生信息,代码为:

// 添加学生信息
public boolean addStudent(Student student)
{
try
{
jdbcTemplate.update("insert into student values(null,?,?,?)",
new Object[]{student.getStudentName(), student.getStudentAge(), student.getStudentPhone()},
new int[]{Types.VARCHAR, Types.INTEGER, Types.VARCHAR});
return true;
}
catch (Exception e)
{
return false;
}
}

2、根据Id删除指定学生信息,代码为:

// 根据Id删除单个学生信息
public boolean deleteStudent(int id)
{
try
{
jdbcTemplate.update("delete from student where studentId = ?", new Object[]{id}, new int[]{Types.INTEGER});
return true;
}
catch (Exception e)
{
return false;
}
}

3、根据Id更新学生信息,代码为:

// 根据Id更新指定学生信息
public boolean updateStudent(int Id, Student student)
{
try
{
jdbcTemplate.update("update student set studentName = ?, studentAge = ?, studentPhone = ? where studentId = ?",
new Object[]{student.getStudentName(), student.getStudentAge(), student.getStudentPhone(), Id},
new int[]{Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.INTEGER});
return true;
}
catch (Exception e)
{
return false;
}
}

4、根据Id查询学生信息,代码为:

// 根据学生Id查询单个学生信息
public Student getStudent(int id)
{
try
{
return (Student)jdbcTemplate.queryForObject("select * from student where studentId = ?",
new Object[]{id}, new int[]{Types.INTEGER}, new RowMapper<Student>(){
public Student mapRow(ResultSet rs, int arg1) throws SQLException
{
Student student = new Student(rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getString(4));
return student;
}
});
}
// 根据Id查询学生信息抛异常, 不管什么原因, 认为查询不到该学生信息, 返回null
catch (DataAccessException e)
{
return null;
}
}

5、查询所有学生信息,代码为:

// 查询所有学生信息
public List<Student> getStudents()
{
List<Map<String, Object>> resultList = jdbcTemplate.queryForList("select * from student");
List<Student> studentList = null;
if (resultList != null && !resultList.isEmpty())
{
studentList = new ArrayList<Student>();
Map<String, Object> map = null;
for (int i = 0; i < resultList.size(); i++)
{
map = resultList.get(i);
Student student = new Student(
(Integer)map.get("studentId"), (String)map.get("studentName"),
(Integer)map.get("studentAge"), (String)map.get("studentPhone")
);
studentList.add(student);
}
}
return studentList;
}

这就是简单的CRUD操作,有了这5个作为基础,其余都可以在这5个的基础上做扩展,就不继续详细写下去了,说几个注意点:

1、个人使用经验来说,除了最后一个查询所有的以外,建议给其他的都加上try...catch...块,因为在操作失败的时候会抛出异常,捕获了就可以知道这次的操作失败了,否则只能程序终止,而自己也不知道操作到底是成功还是失败

2、添加信息、更新信息不建议把每个待操作的字段都作为形参而建议形参就是一个Student实体类,这样一来更符合面向对象的设计原则,二来形参列表的字段多很容易导致出错

3、update、query方法,如果有占位符?的话,建议选择有参数类型的重载方法,指定每个占位符的字段类型,就像我上面代码写的那样

最后,这里讲的都是jdbcTemplate的基本使用,jdbcTemplate里面还有很多方法,就不一一细说了,可以自己去试一下,也可以查阅Spring API文档。

读取配置文件中的数据

之前我们都是把数据库连接的一些属性配置在db.properties里面的,这样方便修改,而这里却是在jdbc.xml里面写死的,所以要想一个办法怎么可以从db.properties里面读取出配置,context帮助开发者实现了这一点,看一下jdbc.xml如何写:

 <?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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!-- 驱动包名 -->
<property name="driverClassName" value="${mysqlpackage}" />
<!-- 数据库地址 -->
<property name="url" value="${mysqlurl}" />
<!-- 用户名 -->
<property name="username" value="${mysqlname}" />
<!-- 密码 -->
<property name="password" value="${mysqlpassword}" />
<!-- 最大连接数量 -->
<property name="maxActive" value="150" />
<!-- 最小空闲连接 -->
<property name="minIdle" value="5" />
<!-- 最大空闲连接 -->
<property name="maxIdle" value="20" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="30" />
<!-- 连接被泄露时是否打印 -->
<property name="logAbandoned" value="true" />
<!-- 是否自动回收超时连接 -->
<property name="removeAbandoned" value="true" />
<!-- 超时等待时间(以秒为单位) -->
<property name="removeAbandonedTimeout" value="10" />
</bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean> <bean id="studentManager" class="com.xrq.jdbc.StudentManager" factory-method="getInstance">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
</beans>

重点就是第10行,第14、第16、第18、第20行就是取属性的写法,和前端的FTL语言类似。

Spring4:JDBC的更多相关文章

  1. Weblogic常见故障常:JDBC Connection Pools(转)

    WebLogic Server中数据库连接池是一个经常出问题的地方,总结一下出问题的原因和解决办法. 一.数据库连接泄漏 此类问题一般都是由于开发人员没有正确关闭数据库连接造成的.比如使用完Conne ...

  2. 老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

      最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者 ...

  3. 笔记:JDBC 数据库

    数据库 URL 在连接数据库时,我们必须使用各种与数据库类型相关的参数,例如主机名.端口号和数据库名称等,JDBC使用了一种与普通URL相类似的语法来描述数据库,JDBC URL 一般语法为: jdb ...

  4. Weblogic常见故障常:JDBC Connection Pools【转】

    WebLogic Server中数据库连接池是一个经常出问题的地方,总结一下出问题的原因和解决办法. 一.数据库连接泄漏 此类问题一般都是由于开发人员没有正确关闭数据库连接造成的.比如使用完Conne ...

  5. 深入浅出学习Hibernate框架(二):JDBC基础操作

    上篇博客<深入浅出学习Hibernate框架(一):从实例入手初识Hibernate框架>简单介绍了一下Hibernate框架,并且举了一个实例来了解Hibernate.这篇博客将介绍JD ...

  6. Unit02: JDBC核心API

    Unit02: JDBC核心API db.properties 注意:如果使用连接池,可以在这个文件中增加对连接池的相关设置: 连接池参数,常用参数有: 初始连接数 最大连接数 最小连接数 每次增加的 ...

  7. Unit01: JDBC原理 、 JDBC基础编程

    Unit01: JDBC原理 . JDBC基础编程 这个文件里面有两块内容: 1.用比较麻烦的方式连接数据库,test1(),test4() 2.创建DBTool,测试DBTool连接数据库 ,tes ...

  8. mysql:JDBC url 参数详解

    MySql链接url参数详解 jdbc:mysql://[host:port],[host:port].../[database][?参数名1][=参数值1][&参数名2][=参数值2]... ...

  9. Java基础教程:JDBC编程

    Java基础教程:JDBC编程 1.什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC A ...

随机推荐

  1. css 等高布局

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. MySQL安装之后没有MySQL数据库的原因

    mysql安装完之后,登陆后发现只有两个数据库:mysql> show databases;+--------------------+| Database           |+------ ...

  3. MySQL 5.6 & 5.7最优配置模板

    摘自:http://mp.weixin.qq.com/s?__biz=MjM5MjIxNDA4NA==&mid=207854835&idx=1&sn=c998031ae6816 ...

  4. 移动端HTML5<video>视频播放优化实践[转]

    http://blog.csdn.net/u010918416/article/details/52705732 http://www.xuanfengge.com/html5-video-play. ...

  5. cassandra安装

    从官网下载下来的包解压后有100多M,里面包含了已经编译好的全部程序. 按照方法,进入目录后运行 bin/cassandra -f 运行不成功. 然后根据"https://wiki.apac ...

  6. 清空StringBuilder的三种方法及效率

    清空StringBuilder的三种方法及效率 大家知道对于字符串频繁拼接是使用stringbuilder.Append方法比使用string+=方法效率高很多,但有时需要清空stringbuilde ...

  7. 通过外部配置文件做mybatis的基础配置,以及Mapper代理接口的实现

    1.通过外部配置文件做mybatis的基础性的配置. 1)先编写config.properties的文件(做一些动态的配置). 配置的内容如下: jdbc.jdbcUrl=jdbc:oracle:th ...

  8. Hibernate和jsp做数据库单表的增删改查

    虽然很基础,但是我转牛角尖了~~~~这是几个文件 1.最重要的.Java文件 package com.chinasofti.hibb.struts; import org.hibernate.Sess ...

  9. Orchard源码--初步(1)

    1.打开解决方案Orachard.sln 2.直接启动项目调试 3.接着你会看到下图 呵呵,有点啰嗦( ̄︶ ̄)↗ 涨 4.点击上图的‘Finish Setup’后

  10. CentOS 7 关闭防火墙

    CentOS 7.0默认使用的是firewall作为防火墙 直接关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable ...