Integration of Spring and Mabatis

Posted by speedamp on Sun, 26 Sep 2021 20:52:06 +0200

1, Data source

        We can use mybatis's own data source or external data sources, such as dduid, C3P0 and Proxool. Here, I use C3P0. The most important XML configuration file in spring is ApplicationContext.xml. In order to facilitate our writing, I directly name the file beans.xml, and then inject C3P0 through attribute injection, To import the external database connection pool, you need to delete all the database connection contents in Mybatis.xml. The code is as follows:

   <!--Remember to remove the data source Mybatis.xml Configuration of data sources in-->
    <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/city?characterEncoding=utf8"/>
        <property name="user" value="root"/>          // Own database account
        <property name="password" value="123456"/>   // Password of your own database
    </bean>

2, Configure SqlSession factory

        Previously, if you did not use Spring dependency injection, you need to write your own SqlSession factory. The code is as follows:     

public final class MybatisTools {
    private static ThreadLocal<SqlSession> th=null;
    private static SqlSessionFactory ssf=null;
     

    // Static loading
    static
    {
        InputStream in=null;
        try {
             in= Resources.getResourceAsStream("mybatis.xml");
            th = new ThreadLocal<SqlSession>();
            ssf = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    // Get Sqlsession
    public static SqlSession getSqlsession()
    {
        SqlSession sse = th.get();
        if(sse==null)
        {
            sse = ssf.openSession();
            th.set(sse);
        }
        return sse;
    }
    
    // Close Sqlsession
    public static void closeSqlsession()
    {
        SqlSession sse = th.get();
        if(sse!=null)
        {
            sse.close();
            th.remove();
            th.set(null);
        }
    }
}

       

          Now, two points need to be noted for bean injection: the attribute datasource in the session factory needs to ref er to the id of the bean in the above data source, and also need to tell the attribute configLocation in the session factory bean that its value needs to be mapped to mybatis.xml, and the value of the last maperlocations needs to be mapped to the XML in which the sql statement is written. The code is as follows:

    <!--to configure session Factory remember to remove mb.xml Configuration of mappings in-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis.xml"/>
        <!--Where is the mapping file-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

          If you do so, you can remove the mappers of the xml file mapping sql statements in mybatis!

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>  // Directly remove
    </mappers>
</configuration>

         

3, Configure all interface bean s in mapper

        Note that the value value in the sqlSessionFactoryBeanName attribute must be the id of the above session factory, as follows:

   <!--mapper Burning seedlings spring To generate the required mapper bean-->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
        <!--Where to scan mapper Interface-->
        <property name="basePackage" value="springmybatis.mapper"/>
    </bean>

 

          The properties in the basePackage must be consistent with the location path of the specific mapper interface in your project.

If you complete the basic addition, deletion, modification and query in the above three steps, there is no big problem, but remember that we still need transactions.

4: Configuring transaction aspect bean s

      The dataSource in the tag here needs to depend on the data source id of the initial C3P0. Here, a paint class provided by spring has been configured as a bean, as follows:

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

       

        Then use the annotation to add an annotation to the method that needs to configure the transaction

@Transactional
 public void addUser(TbUser user)

        If you do this, manually add an exception to your business of adding data, as follows:

  @Override
    @Transactional(readOnly = false,timeout = -1,rollbackFor = Exception.class)
    public void add(User user) throws Exception{

        userMapper.insert(user);
        int n = 1/0;    // Add exception manually
        userMapper.insert(user);
    }

        Then you check the contents of the database, and you will find that the transaction is not rolled back, that is, the insert statement executed before the exception is still inserted into the database. Why? Originally, we not only need to add the transactions provided by spring as beans, but also need to configure the transaction driver and add tx nodes. Otherwise, there will be no tx tag, that is, we need to add the following in the beans.xml file:

<!--Annotation driven for configuration transactions-->
<tx:annotation-driven></tx:annotation-driven>

    <!--Remember to add tx node-->
    <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"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           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-4.3.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

      

5: Configuration in transactions      

   

@Transactional(readOnly = false,timeout = -1,rollbackFor = Exception.class)
  1. readonly

        If it is set to only, it is mainly used for query. If it is set to false, it is used for addition, deletion and modification. If it is not set, it is false by default

    2. timeout

        After establishing a connection with the database, if there is no logical processing after this time, the connection will be disconnected. If it is set to - 1, the timeout of the database will be used,

    3.rollbackFor

        It is recommended to set it to Exception.class, so that if an exception is thrown manually, it can also be caught, and the transaction will be rolled back

6, Behavior of transaction propagation

@Transactional(propagation = Propagation.REQUIRED) 
  1.     Support current transaction:      
  • TransactionDefinition.PROPAGATION_REQUIRED: if a transaction currently exists, join the transaction; If there is no current transaction, a new transaction is created.
  • TransactionDefinition.PROPAGATION_SUPPORTS: if a transaction currently exists, join the transaction; If there are currently no transactions, continue to run in a non transactional manner.    
  • TransactionDefinition.PROPAGATION_MANDATORY: if a transaction currently exists, join the transaction; Throw an exception if there is no current transaction. (mandatory: mandatory).

    two     Current transaction not supported:

  • TransactionDefinition.PROPAGATION_REQUIRED_NEW: create a new transaction. If there is a current transaction, suspend the current transaction.
  • TransactionDefinition.PROPAGETION_NOT_SUPPORTED: run in non transaction mode. If there is a transaction, suspend the current transaction.
  • TransactionDefinition.PROPAGATION_NEVER: runs in a non transactional manner. If there is a transaction, an exception will be thrown.

    three     other

  • TransactionDefinition.PROPAGATION_NESTED: if a transaction currently exists, create a transaction to run as a nested transaction of the current transaction; If there is no transaction at present, this value is equivalent to transactiondefinition.promotion_ REQUIRED.

Topics: Spring