Spring中JDBC的使用
原文地址:Spring中JDBC的使用
写在最前
现在已经JDBC封装的比较完善了,本篇也只是洒洒水的水平。也就是怎么用的水平。但是原理方面的东西还是需要查阅相关资料和书籍。而且,这篇会用之后,并没有什么卵用。只是知道后面封装对象大概的思路是什么。现实工程中还是很少会见到。
JdbcTemplate的起源
JDBC作为Java平台访问关系数据库的标准API,其成功是有目共睹的。几乎所有Java平台的数据访问,都直接地或者间接地使用了JDBC,它是整个Java平台面向关系数据库进行数据访问的基石。
作为一个标准,无疑JDBC是成功的。但是要说JDBC在实际的使用过程中也是受人欢迎的,则不尽然了。JDBC标准 主要面向较为底层的数据库操作,所以在设计过程中,比较贴近底层以提供尽可能多的功能特色。从这个角度来说,JDBC API的设计无可厚非。可是,过于贴近底层的API设计,对于开发人员的使用来说就不- -定是好事了。即使执行简单的查询或者更新,开发人员也要按照API的规矩写上一大堆雷同的代码。如果不能合理封装使用JDBC API的代码,在项目中使用JDBC访问数据所出现的问题估计会让人抓狂。
为了解决JDBC API在实际使用中的尴尬局面,Spring提出了JdbcTemplate作为数据访问的Helper类。这样处理之后,JDBC代码的使用得到了规范(进行数据访问的时候,每次使用的JDBC代码都几乎相同),异常处理和连接释放等问题也得到了统一的管理。
可以大致看一下源码,不过当然没这么简单。。。只是一个大概的样子
JdbcTemplate的使用
书上讲了很多相关的东西足足有一百页,但是总不可能照着字典学语文吧。下面记录的是常用的。
首先还是先引包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
然后在配置文件中配置
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
然后就可以在代码中调用
保存的操作(指查询的返回值为空的)
public class JdbcTemplateDemo1 {
public static void main(String[] args) {
//1.获取 Spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 id 获取 bean 对象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.执行操作
//保存
jt.update("insert into account(name,money)values(?,?)","chayedan",5000);
}
}
根据ID查询(指返回值为一行的),主要注意返回的封装容器为AccountRowMapper()对象
public class JdbcTemplateDemo2 {
public static void main(String[] args) {
//1.获取 Spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 id 获取 bean 对象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.执行操作
//查询一个
Account account = jt.queryForObject("select * from account where id = ? ",new BeanPropertyRowMapper<>(Account.class),1);
System.out.println(account);
}
}
查询所有操作(返回值为多个)
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.获取 Spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 id 获取 bean 对象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.执行操作
//查询所有
List<Account> accounts = jt.query("select * from account where money > ? ",new BeanPropertyRowMapper<>(Account.class), 500);
for(Account account : accounts){
System.out.println(account);
}
}
}
事务控制
Spring 中事务控制的 API
PlatformTransactionManager
:此接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法。
包含有3个具体的操作
TransactionStatus getTransaction(TransactionDefinition definition)
:获取事务状态信息
void commit(TransactionStatus status)
:提交事务
void rollback(TransactionStatus status)
:回滚事务
不过我们一般使用的是这个实现类
org.springframework.jdbc.datasource.DataSourceTransactionManager
用于Spring JDBC 或者 iBatis 进行持久化数据
另外一点
TransactionDefinition
和TransactionStatus
太庞杂了,详情请谷歌。
引包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
用XML 进行事务控制
在Spring的配置文件中配置
<!--
配置事务管理器对象,传入DataSource对象
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
advice标签:需要把transactionManager对象
由它使用transactionManage完成事务的环绕加强
-->
<tx:advice id="transactionTX" transaction-manager="transactionManager">
<!--
细化的控制
name 感兴趣的方法名,支持通配符
read-only:是否是只读事务
isolation:隔离级别
timeout:超时时间 默认-1
rollback-for: 捕获到该类型异常才回滚,默认只要捕获异常就回滚
no-rollback-for 遇到该异常不回滚的类
下面配置的意思就是只要不是以find开头的方法,都需要事务
-->
<tx:attributes>
<tx:method name="*" read-only="false" />
<tx:method name="find*" read-only="true" isolation="DEFAULT" timeout="-1" />
</tx:attributes>
</tx:advice>
<!--配合上面的tx:advice标签使用-->
<aop:config>
<aop:advisor advice-ref="transactionTX" pointcut="execution(* com.service..*.*(..))"></aop:advisor>
</aop:config>
说白了,就是利用AOP来进行事务控制
但是太复杂了,推荐使用注解
用注解进行事务控制(推荐)
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
开启注解扫描,扫描@Transactional
-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
在类上或者方法上加上@Transactional
就能进行事务控制了
默认值为@Transactional(readOnly = false)
如果不想用XML进行配置,也可以用纯注解的方式
package com.chayedan.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import javax.xml.crypto.Data;
@Configuration
@ComponentScan("com.chayedan")
@PropertySource("classpath:db.properties")
//等同于 该配置<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
@EnableTransactionManagement
public class Config {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource getDataSource(){
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setDriverClassName(driver);
hikariDataSource.setJdbcUrl(url);
hikariDataSource.setUsername(username);
hikariDataSource.setPassword(password);
return hikariDataSource;
}
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}