SpringTemplate增删改查及其事务控制基本使用

SpringTemplate增删改查及其事务控制基本使用,第1张

一。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的事务控制

  1. 开启事务: start transaction; (con.setAutoCommit(false);)
    2. 回滚:rollback; (con.rollback();)
    3. 提交:commit; (con.commit();)

SELECT @@autocommit; – 1 代表自动提交 0 代表手动提交

事务的四大特征:
1. 原子性:是不可分割的最小 *** 作单位,要么同时成功,要么同时失败。
2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
3. 隔离性:多个事务之间。相互独立。
4. 一致性:事务 *** 作前后,数据总量不变

  1. 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切点 转账方法
2通知 事务控制
引入命名空间 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>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/728110.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存