JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的RedisTemplate,操作消息队列的JmsTemplate等等。
4.0.0
com.itheima
itheima_spring_jdbc
1.0-SNAPSHOT
war
itheima_spring_jdbc Maven Webapp
http://www.example.com
mysql
mysql-connector-java
5.1.32
c3p0
c3p0
0.9.1.2
com.alibaba
druid
1.1.10
junit
junit
4.12
org.springframework
spring-context
5.0.5.RELEASE
org.springframework
spring-test
5.0.5.RELEASE
org.springframework
spring-web
5.0.5.RELEASE
org.springframework
spring-webmvc
5.0.5.RELEASE
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet.jsp
javax.servlet.jsp-api
2.2.1
provided
com.fasterxml.jackson.core
jackson-core
2.9.0
com.fasterxml.jackson.core
jackson-databind
2.9.0
com.fasterxml.jackson.core
jackson-annotations
2.9.0
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.3
org.springframework
spring-jdbc
5.0.5.RELEASE
org.springframework
spring-tx
5.0.5.RELEASE
创建数据库表和实体
CREATE TABLE account(
NAME VARCHAR(100),
money DOUBLE(7,2)
)
INSERT INTO account VALUES("tom",5000);
INSERT INTO account VALUES("lucy",5000);
package com.itheima.domain;
public class Account {
private String name;
private double money;
public String getNa me() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"name='" + name + '\'' +
", money=" + money +
'}';
}
}
创建JdbcTemplate对象
执行数据库操作
@Test
//测试JdbcTemplate开发步骤
public void test1() throws PropertyVetoException {
//创建数据源对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("root");
dataSource.setPassword("root");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//设置数据源对象 知道数据库在哪
jdbcTemplate.setDataSource(dataSource);
//执行操作
int row = jdbcTemplate.update("insert into account values(?,?)", "tom", 5000);
System.out.println(row);
}
我们可以将JdbcTemplate的创建权交给Spring,将数据源DataSource的创建权也交给Spring,在Spring容器内部将数据源DataSource注入到JdbcTemplate模版对象中,然后通过Spring容器获得JdbcTemplate对象来执行操作。
配置如下:
测试代码
@Test
//测试Spring产生jdbcTemplate对象
public void test2() throws PropertyVetoException {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
int row = jdbcTemplate.update("insert into account values(?,?)", "lisi", 5000);
System.out.println(row);
}
将数据库的连接信息抽取到外部配置文件中,和spring的配置文件分离开,有利于后期维护
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
配置文件修改为:
package com.itheima.test;
import com.itheima.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
//修改更新
@Test
public void testUpdate(){
jdbcTemplate.update("update account set money=? where name=?",10000,"tom");
}
//删除
@Test
public void testDelete(){
jdbcTemplate.update("delete from account where name=?","tom");
}
}
package com.itheima.test;
import com.itheima.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
//聚合查询
@Test
public void testQueryCount(){
Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
System.out.println(count);
}
//查询一个
@Test
public void testQueryOne(){
Account account = jdbcTemplate.queryForObject("select * from account where name=?", new BeanPropertyRowMapper(Account.class), "tom");
System.out.println(account);
}
//查询所有
@Test
public void testQueryAll(){
List accountList = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper(Account.class));
System.out.println(accountList);
}
}
①导入spring-jdbc和spring-tx坐标
②创建数据库表和实体
③创建JdbcTemplate对象
JdbcTemplate jdbcTemplate = newJdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
④执行数据库操作
更新操作:
jdbcTemplate.update (sql,params)
查询操作:
jdbcTemplate.query (sql,Mapper,params)
jdbcTemplate.queryForObject(sql,Mapper,params)
PlatformTransactionManager 接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法。
注意:
PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,例如:Dao 层技术是jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager
Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager
TransactionDefinition 是事务的定义信息对象,里面有如下方法:
设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。
TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。
编程式事务控制三大对象
Spring 的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中声明,用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。
注意:Spring 声明式事务控制底层就是AOP
声明式事务控制明确事项:
①引入tx命名空间
②配置事务增强
③配置事务 AOP 织入
④测试事务控制转账业务代码
@Override
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
int i = 1/0;
accountDao.in(inMan,money);
}
其中,
编写 AccoutDao
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void out(String outMan, double money) {
jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
}
public void in(String inMan, double money) {
jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
}
}
编写 AccoutService
@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
int i = 1/0;
accountDao.in(inMan,money);
}
}
编写 applicationContext.xml 配置文件
注解声明式事务控制的配置要点