查看“Spring:JdbcTemplate、事务”的源代码
←
Spring:JdbcTemplate、事务
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:SpringFramework]] == 关于 == Spring 对不同的持久化层技术都进行了封装: :[[File:spring的dao模板类.png|600px]] :* '''JdbcTemplate''' 对 JDBC 进行了封装; === jar包 === [[File:spring-JDBCTemplate相关jar包.jpg|300px]] :* 数据库驱动包; :* JDBC 包; :* 事务包 === JDBC 模板的基本使用 === <syntaxhighlight lang="java" highlight="3,9"> @Test public void demo1(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring_day03"); dataSource.setUsername("root"); dataSource.setPassword("123"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into account values (null,?,?)", " 会希",10000d); } </syntaxhighlight> == 连接池 == 数据库连接池(Connection pooling):程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请、使用、释放。<br/> 连接池的机制: # 程序初始化时创建连接池; # 使用时向连接池申请可用连接; # 使用完毕,将连接返还给连接池; # 程序退出时,断开所有连接,并释放资源; 其中: # 最小连接数:连接池一直保持的数据库连接; # 最大连接数:连接池能申请的最大连接数: #: 如果数据库连接请求超过最大次数,后到的请求将被加入等待队列; === Spring 内置连接池 === “org.springframework.jdbc.datasource.'''DriverManagerDataSource'''”: # 配置内置连接池: #: <syntaxhighlight lang="properties"> <!-- 配置Spring 的内置连接池--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring_day02"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean> </syntaxhighlight> # 配置jdbcTemplate模板: #: <syntaxhighlight lang="properties"> <!-- 配置JDBC 模板--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> </syntaxhighlight> # 编写测试类: #* 注入 jdbcTemplate; #: <syntaxhighlight lang="java"> @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test public void demo1(){ jdbcTemplate.update("insert into account values (null,?,?)", "eijux",10000d); } } </syntaxhighlight> === DBCP 连接池 === # 引入dbcp 连接池的jar 包: #: [[File:dbcp 连接池的jar 包.jpg|400px]] # 配置连接池: #:<syntaxhighlight lang="properties"> <!-- 配置DBCP 连接池--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///spring_day02"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean> </syntaxhighlight> === c3p0 连接池 === # 引入相应的jar 包: #: [[File:c3p0 连接池的jar 包.jpg|400px]] # 配置连接池: #:<syntaxhighlight lang="properties"> <!-- 配置C3P0 连接池--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql:///spring_day02"/> <property name="user" value="root"/> <property name="password" value="123"/> </bean> </syntaxhighlight> == 使用属性文件 == 定义属性文件“jdbc.properties”: <syntaxhighlight lang="properties"> jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///spring_day02 jdbc.username=root jdbc.password=123 </syntaxhighlight> 引入外部的属性文件:(两种方式) # 第一种方式: #:<syntaxhighlight lang="properties"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties"/> </bean> </syntaxhighlight> # 第二种方式: #:<syntaxhighlight lang="properties"> <context:property-placeholder location="classpath:jdbc.properties"/> </syntaxhighlight> == jdbcTemplate == JDBC 模板CRUD 的操作: * JdbcTemplate类使用“org.springframework.jdbc.core.'''RowMapper<T>'''”接口进行结果映射:将结果集ResultSet的行,映射到实际的结果对象。 <syntaxhighlight lang="java" highlight="5-6,11,26,32,38,41-45"> @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo3 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test // 插入操作 public void demo1() { jdbcTemplate.update("insert into account values (null,?,?)", "冠希",10000d); } @Test // 修改操作 public void demo2() { jdbcTemplate.update("update account set name=?,money =? where id = ?", "思雨",10000d,5); } @Test // 删除操作 public void demo3() { jdbcTemplate.update("delete from account where id = ?", 5); } @Test // 查询一条记录 public void demo4() { Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 1); System.out.println(account); } @Test // 查询所有记录 public void demo5() { List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper()); for (Account account : list) { System.out.println(account); } } class MyRowMapper implements RowMapper<Account> { @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } } } </syntaxhighlight> # 注入了 jdbcTemplate; # 使用 jdbcTemplate进入db操作; # 使用 RowMapper进行结果集映射; == 事务 == === 关于事务 === 事务:逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败。 spring事务管理两种方式: # 编程式事务管理(不用); # 声明式事务管理: ## 基于xml配置文件实现; ## 基于注解实现; ==== 事务特性: ==== # '''原子性''':强调事务的不可分割; # '''一致性''':事务的执行的前后数据的完整性保持一致; # '''隔离性''':一个事务执行的过程中,不应该受到其他事务的干扰; # '''持久性''':事务一旦结束,数据就持久到数据库; === Spring事务管理API === ---- # PlatformTransactionManager:平台事务管理器(真正管理事务的对象); ## “org.springframework.jdbc.datasource.'''DataSourceTransactionManager'''”:使用Spring JDBC或 iBatis进行持久化数据时使用; ## “org.springframework.orm.hibernate3.'''HibernateTransactionManager'''”:使用 Hibernate 版本进行持久化数据时使用; # TransactionDefinition:事务定义信息 #: “隔离级别”、“传播行为”、“超时信息”、“是否只读”; * TransactionStatus:事务的状态; ==== 隔离级别 ==== 如果不考虑隔离性引发安全性问题: # 脏读:一个事务读到了另一个事务的未提交的数据; # 不可重复读:一个事务读到了另一个事务已经提交的“update”的数据,导致多次查询结果不一致; # 虚读:一个事务读到了另一个事务已经提交的“insert”的数据,导致多次查询结果不一致; 事务隔离级别: # 未提交读(“Read_Uncommited”):脏读,不可重复读,虚读都有可能发生。 # 已提交读(“Read_Commited”):避免脏读。(但是不可重复读和虚读有可能发生) # 可重复读(“Repeatable_Read”):避免脏读、不可重复读。(但是虚读有可能发生) # 串行化的(“Serializable”):避免以上所有读问题。 ==== 事务的传播行为 ==== # 保证同一个事务中: #* “'''PROPAGATION_REQUIRED'''”:支持当前事务,如果不存在就新建一个(默认); #* “PROPAGATION_SUPPORTS”:支持当前事务,如果不存在,就不使用事务; #* “PROPAGATION_MANDATORY”:支持当前事务,如果不存在,抛出异常; # 保证没有在同一个事务中: #* “'''PROPAGATION_REQUIRES_NEW'''”:如果有事务存在,挂起当前事务,创建一个新的事务; #* “PROPAGATION_NOT_SUPPORTED”:以非事务方式运行,如果有事务存在,挂起当前事务; #* “PROPAGATION_NEVER”:以非事务方式运行,如果有事务存在,抛出异常; #* “'''PROPAGATION_NESTED'''”:如果当前事务存在,则嵌套事务执行; === (编程式 事务管理) === ---- (了解) # 配置事务管理器; # 配置事务管理模板; # 业务层注入事务管理模板; #: <syntaxhighlight lang="properties"> <!-- 配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务管理模板--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean> <!-- 配置业务层的类--> <bean id="accountService" class="cn.itcast.transaction.demo1.AccountServiceImpl"> <property name="accountDao" ref="accountDao"/> <!-- 注入事务管理模板--> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> </syntaxhighlight> # 手动编写代码实现事务管理: #* 使用“TransactionTemplate.execute(TransactionCallback<T> action)”方法。如: #: <syntaxhighlight lang="java"> public void transfer(final String from, final String to, final Double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { accountDao.outMoney(from, money); int d = 1 / 0; accountDao.inMoney(to, money); } }); } </syntaxhighlight> === 事务管理:xml === ---- 步骤: # 配置“事务管理器”;(需要配置“DataSource”) # 配置事务“增强”; # 配置“切面”; #: <syntaxhighlight lang="properties"> <!-- dataSource --> ... <!-- 第一步 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入dataSource --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 第二步 配置事务增强 --> <tx:advice id="txadvice" transaction-manager="transactionManager"> <!-- 做事务操作 --> <tx:attributes> <!-- 设置进行事务操作的方法匹配规则 --> <!-- isolation="DEFAULT" 隔离级别 propagation="REQUIRED" 传播行为 read-only="false" 只读 timeout="-1" 过期时间 rollback-for="" -Exception no-rollback-for="" +Exception --> <tx:method name="account*" propagation="REQUIRED"/> <!-- <tx:method name="insert*" /> --> </tx:attributes> </tx:advice> <!-- 第三步 配置切面 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution(* cn.itcast.service.OrdersService.*(..))" id="pointcut1"/> <!-- 切面 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/> </aop:config> </syntaxhighlight> === 事务管理:注解 === ---- 步骤: # 配置“事务管理器”;(需要配置“DataSource”) # 开启事务注解; #: <syntaxhighlight lang="properties"> <!-- dataSource --> ... <!-- 第一步配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 第二步 开启事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </syntaxhighlight> # 使用“'''@Transactional'''”注解;(标注Service) #: <syntaxhighlight lang="java"> @Transactional public class OrdersService { private OrdersDao ordersDao; public void setOrdersDao(OrdersDao ordersDao) { this.ordersDao = ordersDao; } //调用dao的方法 //业务逻辑层,写转账业务 public void accountMoney() { //小王少1000 ordersDao.lessMoney(); //出现异常 int i = 10/0; //小马多1000 ordersDao.moreMoney(); } } </syntaxhighlight>
返回至“
Spring:JdbcTemplate、事务
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息