Spring学习笔记(四)——Mybatis-Spring和事务

文章目录

      • 八、Mybatis-Spring
        • 8.1 配置
        • 8.2 sqlSessionFactory和SqlSession
        • 8.3 操作实现
        • 8.4 SqlSessionDaoSupport
      • 九、事务
        • 9.1 配置
        • 9.2 配置事务通知
        • 9.4 配置事务切入
        • 9.2 配置事务通知
        • 9.4 配置事务切入

八、Mybatis-Spring

8.1 配置

mybatis




<configuration>

    <settings>
        <setting name="logImpl" value="LOG4J"/>
    settings>
    <typeAliases>
        <package name="pojo"/>
    typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="445133469"/>
            dataSource>
        environment>
    environments>

    <mappers>
        <mapper resource="dao/UserMapper.xml">mapper>
    mappers>

configuration>

在Spring中


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="445133469"/>
    bean>
beans>

8.2 sqlSessionFactory和SqlSession

Mybatis

 try {
     String resource = "mybatis-config.xml";
     InputStream inputStream = Resources.getResourceAsStream(resource);
     sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 } catch (IOException e) {
     e.printStackTrace();
 }
 return sqlSessionFactory.openSession(true);

Spring


    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:dao/*.xml"/>
    bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    bean>

8.3 操作实现

UserDao接口

package dao;

import pojo.User;

import java.util.List;

public interface UserDao {
    List<User> getUserList();
}

UserMapper.xml




<mapper namespace="dao.UserDao">

    <select id="getUserList" resultType="pojo.User">
        select * from mybatis.user;
    select>

mapper>

mybatis运行测试

	@Test
    public void getUserList(){

        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();

        for(User user:userList){
            System.out.println(user);
        }

        sqlSession.close();
    }

Spring运行测试

Spring 需要实现接口的实现类,然后在配合文件中注册实现类的bean

  1. 接口实现类

    package dao;
    
    import org.mybatis.spring.SqlSessionTemplate;
    import pojo.User;
    
    import java.util.List;
    
    public class UserDaoImp implements UserDao {
    
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public List<User> getUserList() {
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            List<User> list = mapper.getUserList();
            reurn list;
        }
    }
    
  2. 注册bean

    <bean id="imp" class="dao.UserDaoImp">
        <property name="sqlSession" ref="sqlSession"/>
    bean>
    
  3. 测试运行

        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("Spring-dao.xml");
    
            UserDaoImp imp = (UserDaoImp) context.getBean("imp");
    
            List<User> list = imp.getUserList();
            for (User user : list) {
                System.out.println(user);
            }
        }
    

8.4 SqlSessionDaoSupport

SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法

public class UserDaoImp extends SqlSessionDaoSupport implements UserDao {

    public List<User> getUserList() {
        UserDao mapper = getSqlSession().getMapper(UserDao.class);
        List<User> list = mapper.getUserList();
        return list;
    }
}

SqlSessionDaoSupport 需要通过属性设置一个 sqlSessionFactorySqlSessionTemplate。如果两个属性都被设置了,那么 SqlSessionFactory 将被忽略。

    <bean id="userDao" class="dao.UserDaoImp">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    bean>

测试

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("Spring-dao.xml");

        UserDaoImp userDao = (UserDaoImp) context.getBean("userDao");

        List<User> list = userDao.getUserList();
        for (User user : list) {
            System.out.println(user);
        }
    }

九、事务

在接口中添加插入和删除操作

package dao;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import pojo.User;

import java.util.List;

public interface UserDao {
    List<User> getUserList();

    @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
    int addUser(User user);

    @Delete("delete from mybatis.user where id = #{id}")
    int deleteUser(@Param("id") int id);
}

修改实现类

package dao;

import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import pojo.User;

import java.util.List;

public class UserDaoImp extends SqlSessionDaoSupport implements UserDao  {

    public List<User> getUserList() {
        UserDao mapper = getSqlSession().getMapper(UserDao.class);

        mapper.addUser(new User(11,"新同学","111111"));
        mapper.deleteUser(1);

        List<User> list = mapper.getUserList();
        return list;
    }

    public int addUser(User user) {
        return getSqlSession().getMapper(UserDao.class).addUser(user);
    }

    public int deleteUser(int id) {
        return getSqlSession().getMapper(UserDao.class).deleteUser(id);
    }
}

运行上面方法,正常运行不存在问题,现在我们让其中一个操作出错,将删除操作的代码故意写错

Spring学习笔记(四)——Mybatis-Spring和事务_第1张图片

在运行时,代码报错

Spring学习笔记(四)——Mybatis-Spring和事务_第2张图片

但是数据库中插入了新同学

Spring学习笔记(四)——Mybatis-Spring和事务_第3张图片

这不符合事务的要求,事务要求要么全部成功,要么全部失败,接下来我们用Spring来解决这个问题

9.1 配置

要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <constructor-arg ref="dataSource" />
bean>

9.2 配置事务通知


    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        
        <tx:attributes>
            <tx:method name="insert" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
        tx:attributes>
    tx:advice>

9.4 配置事务切入


    <aop:config>
        
        <aop:pointcut id="pointcut" expression="execution(* dao.*.*(..))"/>
        
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    aop:config>

11,“新同学”,“111111”));
mapper.deleteUser(1);

    List list = mapper.getUserList();
    return list;
}

public int addUser(User user) {
    return getSqlSession().getMapper(UserDao.class).addUser(user);
}

public int deleteUser(int id) {
    return getSqlSession().getMapper(UserDao.class).deleteUser(id);
}

}




运行上面方法,正常运行不存在问题,现在我们让其中一个操作出错,将删除操作的代码故意写错

[外链图片转存中...(img-eqqDP7ob-1595994417127)]

在运行时,代码报错

[外链图片转存中...(img-pVMlAJin-1595994417128)]

但是数据库中插入了新同学

[外链图片转存中...(img-jw7O2CiS-1595994417129)]

这不符合事务的要求,事务要求要么全部成功,要么全部失败,接下来我们用Spring来解决这个问题



#### 9.1 配置

要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 `DataSourceTransactionManager` 对象:

```xml

  

9.2 配置事务通知


    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        
        <tx:attributes>
            <tx:method name="insert" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
        tx:attributes>
    tx:advice>

propagetion(传播)属性:

  • REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
  • REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

9.4 配置事务切入


    <aop:config>
        
        <aop:pointcut id="pointcut" expression="execution(* dao.*.*(..))"/>
        
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    aop:config>

你可能感兴趣的:(Spring)