一。JdbcCRUD *** 作
1,导入坐标包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
创建实体及其数据库 (test下有Account表)
public class Account {
String name;
double money;
...
(1)设置数据源
这里设置c3p0的数据源
ComboPooledDataSource dataSource=new ComboPooledDataSource();
//设置数据源参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("root");
dataSource.setPassword("root");
/*Druid连接池数据源创建
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://127.0.0.1/db_student?serverTimezone=UTC");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); //这个可以缺省的,会根据url自动识别
dataSource.setUsername("root");
dataSource.setPassword("root");
*/
JdbcTemplate jdbcTemplate=new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
//设置数据源对象,知道数据库在哪
jdbcTemplate.setDataSource(dataSource);
(2)插入 *** 作
int row = jdbcTemplate.update("insert into account values(?,?)","zhangsan", 5000);
System.out.println(row);//影响行数
spring产生 JdbcTemplate jdbcTemplate=new JdbcTemplate();模板对象注入dataSource
resource下有
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
applicationContext.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"
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
">
<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--这是不加载配置文件的<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="root"/>
</bean>
--><!--jdbc模板对象及其注入数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
测试
public void test2(){
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate = app.getBean(JdbcTemplate.class);
int row = jdbcTemplate.update("insert into account values(?,?)","zhangsan3", 5000);
System.out.println(row);
}
这里我们导入了spring-test和Junit测试的坐标
这里测试增删改查方法
准备
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class jdbcTemplateCRUDTest {
@Autowired
private JdbcTemplate jdbcTemplate;
增
@Test
public void testUpdate(){
jdbcTemplate.update("insert into account values(?,?)","zhangsan", 5000);
}
删
@Test
public void testDelete(){
jdbcTemplate.update("delete from account where name = ?","zhangsan3");
}
}
改
@Test
public void testUpdate(){
jdbcTemplate.update("update account set money = ? where name = ?",10000,"zhangsan3");
}
查
查询多个
@Test
public void testQueryAll(){
List<Account> list = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
for (Account account : list) {
System.out.println(account);
}}
查询一个
@Test
public void testQueryOne() {
Account zhangsan = jdbcTemplate.queryForObject("select * from account where name = ?",
new BeanPropertyRowMapper<Account>(Account.class),//写你要封装的对象泛型及其字节码
"zhangsan");
System.out.println(zhangsan);
}
查询聚合 返回数字
@Test
public void testQueryCount() {
Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class);
System.out.println(count);
}
二。Spring的事务控制
- 开启事务: start transaction; (con.setAutoCommit(false);)
2. 回滚:rollback; (con.rollback();)
3. 提交:commit; (con.commit();)
SELECT @@autocommit; – 1 代表自动提交 0 代表手动提交
事务的四大特征:
1. 原子性:是不可分割的最小 *** 作单位,要么同时成功,要么同时失败。
2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
3. 隔离性:多个事务之间。相互独立。
4. 一致性:事务 *** 作前后,数据总量不变
-
read uncommitted:读未提交
* 产生的问题:脏读、不可重复读、幻读
2. read committed:读已提交 (Oracle)
* 产生的问题:不可重复读、幻读
3. repeatable read:可重复读 (MySQL默认)
* 产生的问题:幻读
4. serializable:串行化
* 可以解决所有的问题注意:隔离级别从小到大安全性越来越高,但是效率越来越低
* 数据库查询隔离级别:
* select @@tx_isolation;
* 数据库设置隔离级别:
* set global transaction isolation level 级别字符串;
编程式事务控制相关对象
PlatformTransactionManager这是个接口根据不同dao层实现来实现
TransactionDefinition事务定义对象 封装事务参数(事务隔离级别,是否只读,超时时间…)
TransactionStatus 事务的具体运行状态 (事务是否回滚…)
声明式事务控制(底层就是aop)
通过配置的事务增强与切点业务方法进行织入
文件结构
applicationContext.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="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
AccountDao有转入转出钱的方法
public class AccountDaoImpl implements AccountDao {
private JdbcTemplate jdbcTemplate;
/*public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.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);
}
}
Service层有个方法指定转入人转出人的转钱方法
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
accountDao.in(inMan,money);
}
测试
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.transfer("tom","lucy",500);
accountDao.out(outMan,money);事务1
accountDao.in(inMan,money);事务2
accountDao.out(outMan,money);
int i=1/0;
accountDao.in(inMan,money);
事务二不执行一方钱少一方钱不变
可以开启事务trycatch捕捉回滚事务和提交事务
1切点 转账方法
引入命名空间 xmlns:tx=“http://www.springframework.org/schema/tx”
<!--平台事务管理器要注入DataSource-->
<!--平台jdbc和mybatis都是DataSourceTransactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--通知 提交回滚事务-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
3配置切面
-配置事务aop织入
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor>
</aop:config>
</beans>
在执行测试报错by zore错误但是钱不变
设置事务的属性信息
name切点的方法,增强的方法(name="update*"以update开头的方法)
isolation 隔离级别
read-only 是否只读 (查询方法可以设为true)
propagation传播行为查看详情
timeout 超时时间
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/>
<tx:method name="save" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
<tx:method name="findAll" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
基于注解
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional
@Service("accountService")
//@Transactional这里写就这个类的方法都采用这个配置
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
/*public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
*/
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED,timeout = -1,readOnly = false)
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
int i=1/0;
accountDao.in(inMan,money);
}
@Transactional(isolation = Isolation.DEFAULT)
public void xxx(){}
}
注解驱动的配置 欢迎分享,转载请注明来源:内存溢出
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.itheima"/>
<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="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--平台事务管理器dao层用的什么技术是mybatis还是hb-->
<!--平台事务管理器要注入DataSource-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--通知 提交回滚事务-->
<!--事务的注解驱动!!!!.-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
评论列表(0条)