spring是一站式框架,对于各种层次和各大框架都有支持,jdbcTemplate就是spring对jdbc的一个深度封装,方便开发者使用jdbc进行数据库操作
由于jdbcTemplate只是对jdbc的封装,用法差不了多少,我们这里不会细说,还是按照spring的核心,说一下xml配置和注解配置两种方法,顺带说一下事务管理
首先我们还是先把需要的依赖先加一下
compile "org .springframework :spring-jdbc :4 .3 .9 .RELEASE "
compile "org .springframework :spring-tx :4 .3 .9 .RELEASE "
由于我们需要连接mysql,还需要mysql-connector。我们还要用到c3p0连接池,于是乎还要加上c3p0的依赖
compile "mysql :mysql-connector-java :5 .1 .38 "
compile "c3p0 :c3p0 :0 .9 .1 .2 "
在jdbc中,第一步要做的就是写一个配置文件,把什么用户名密码、数据库名称、驱动什么的全部配置起来,在spring中自然要用的就是xml来配置了,这就用到了c3p0连接池
<bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name ="driverClass" value ="com.mysql.jdbc.Driver" />
<property name ="jdbcUrl" value ="jdbc:mysql://localhost:3306/test" />
<property name ="user" value ="root" />
<property name ="password" value ="你的mysql密码" />
</bean >
然后就是配置jdbcTemplate,这里就是少有的不能用注解配置的情况了,毕竟你不能在源码上加注解啊,只能老老实实用xml配置了
打开源码可以看到JdbcTemplate类是有一个DataSource属性的,这需要你给它注入值(也就是你的连接信息了)
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager , InitializingBean {
private DataSource dataSource;
...
}
<bean id ="template" class ="org.springframework.jdbc.core.JdbcTemplate" >
<property name ="dataSource" ref ="dataSource" ></property >
</bean>
接下来我们需要在数据库中创建一张表(我们就不用User了,都用烂了,就用student吧),这里提一下,idea本身也是自带数据库连接的,还是挺好用的
我们双击shift,在出现的搜索中搜database
第一个就是我们想要的,然后点击绿色加号,选择连接mysql
出来的界面想必大家都不陌生,就是我们刚填写的连接信息了
然后在你右侧就能看见你连接上的数据库了,右键就可以new一个table了,后面就是傻瓜式操作了,我就不细说了,看一下我创建好的student类
id为int主键自增,名字为varchar(20),年龄int就行,钱自然要用dicimal了
接下来插入两条数据,为我们马上要展开的具体的实务操作做准备,内容就随便你了
我们来创建一个StudentDao,其中需要两个方法,一个是付钱,一个是收钱,由于是测试,我们可以直接将数据写死
@Bean
@Repository (value = "studentDao" )
data class StudentDao (var name: String)
{
@Resource (name="template" )private lateinit var template: JdbcTemplate
fun payMoney()
{
val sql = "update student set money=money-? where name=?"
template.update(sql, 200 , "小黄" )
}
fun collectMoney()
{
val sql = "update student set money=money+? where name=?"
template.update(sql, 200 , "小明" )
}
}
然后再创建一个StudentService,我们需要在这里做付款和收款的工作
@Bean
@Service (value = "studentService" )
data class StudentService(@Resource (name = "studentDao" )var dao: StudentDao)
{
fun transferAccount()
{
dao.payMoney()
dao.collectMoney()
}
}
接下来就是配置我们的事务了,我们来到xml
可以打开DataSourceTransactionManager源码看一下,它也是需要注入一个dataSource的,于是我们给它配置上
<bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name ="dataSource" ref ="dataSource" />
</bean >
这里“tx:method name”可以全字匹配也支持部分匹配的,我这样写就是匹配所有以Account结尾的方法
<tx:advice id ="txadvice" transaction-manager ="transactionManager" >
<tx:attributes >
<tx:method name ="*Account" />
</tx:attributes >
</tx:advice >
看到这个大家应该就明白了,其实事务也是用AOP加进去的。这里我们用的不再是aop:aspect,而是aop:advisor,然后将我们刚配置的事务增强加进去,加强StudentService的方法
<aop:config >
<aop:pointcut id ="pointcut" expression ="execution(* com.kotlin.Service.StudentService.*(..))" />
<aop:advisor advice-ref ="txadvice" pointcut-ref ="pointcut" />
</aop:config >
到这里配置就完成了,然后我们来运行一下
class main
{
@Test
fun test()
{
val context = FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/applicationContext.xml" )
val studentService = context.getBean("studentService" ) as StudentService
studentService.transferAccount()
}
}
运行前
运行后
然后我们再给它制造点异常,还是用我们的4/0
除零异常出来了,我们再看看数据库
并没有变化,说明回滚成功
最后我们看一下注解方式实现,你会发现,这事务的注解是在太简单了
看下我们的xml,之前那么多,现在只剩下第一条
<bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name ="driverClass" value ="com.mysql.jdbc.Driver" />
<property name ="jdbcUrl" value ="jdbc:mysql://localhost:3306/test" />
<property name ="user" value ="root" />
<property name ="password" value ="gg123456" />
</bean >
<bean id ="template" class ="org.springframework.jdbc.core.JdbcTemplate" >
<property name ="dataSource" ref ="dataSource" > </property >
</bean >
<bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name ="dataSource" ref ="dataSource" />
</bean >
<tx:annotation-driven transaction-manager ="transactionManager" />
剩下的就没办法了 ,谁教我们不能在他源码上加注解呢
然后看一下Dao和Service上的注解
@Bean
@Service (value = "studentService" )
@Transactional
data class StudentService(@Resource (name = "studentDao" )var dao: StudentDao)
{
fun transferAccount()
{
dao.payMoney()
dao.collectMoney()
}
}
你没有眼花,我也没有少写,确实只多了一行,只需要在StudentService上加一个@Transactional,一切解决