Spring的jdbcTemplate操作
1 、spring是框架一站式框架
(1)针对javaee三层,每一层都有解决技术
(2)在dao层,使用jdbcTemplate,View层使用SpringMvc
2、 spring对不同的持久化层技术都进行封装
(1)jdbcTemplate对jdbc进行封装
3、 jdbcTemplate 使用和 dbutils 使用很相似,都数据库进行 crud 操作增加
1、 导入jdbcTemplate使用的jar包 点击打开链接
还需导入c3p0所需jar包(数据库驱动)点击打开链接
2、 创建对象,设置数据库信息
3、 创建jdbcTemplate对象,设置数据源
4 、调用jdbcTemplate对象里面的updata方法实现操作
// 添加
@Test
public void add() {
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "insert into t_user values(?,?)";
int rows = jdbcTemplate.update(sql, "lucy", "Haugn123");
System.out.println(rows);
}
修改
// 修改
@Test
public void update() {
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "update t_user set password=? where username=?";
int rows = jdbcTemplate.update(sql, "13245", "lucy");
System.out.println(rows);
}
删除
// 删除
@Test
public void deletetest() {
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "delete from t_user where username=?";
int rows = jdbcTemplate.update(sql, "lucy");
System.out.println(rows);
}
查询
1、 使用jdbcTemplate实现查询操作
DBUtils: QueryRunner runner = new QueryRunner(datasource) 返回对象
runner.query(sql,new BeanHandler<User>(User.class)) 返回list集合
runner.query(sql,new BeanListHandler<User>(User.class))
//在使用dbutils时,有ResultSetHandler接口 dnutils中提供了针对不同的返回结果提供不同的结果实现类
2、 查询具体实现
第一个查询返回某一个值
使用方法:queryForObject
(1)第一个参数是sql语句
(2)第二个参数返回类型的class(int类型返回值就是Integer.class,String.class...)
// 演示查询某一个值
public void testCount() {
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "select count(*) from user ";
int count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println(count);
}
Jdbc实现:
//jdbc实现
@Test
public void testJDBC() throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
// 加载数据库驱动
try {
Class.forName("com.jdbc.driver");
// 创建连接
connection = DriverManager.getConnection(
"jdbc:mysql:///spring_jdbctemplate", "root", "Huang123");
// 编写sql语句
// 查询表中的所有记录
String sql = "select * form t_user where username=?";
// 预编译sql
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "lucy");
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String username = resultSet.getString("username");
String password = resultSet.getString("password");
// 方法user对象中
User user = new User();
user.setUsername(username);
user.setPassword(password);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
connection.close();
preparedStatement.close();
resultSet.close();
}
}
第二个查询返回对象
使用方法:queryForObject
第一个参数是sql语句
第二个参数是 RowMapper,是接口,类似于dbutils里面ResultSetHandler接口,Spring并没有帮我们封装完,需要使用RowMaper接口,写他的接口的实现类
class MyRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int num) throws SQLException {
//从结果集中得到数据
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User();
//将数据封装到对象中
user.setPassword(password);
user.setUsername(username);
return user;
}
第三个参数是可变参数
// 查询返回单个对象
@Test
public void queryUser() {
// 代码中配置c3p0
// ComboPooledDataSource dataSource = new ComboPooledDataSource();
// dataSource.setDriverClass("com.mysql.jdbc.Driver");
// dataSource.setJdbcUrl("jdbc:mysql:///spring_jdbctemplate");
// dataSource.setUser("root");
// dataSource.setPassword("Huang123");
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "select * from user where username=?";
User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "lucy");
System.out.println(user);
}
第三个查询返回list集合
使用方法:query
(1) sql语句
(2) RowMapper接口,自己写类实现数据封装
(3) 可变参数
// 查询返回对象集合
@Test
public void queryList() {
// 设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUsername("root");
dataSource.setPassword("Huang123");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 调用JdbcTemplate方法实现操作
// 创建sql语句
String sql = "select * from user";
List<User> user = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(user);
}
Spring配置连接池和dao使用jdbcTemplate
1、 spring配置c3p0连接池
第一步导入jar包点击打开链接
创建service类与dao类
service类:
package com.spring_stu.c3p0;
public class UserService {
//在service引入dao
private UserDao userDao;
//set方法注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(){
System.out.println("UserService");
userDao.add();
}
}
dao类:
package com.spring_stu.c3p0;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDao {
//在dao中使用template模板
//得到jdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void add(){
String sql="insert into user values(?,?) ";
jdbcTemplate.update(sql,"lilwei","502");
}
}
第二步创建spring配置文件,配置连接池,在代码中的配置为:
// 代码中配置c3p0
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///spring_jdbctemplate");
dataSource.setUser("root");
dataSource.setPassword("Huang123");
(1)把代码在配置文件中进行配置
<!-- 配置c3p0连接池 -->
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_jdbctemplate"></property>
<property name="user" value="root"></property>
<property name="password" value="Huang123"></property>
</bean>
2 、dao使用jdbcTemplate
(1)创建service和dao,配置service和dao对象,在service注入dao对象
<!-- 创建serveice与dao对象,在service中注入dao对象 -->
<bean id="userDao" class="com.spring_stu.c3p0.UserDao">
<!-- 在dao中注入模板对象 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="userService" class="com.spring_stu.c3p0.UserService">
<!-- 注入dao对象 -->
<property name="userDao" ref="userDao" ></property>
</bean>
(2)创建jdbcTemplate对象,把模板对象注入到dao里面
//在dao中使用template模板
//得到jdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
创建jdbcTemplate模板,在jdbcTemplate对象里面注入dataSource:
<!-- 创建jdbcTemplate模板对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 需要将DataSource对象传递至jdbcTemplate中 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
将jdbcTemplate模板注入到dao中:
<bean id="userDao" class="com.spring_stu.c3p0.UserDao">
<!-- 在dao中注入模板对象 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
完整的配置文件为:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0连接池 -->
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_jdbctemplate"></property>
<property name="user" value="root"></property>
<property name="password" value="Huang123"></property>
</bean>
<!-- 创建serveice与dao对象,在service中注入dao对象 -->
<bean id="userDao" class="com.spring_stu.c3p0.UserDao">
<!-- 在dao中注入模板对象 -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="userService" class="com.spring_stu.c3p0.UserService">
<!-- 注入dao对象 -->
<property name="userDao" ref="userDao" ></property>
</bean>
<!-- 创建jdbcTemplate模板对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 需要将DataSource对象传递至jdbcTemplate中 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
一份较为完整的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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
Spring的事务管理
事务概念
1 、什么是事务:事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消
2、 事务特性:
- 原子性(事务不可分割);
- 一致性(事务前后数据一致);
- 隔离性(多个事务之间,保持数据的隔离);
- 持久性(保证事务在提交后,数据库必须对数据进行操作而产生永久性影响);
3、 不考虑隔离性产生读问题
- 脏读:A事务中读取到了B事务中未提交的数据,造成数据错误
- 不可重复读:A事务中读取到了B事务中已提交的数据,在特定情景下会产生影响,比如生成统一的数据报表
- 虚读(幻读):A事务中读取到了B事务中已提交的新插入的数据,影响同上
4、 解决读问题
(1)设置隔离级别
Spring事务管理api
1 、spring事务管理两种方式
第一种编程式事务管理(不用)
第二种声明式事务管理
(1) 基于xml配置文件实现
(2) 基于注解实现
2 spring事务管理的api介绍
(1)spring针对不同的dao层框架,提供接口不同的实现类
(2)首先配置事务管理器
搭建转账环境
1、 创建数据库表,添加数据
2 创建service和dao类,完成注入关系
<!-- 创建serveice与dao对象,在service中注入dao对象 -->
<bean id="orderDao" class="com.spring.Dao.OrderDao">
<!-- 注入 jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="orderService" class="com.spring.service.OrderService">
<!-- 注入dao对象 -->
<property name="orderDao" ref="orderDao"></property>
</bean>
(1)service层又叫业务逻辑层
(2)dao层,单纯对数据库操作层,在dao层不添加业务
(3)需求:小王转账 1000 给小里
- 小王少1000
- 小里多1000
package com.spring.Dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class OrderDao {
JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/*
* 只写对数据库操作,不写业务
* */
//小王少钱的方法
public void lessMoney(){
String sql="update user1 set money=money-? where username=? ";
jdbcTemplate.update(sql,1000,"小王");
}
//多钱的方法
public void moreMoney(){
String sql="update user1 money=money+1000 where username=?";
jdbcTemplate.update(sql,1000,"小里");
}
}
package com.spring.service;
import com.spring.Dao.OrderDao;
public class OrderService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
//调用dao方法
//业务逻辑层:需要写转账方法(分层思想)
public void accountMoney(){
//小王少1000
orderDao.lessMoney();
//中间出现异常,转账完成失败
// int i = 1/0;
//小里多1000
orderDao.moreMoney();
}
}
3 、产生问题:
(1)如果小王少了1000之后,出现异常,小马不会多1000,钱丢失了
4 、解决:
( 1 )添加事务解决,出现异常进行回滚操作声明式事务管理(xml配置)
1、 配置文件方式使用aop思想配置
第一步、 配置事务管理器 <!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步配置事务增强
<!-- 2、配置事务的增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配的规则 -->
<!-- 以account开头的全部匹配 -->
<tx:method name="account*"/>
</tx:attributes>
</tx:advice>
第三步配置切面
<!-- 3、配置切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="excution(* com.spring.service.OrderService.accountMoney(..))" id="pointcut1"/>
<!-- 切面具体操作:将哪个增强用在哪个切面上 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
声明式事务管理(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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0连接池 -->
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///Tranfar"></property>
<property name="user" value="root"></property>
<property name="password" value="Huang123"></property>
</bean>
<!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2、配置事务的增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配的规则 -->
<!-- 以account开头的全部匹配 -->
<tx:method name="account*"/>
</tx:attributes>
</tx:advice>
<!-- 3、配置切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="excution(* com.spring.service.OrderService.accountMoney(..))" id="pointcut1"/>
<!-- 切面具体操作:将哪个增强用在哪个切面上 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
<!-- 创建serveice与dao对象,在service中注入dao对象 -->
<bean id="orderDao" class="com.spring.Dao.OrderDao">
<!-- 注入 jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="orderService" class="com.spring.service.OrderService">
<!-- 注入dao对象 -->
<property name="orderDao" ref="orderDao"></property>
</bean>
<!-- 创建jdbcTemplate模板对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 需要将DataSource对象传递至jdbcTemplate中 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
声明式事务管理(注解)
第一步 配置事务管理器
<!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步 配置事务注解
<!--2、开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
第三步在要使用事务的方法所在类上面添加注解
package com.spring.service;
import org.springframework.transaction.annotation.Transactional;
import com.spring.Dao.OrderDao;
@Transactional
public class OrderService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
//调用dao方法
//业务逻辑层:需要写转账方法(分层思想)
public void accountMoney(){
//小王少1000
orderDao.lessMoney();
//小里多1000
orderDao.moreMoney();
}
}
声明式事务管理(注解方式)的格式也是大体一致,给出本转账例子的格式:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置c3p0连接池 -->
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///Tranfar"></property>
<property name="user" value="root"></property>
<property name="password" value="Huang123"></property>
</bean>
<!-- 1、配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2、开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 创建serveice与dao对象,在service中注入dao对象 -->
<bean id="orderDao" class="com.spring.Dao.OrderDao">
<!-- 注入 jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="orderService" class="com.spring.service.OrderService">
<!-- 注入dao对象 -->
<property name="orderDao" ref="orderDao"></property>
</bean>
<!-- 创建jdbcTemplate模板对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 需要将DataSource对象传递至jdbcTemplate中 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
本章小结:
1、 spring的jdbcTemplate操作
(1)实现crud操作
- 增加、修改、删除,调用模板update方法
- 查询某个值时候,调用queryForObject方法
--- 自己写实现类封装数据
- 查询对象,调用queryForObject方法
- 查询list集合,调用query方法
2、 spring配置连接池
(1)配置c3p0连接池
(2)dao注入jdbcTemplate操作
3、spring事务管理
(1)事务概念
(2)spring进行事务管理api
- spring针对不同的dao层框架提供不同的实现类
(3)spring进行事务配置(声明式)
- 基于xml配置文件
- 基于注解方式