Spring DAO
Spring DAO
连接池
使用JDBC访问数据库是,频繁的打开连接和关闭连接,造成性能影响,所以有了连接池。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个,这项技术能明显提高对数据库操作的性能。
数据源(DataSource)
数据的来源,是提供某种所需要数据的器件或原始媒体。在数据源中存储了所有建立数据库连接的信息。通过提供正确的数据源名称,你可以找到相应的数据库连接。最终,我们通过DataSource来获取连接池(Connection Pool)中的Connection对象。
常见的开源连接池:Proxool Druid
Proxool
Proxool是一种Java数据库连接池技术。sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。
Proxool的常用属性:
driver: 驱动类
driverUrl: 连接字符串
user: 数据库登录名
password: 数据库登录密码
maximumConnectionCount: 最大连接数
minimumConnectionCount: 最小连接数
statistics: 连接池使用状况统计,值形如:1m,15m,1h,1d
simultaneousBuildThrottle:可一次建立的最大连接数
trace: 是否记录执行的sql语句
DataSource类:
DataSource代理: LazyConnectionDataSourceProxy
Proxool DataSource: ProxoolDataSource
示例:
<bean id="dataSource_proxool"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="driverUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<property name="user" value="scott" />
<property name="password" value="tiger" />
<property name="maximumConnectionCount" value="10" />
<property name="minimumConnectionCount" value="5" />
<property name="statistics" value="1m,15m,1h,1d" />
<property name="simultaneousBuildThrottle" value="30" />
<property name="trace" value="false" />
</bean>
</property>
</bean>
JdbcDaoSupport
JdbcDaoSupport作为DAO的父类。它与特定的数据源相关联。这个类最重要的功能就是使子类可以使用JdbcTemplate对象,而无需创建DriverManagerDataSource对象。
getJdbcTemplate()方法用于获取JdbcTemplate对象
示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="dataSource_proxool"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="driverUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<property name="user" value="scott" />
<property name="password" value="tiger" />
<property name="maximumConnectionCount" value="10" />
<property name="minimumConnectionCount" value="5" />
<property name="statistics" value="1m,15m,1h,1d" />
<property name="simultaneousBuildThrottle" value="30" />
<property name="trace" value="false" />
</bean>
</property>
</bean>
<bean id="deptDAO" class="com.trkj.dao.DeptDAO">
<property name="dataSource" ref="dataSource_proxool"></property>
</bean>
</beans>
resources.properties文件
资源属性文件
通常我们将数据的配置信息保存在properties文件中,方便阅读和修改。
示例:
db.driver.class=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
db.username=scott
db.password=tiger
proxool.maxConnCount=10
proxool.minConnCount=5
proxool.statistics=1m,15m,1h,1d
proxool.simultaneousBuildThrottle=30
proxool.trace=false
该类能让Spring读取到properties
示例:
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db-resource.properties</value>
</list>
</property>
</bean>
在Spring的xml配置文件中读取properties,和EL相同,${name}
示例:
<bean id="dataSource_proxool"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="driver" value="${db.driver.class}" />
<property name="driverUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maximumConnectionCount" value="${proxool.maxConnCount}" />
<property name="minimumConnectionCount" value="${proxool.minConnCount}" />
<property name="statistics" value="${proxool.statistics}" />
<property name="simultaneousBuildThrottle" value="${proxool.simultaneousBuildThrottle}" />
<property name="trace" value="${proxool.trace}" />
</bean>
</property>
</bean>
Druid
Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池。
配置方式跟Proxool无太大差别
示例:
<bean id="dataSource_druid"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="10" />
<property name="maxActive" value="30" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="testWhileIdle" value="false" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
<property name="defaultAutoCommit" value="true" />
<property name="ValidationQueryTimeout" value="60000" />
<property name="validationQuery" value="select 1" />
</bean>
</property>
</bean>
事务
是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
四个特征(ACID)原子性 一致性 隔离性 持久性
示例:
配置事务管理器
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource_druid" />
</property>
</bean>
启用事务注解
<tx:annotation-driven transaction-manager="transactionManager" />
@Transactional
修饰类或方法
常用属性
readOnly 只读,用于查询,提高效率
rollbackFor 抛出指定异常才会回滚
示例
@Transactional(rollbackFor = { Exception.class }, readOnly = true)
零配置
DAO不能继承自JdbcDaoSupport类,而是将JdbcTemplate注入进来
DAO使用@Repository标注
Service使用@Service标注
使用@Autowired自动注入
示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.trkj2" />
<bean id="dataSource_proxool"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="org.logicalcobwebs.proxool.ProxoolDataSource">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="driverUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<property name="user" value="scott" />
<property name="password" value="tiger" />
<property name="maximumConnectionCount" value="10" />
<property name="minimumConnectionCount" value="5" />
<property name="statistics" value="1m,15m,1h,1d" />
<property name="simultaneousBuildThrottle" value="30" />
<property name="trace" value="false" />
</bean>
</property>
</bean>
<bean id="dataSource_druid"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />
<property name="username" value="scott" />
<property name="password" value="tiger" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="10" />
<property name="maxActive" value="30" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="testWhileIdle" value="false" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
<property name="defaultAutoCommit" value="true" />
<property name="ValidationQueryTimeout" value="60000" />
<property name="validationQuery" value="select 1" />
</bean>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource_druid"></property>
</bean>
<!-- 事务管理器,这是一个切面,定义的是环绕通知 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource_druid" />
</property>
</bean>
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
package com.trkj2.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.trkj.pojos.Dept;
@Repository
public class DeptDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 新增部门
*
* @param deptNo
* @param dname
* @param loc
*/
public void addNew(int deptNo, String dname, String loc) {
String sql = "insert into dept values(?,?,?)";
jdbcTemplate.update(sql, deptNo, dname, loc);
}
/**
* 修改部门信息
*
* @param deptNo
* @param dname
* @param loc
*/
public void update(int deptNo, String dname, String loc) {
String sql = "update dept set dname=?, loc=? where deptno=?";
jdbcTemplate.update(sql, dname, loc, deptNo);
}
/**
* 删除部门
*
* @param deptNo
*/
public void delete(int deptNo) {
String sql = "delete from dept where deptno=?";
jdbcTemplate.update(sql, deptNo);
}
/**
* 分页查询
*
* @param curpage
* 当前页
* @param pagesize
* 页大小
* @return
*/
public List<Dept> queryByPage(int curpage, int pagesize) {
int start = (curpage - 1) * pagesize;
int end = curpage * pagesize;
String sql = "select deptno, dname, loc from (select rownum as rn,"
+ " deptno, dname, loc from dept)"
+ " where rn > ? and rn <= ?";
return jdbcTemplate.query(sql,
new Object[] { start, end },
new RowMapper<Dept>() {
@Override
public Dept mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Dept(rs.getInt(1), rs.getString(2), rs.getString(3));
}
});
}
}
package com.trkj2.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.trkj2.dao.DeptDAO;
import com.trkj2.pojos.Dept;
/**
* 业务类
* @author Administrator
*
*/
@Service
public class DeptService {
@Autowired
private DeptDAO deptDAO;
public void setDeptDAO(DeptDAO deptDAO) {
this.deptDAO = deptDAO;
}
/**
* 批量添加部门
* @param list
*/
@Transactional(rollbackFor = {Exception.class})
public void batchAddNew(List<Dept> list){
for(Dept dept: list){
deptDAO.addNew(dept.getDeptNo(),
dept.getDname(),
dept.getLoc());
}
}
public int query(){
return 10;
}
}
JUnit4注解
JUnit4常用的注解
@Before 修饰setUp()方法,在每个测试方法之前执行
@After 修饰tearDown()方法,在每个测试方法之后执行
@BeforeClass 在所有方法执行之前执行
@AfterClass 在所有方法执行之后执行
@Test 要测试的方法
@Ignore 不被测试的方法
Spring DAO的更多相关文章
- 关于Hibernate在反向工程时无法选择Spring DAO Type的解决方法【更新版】
目录(?)[+] IT程序员开发必备-各类资源下载清单,史上最全IT资源,个人收藏总结! 之前有一篇文章中(Hibernate反向工程步骤及DAO Type无法选择Spring DAO解决方法)提到, ...
- 学习Spring5必知必会(6)~Spring DAO
一.Spring 对持久层技术的支持 Spring DAO 1.模板类: 2.基类: 二.spring JDBC [JDBCTemplate 模板类] 1.案例:使用jdbc 完成crud操作 (1) ...
- spring DAO 有什么用?
Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一 种统一的方式工作.这使得用户容易在持久性技术之间切换.它还允许您在编写 代码时,无需考虑捕获每种技术 ...
- Spring DAO模块
Spring的DAO模块提供了对JDBC.Hibernate.Mybatis等DAO层支持,本节介绍DAO模块对JDBC的支持.DAO模块依赖ommons-dbcp.jar.commons-pool. ...
- spring深入学习(五)-----spring dao、事务管理
访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...
- Spring DAO vs Spring ORM vs Spring JDBC
Pat 的疑惑 最近关注于 Spring 提供的数据访问技术,对于 Spring 相关的这几个项目有何不同我不是太明白: Spring-DAO (http://docs.spring.io/sprin ...
- SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装
SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...
- Spring之DAO一
前面博客把bean.aop简单了解了一下,今天主要是了解Spring中DAO层,如果使用传统的JDBC时需要创建连接.打开.执行sql.关闭连接这一系列的步骤,Spring框架对JDBC进行了封装,我 ...
- Spring之DAO二
上一篇算是把JdbcDaoSupport的使用演示了一下,这篇主要是演示MappingSqlQuery.SqlUpdate.SqlFunction的使用以及Spring的事务管理. 一.Mapping ...
随机推荐
- C语言单片机项目实战超声波雷达测距
本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上. 模块工作原理如下 (1)采用 IO 触发测距,给至少 10us 的 ...
- Python爬取COVID-19疫情监控实战
一.项目概述 本项目基于Python.Flask.Echarts打造的一个疫情监控系统,涉及技术: Python网络爬虫 Python与Mysql数据库交互 使用Flask构建web项目 基于Echa ...
- 通过两个位置的经纬度坐标计算距离(C#版本)
/// <summary> /// 通过地图上的两个坐标计算距离(C#版本) /// Add by 成长的小猪(Jason.Song) on 2017/11/01 /// http://b ...
- 输出单层结点 牛客网 程序员面试金典 C++ Python
输出单层结点 牛客网 程序员面试金典 C++ Python 题目描述 对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表. 给定二叉树的根结点指针TreeNode* root,以及链表上 ...
- hdu 3635 Dragon Balls(并查集)
题意: N个城市,每个城市有一个龙珠. 两个操作: 1.T A B:A城市的所有龙珠转移到B城市. 2.Q A:输出第A颗龙珠所在的城市,这个城市里所有的龙珠个数,第A颗龙珠总共到目前为止被转移了多少 ...
- 让 AI 为你写代码 - 体验 Github Copilot
前几天在群里看到有大神分享 Copoilot AI 写代码,看了几个截图有点不敢相信自己的眼睛.今天赶紧自己也来体验一下 Copoilot AI 写代码到底有多神奇. 申请 现在 Copoilot 还 ...
- spark structured-streaming 最全的使用总结
一.spark structured-streaming 介绍 我们都知道spark streaming 在v2.4.5 之后 就进入了维护阶段,不再有新的大版本出现,而且 spark strea ...
- 官宣 .NET RC 2
我们很高兴发布 .NET 6 RC(Release Candidate) 2.它是生产环境中支持的两个"go live"候选版本中的第二个. 在过去的几个月里,团队一直专注于质量的 ...
- celery ValueError: invalid literal for int() with base 10: '26379;sentinel'
celery使用redis sentinel作为broker的时候,因为redis sentinel配置字符串格式解析报错 ValueError: invalid literal for int() ...
- dart系列之:dart类中的泛型
目录 简介 为什么要用泛型 怎么使用泛型 类型擦除 泛型的继承 泛型方法 总结 简介 熟悉JAVA的朋友可能知道,JAVA在8中引入了泛型的概念.什么是泛型呢?泛型就是一种通用的类型格式,一般用在集合 ...