Spring学习(十二)

12. 整合Mybatis

步骤:

  1. 导入相关jar包

    • junit

    • mybatis

    • sql数据库

    • spring相关的

    • aop织入

    • mybatis-spring【new】

      (注意!!这里的spring-core包要和spring-jdbc包的版本一致!!!!否则报错java.lang.NoSuchMethodError: org.springframework.beans.factory.config.ConfigurableListableBeanFactor)

    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.28version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.9version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.3.16version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.3.6version>
        dependency>
        
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.5version>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.2version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>5.3.6version>
        dependency>
        
    dependencies>
    
  2. 编写配置文件

  3. 测试

12.1 回忆MyBatis

  1. 编写实体类

    @Data
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
    
  2. 编写核心配置文件

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.Yurrize.pojo"/>
        typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306"/>
                    <property name="username" value="root"/>
                    <property name="password" value="020113"/>
                dataSource>
            environment>
        environments>
        <mappers>
            <mapper class="com.Yurrize.mapper.UserMapper"/>
        mappers>
    configuration>
    
  3. 编写接口

    public interface UserMapper {
        public List<User> selectUser();
    }
    
  4. 编写mapper.xml

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.Yurrize.mapper.UserMapper">
        <select id="selectUser" resultType="User">
            select * from mybatis.user
        select>
    mapper>
    
  5. 测试

    public class MyTest {
        @Test
        public void test() throws IOException {
            String resources="mybatis-config.xml";
            InputStream stream = Resources.getResourceAsStream(resources);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.selectUser();
            for (User user : userList) {
                System.out.println(user);
            }
        }
    }
    

12.2 MyBatis-Spring

  • 什么是MyBatis-Spring

    MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。

  1. 编写数据源配置

    • 核心配置文件:代替原来的mybatis.xml
    
    <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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
        
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="020113"/>
        bean>
    
        
        <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:com/Yurrize/mapper/*.xml"/>
        bean>
        
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            
            <constructor-arg index="0" ref="sqlSessionFactory"/>
        bean>
    beans>
    
    • 在原来的mybatis文件中保留别名,与设置等标签,当然也可以整合到核心文件中
    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.Yurrize.pojo"/>
        typeAliases>
    	<setting.......>setting.......>
    configuration>
    
    • 将实现类的bean分离出来,便于阅读
    
    <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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
        <import resource="spring-dao.xml"/>
        <bean id="userMapper" class="com.Yurrize.mapper.UserMapperImpl">
            <property name="sqlSessionTemplate" ref="sqlSession"/>
        bean>
    beans>
    
  2. sqlSessionFactory

        
        <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:com/Yurrize/mapper/*.xml"/>
        bean>
    
  3. sqlSessionTemplate

        <!--SqlSessionTemplate:就是我们使用的sqlSession-->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <!--只能使用构造器注入sqlSessionFactor,因为没有set方法-->
            <constructor-arg index="0" ref="sqlSessionFactory"/>
        </bean>
    
  4. 需要给接口添加实现类【新增】

    public class UserMapperImpl implements UserMapper{
        //在原来我们所有操作都是用sqlSession来执行,现在使用sqlSessionTemplate
        private SqlSessionTemplate sqlSessionTemplate;
    
        public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
            this.sqlSessionTemplate = sqlSessionTemplate;
        }
    
        @Override
        public List<User> selectUser() {
            UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
            return mapper.selectUser();
        }
    }
    
  5. 将自己写的实现类注入到Spring中测试

    public class MyTest {
        @Test
        public void test() throws IOException {
    
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
            for (User user : userMapper.selectUser()) {
                System.out.println(user);
            }
        }
    }
    

12.3 SqlSessionDaoSupport

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

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

在这个类里面,通常更倾向于使用 MapperFactoryBean,因为它不需要额外的代码。但是,如果你需要在 DAO 中做其它非 MyBatis 的工作或需要一个非抽象的实现类,那么这个类就很有用了。

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

假设类 UserMapperImplSqlSessionDaoSupport 的子类,可以编写如下的 Spring 配置来执行设置:

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

13. 声明式事务

13.1 回顾事务

  • 把一组事务当初一个业务来做,要么都成功,要么都失败
  • 事务在项目开发中,涉及到数据一致性问题
  • 确保完整性和一致性

事务的ACID原则:

  • 原子性:确保事务要不都成功,要不都失败
  • 一致性:一旦事务完成,要么一致提交,数据前后保持不变
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,但要排除其他事务对本次事务的影响
  • 持久性:事务一旦提交,无论系统发生什么问题,结果不会被影响,被持久化的写到存储器中

13.2 Spring中的事务管理

  • 声明式事务:Aop
  • 编程式事务:需要在代码中运行事务管理

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


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

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

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况下;
  • 如果我们不在Spring中配置声明式事务,我们就需要在代码中手动配置事务
  • 事务在项目开发中十分重要,涉及到数据的一致性和完整性问题
    essionTemplate。如果两个属性都被设置了,那么SqlSessionFactory` 将被忽略。

假设类 UserMapperImplSqlSessionDaoSupport 的子类,可以编写如下的 Spring 配置来执行设置:

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

13. 声明式事务

13.1 回顾事务

  • 把一组事务当初一个业务来做,要么都成功,要么都失败
  • 事务在项目开发中,涉及到数据一致性问题
  • 确保完整性和一致性

事务的ACID原则:

  • 原子性:确保事务要不都成功,要不都失败
  • 一致性:一旦事务完成,要么一致提交,数据前后保持不变
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,但要排除其他事务对本次事务的影响
  • 持久性:事务一旦提交,无论系统发生什么问题,结果不会被影响,被持久化的写到存储器中

13.2 Spring中的事务管理

  • 声明式事务:Aop
  • 编程式事务:需要在代码中运行事务管理

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


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

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

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况下;
  • 如果我们不在Spring中配置声明式事务,我们就需要在代码中手动配置事务
  • 事务在项目开发中十分重要,涉及到数据的一致性和完整性问题

你可能感兴趣的:(Spring,spring,学习,java)