According to the official statement, the development work of Spring3 was completed before the advent of ibatis3, that is, Mybatis3, so there is still no support for Mybatis3 in Spring3. Therefore, the Mybatis community developed Mybatis-Spring itself to meet the needs of Mybatis users to integrate Spring. The following will give a brief introduction to the usage of integrating Mybatis and Spring through Mybatis-Spring.
MapperFactoryBean
First, we need to download the Mybatis-Spring jar package from the Mybatis official website and add it to the class path of our project. Of course, we also need to add the related jar package of Mybatis and the related jar package of Spring. We know that all operations in Mybatis are based on a SqlSession, and SqlSession is generated by SqlSessionFactory, and SqlSessionFactory is generated by SqlSessionFactoryBuilder. But Mybatis-Spring is based on SqlSessionFactoryBean. When using Mybatis-Spring, we also need SqlSession, and this SqlSession is embedded in the program and generally does not require us to access it directly. SqlSession is also generated by SqlSessionFactory, but Mybatis-Spring encapsulates a SqlSessionFactoryBean for us. In this bean, we still use SqlSessionFactoryBuilder to establish the corresponding SqlSessionFactory, and then obtain the corresponding SqlSession. Through SqlSessionFactoryBean we can provide some configuration information of Mybatis by specifying some properties on it. So next we need to define a SqlSessionFactoryBean in Spring's applicationContext configuration file.
Xml code
<bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" / > <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" /> </bean>
When defining SqlSessionFactoryBean, the dataSource attribute must be specified, which represents the data source used to connect to the database. Of course, we can also specify some other attributes. Here are a few:
mapperLocations: It indicates the location where our Mapper file is stored. When our Mapper file is in the same location as the corresponding Mapper interface, there is no need to specify the value of this attribute.
configLocation: used to specify the configuration file location of Mybatis. If this attribute is specified, the corresponding SqlSessionFactoryBuilder will be constructed using the content of the configuration file as the configuration information, but the content specified by subsequent attributes will overwrite the corresponding content specified in the configuration file.
typeAliasesPackage: It generally corresponds to the package where our entity class is located. At this time, the simple class name in the corresponding package that does not include the package name will be automatically taken as the alias including the package name. Multiple packages can be separated by commas or semicolons.
typeAliases: array type, used to specify aliases. After specifying this attribute, Mybatis will use the short name of this type as the alias of this type, provided that the @Alias annotation is not marked on the class, otherwise the value corresponding to the annotation will be used as the alias of this type.
Xml code
<property name="typeAliases"> <array> <value>com.tiantian.mybatis.model.Blog</value> <value>com.tiantian.mybatis.model.Comment</value> </array> </property >
plugins: array type, used to specify the Interceptor of Mybatis.
typeHandlersPackage: used to specify the package where the TypeHandler is located. If this attribute is specified, SqlSessionFactoryBean will automatically register the classes under the package as the corresponding TypeHandler. Multiple packages can be separated by commas or semicolons.
typeHandlers: Array type, representing TypeHandler.
The next step is to define the MapperFactoryBean corresponding to the Mapper object we want in Spring's applicationContext file. The Mapper object we want can be obtained through MapperFactoryBean. MapperFactoryBean implements Spring's FactoryBean interface, so MapperFactoryBean obtains the corresponding Mapper object through the getObject method defined in the FactoryBean interface. When defining a MapperFactoryBean, there are two properties that we need to inject. One is the sqlSessionFactory used by Mybatis-Spring to generate SqlSessionTemplate objects that implement the SqlSession interface; the other is the corresponding Mapper interface we want to return.
After defining the MapperFactoryBean corresponding to the corresponding Mapper interface, we can inject our corresponding Mapper interface into the bean object managed by Spring, such as the Service bean object. In this way, when we need to use the corresponding Mapper interface, MapperFactoryBean will obtain the corresponding Mapper interface from its getObject method, and internally getObject will still call the getMapper (Mapper interface) method of the SqlSession interface through the properties we injected to return the corresponding Mapper. interface. In this way, the integration of Mybatis and Spring is achieved by handing over SqlSessionFactory and the corresponding Mapper interface to Spring management.
Spring's applicationContext.xml configuration file:
Xml code
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans /spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring- mvc-3.0.xsd"> <context:component-scan base-package="com.tiantian.mybatis"/> <context:property-placeholder location="classpath:config/jdbc.properties"/> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name ="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath: com/tiantian/mybatis/mapper/*.xml"/> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean id="blogMapper"> <property name="mapperInterface" value="com.tiantian.mybatis.mapper.BlogMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> beans> </beans>
BlogMapper.xml file:
Xml code
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis -3-mapper.dtd"> <mapper namespace="com.tiantian.mybatis.mapper.BlogMapper"> <!-- Add new record--> <insert id="insertBlog" parameterType="Blog" useGeneratedKeys="true" keyProperty="id"> insert into t_blog(title,content,owner) values(#{title},#{content},#{owner}) </ insert> <!-- Query a single record--> <select id="selectBlog" parameterType="int" resultMap="BlogResult"> select * from t_blog where id = #{id} </select> <!-- Modify record--> <update id="updateBlog" parameterType="Blog"> update t_blog set title = #{title},content = #{content},owner = #{owner} where id = #{id} </update> <!-- Query all records--> <select id="selectAll" resultType="Blog"> select * from t_blog </select> <!-- Delete records--> <delete id="deleteBlog" parameterType="int"> delete from t_blog where id = #{id} </delete> </mapper>
BlogMapper.java:
Java code
package com.tiantian.mybatis.mapper; import java.util.List; import com.tiantian.mybatis.model.Blog; publicinterface BlogMapper { public Blog selectBlog(int id); publicvoid insertBlog(Blog blog); publicvoid updateBlog(Blog blog ); publicvoid deleteBlog(int id); public List<Blog> selectAll(); }
BlogServiceImpl.java:
Java code
package com.tiantian.mybatis.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.tiantian.mybatis.mapper.BlogMapper; import com.tiantian. mybatis.model.Blog; import com.tiantian.mybatis.service.BlogService; @Service publicclass BlogServiceImpl implements BlogService { private BlogMapper blogMapper; publicvoid deleteBlog(int id) { blogMapper.deleteBlog(id); } public Blog find(int id) { returnblogMapper.selectBlog(id); } public List<Blog> find() { returnblogMapper.selectAll(); } publicvoid insertBlog(Blog blog) { blogMapper.insertBlog(blog); } publicvoid updateBlog(Blog blog) { blogMapper.updateBlog(blog); } public BlogMapper getBlogMapper() { returnblogMapper; } @Resource publicvoid setBlogMapper(BlogMapper blogMapper) { this.blogMapper = blogMapper; } }
MapperScannerConfigurer
When using the above method for integration, if we have a Mapper, we need to define a corresponding MapperFactoryBean. When we have relatively few Mappers, this is okay, but when we have quite a lot of Mappers, we define each Mapper like this The corresponding MapperFactoryBean appears to be slower. For this purpose, Mybatis-Spring provides us with a class called MapperScannerConfigurer. Through this class, Mybatis-Spring will automatically register the MapperFactoryBean object corresponding to Mapper for us.
If we need to use MapperScannerConfigurer to help us automatically scan and register the Mapper interface, we need to define a bean corresponding to MapperScannerConfigurer in Spring's applicationContext configuration file. For MapperScannerConfigurer, there is one attribute that we must specify, and that is basePackage. basePackage is used to specify the base package where the Mapper interface file is located. The Mapper interfaces under this base package or all its sub-packages will be searched. Multiple base packages can be separated by commas or semicolons. The simplest MapperScannerConfigurer definition is to specify only one basePackage attribute, such as:
Xml code
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> </bean>
In this way, MapperScannerConfigurer will scan all interfaces under the specified base package and register them as MapperFactoryBean objects. When using MapperScannerConfigurer and adding the basePackage attribute, the applicationContext configuration file in our example above will become like this:
Xml code
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans /spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring- mvc-3.0.xsd"> <context:component-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location="classpath:config/jdbc.properties" /> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name ="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath: com/tiantian/mybatis/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> </bean> </beans>
Sometimes the base package we specify is not all the Mapper interfaces we defined. For this reason, MapperScannerConfigurer also provides us with two other attributes that can narrow the scope of search and registration. One is annotationClass and the other is markerInterface.
annotationClass: When annotationClass is specified, MapperScannerConfigurer will only register interfaces marked with the annotationClass annotation.
markerInterface: markerInterface is used to specify an interface. When markerInterface is specified, MapperScannerConfigurer will only register the interface inherited from markerInterface.
If both of the above properties are specified, MapperScannerConfigurer will take their union instead of their intersection. Even if annotationClass is used for marking or the interface inherited from markerInterface will be registered as a MapperFactoryBean.
Now assuming that our Mapper interface inherits a SuperMapper interface, then we can define our MapperScannerConfigurer like this.
Xml code
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/> </bean>
If the annotation MybatisMapper tag is used, then we can define our MapperScannerConfigurer like this.
Xml code
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="annotationClass" value="com.tiantian.mybatis.annotation.MybatisMapper"/> </bean>
In addition to the properties used to narrow the scope of the registered Mapper interface, we can also specify some other properties, such as:
sqlSessionFactory: This property has been deprecated. When we use multiple data sources, we need to use sqlSessionFactory to specify the SqlSessionFactory that needs to be used when registering MapperFactoryBean, because when sqlSessionFactory is not specified, one will be automatically injected in the Autowired manner. In other words, when we only use one data source, that is, when we only define one SqlSessionFactory, we do not need to specify SqlSessionFactory for MapperScannerConfigurer.
sqlSessionFactoryBeanName: Its function is the same as sqlSessionFactory, except that it specifies the bean name corresponding to the defined SqlSessionFactory.
sqlSessionTemplate: This attribute has been deprecated. Its function is also equivalent to sqlSessionFactory, because as mentioned earlier, MapperFactoryBean ultimately uses the getMapper method of SqlSession to obtain the corresponding Mapper object. It only needs to be specified when multiple SqlSessionTemplates are defined. For a MapperFactoryBean, only one of SqlSessionFactory and SqlSessionTemplate is required. When both are specified, SqlSessionFactory will be ignored.
sqlSessionTemplateBeanName: Specify the bean name corresponding to the sqlSessionTemplate to be used.
Note: Since using the sqlSessionFactory and sqlSessionTemplate properties will cause some content to be loaded before the PropertyPlaceholderConfigurer, the external property information used in the configuration file cannot be replaced in time and errors will occur. Therefore, the official new The sqlSessionFactory and sqlSessionTemplate properties have been abandoned in Mybatis-Spring. It is recommended that you use the sqlSessionFactoryBeanName property and the sqlSessionTemplateBeanName property.
Xml code
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mybatis="http://www.mybatis.org/schema/mybatis" xsi:schemaLocation="http://www.springframework .org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.mybatis.org/schema/mybatis http:/ /www.mybatis.org/schema/mybatis/mybatis-spring.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location= "classpath:config/jdbc.properties" /> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/mybatis/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> </beans>
SqlSessionTemplate
In addition to using the Mapper interface directly after the above integration, Mybatis-Spring also provides us with a way to directly use SqlSession. Mybatis-Spring provides us with a SqlSessionTemplate class that implements the SqlSession interface. It is thread-safe and can be used by multiple Dao at the same time. At the same time, it is also associated with Spring's transaction to ensure that the currently used SqlSession is one that has been bound to Spring's transaction. And it can also manage the submission and closing of Session by itself. When Spring's transaction management mechanism is used, SqlSession can also be submitted and rolled back along with Spring's transactions.
When using SqlSessionTemplate we can define it in Spring's applicationContext configuration file as follows:
<bean id="sqlSession"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
In this way, we can directly use SqlSessionTemplate to program in Dao through Spring's dependency injection. At this time, our Dao may look like this:
Java code
package com.tiantian.mybatis.dao; import java.util.List; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.stereotype.Repository; import com.tiantian.mybatis.model. Blog; @Repository publicclass BlogDaoImpl implements BlogDao { private SqlSessionTemplate sqlSessionTemplate; publicvoid deleteBlog(int id) { sqlSessionTemplate.delete("com.tiantian.mybatis.mapper.BlogMapper.deleteBlog", id); } public Blog find(int id) { returnsqlSessionTemplate.selectOne("com.tiantian.mybatis. mapper.BlogMapper.selectBlog", id); } public List<Blog> find() { returnthis.sqlSessionTemplate.selectList("com.tiantian.mybatis.mapper.BlogMapper.selectAll"); } publicvoid insertBlog(Blog blog) { this.sqlSessionTemplate.insert("com.tiantian. mybatis.mapper.BlogMapper.insertBlog", blog); } publicvoid updateBlog(Blog blog) { this.sqlSessionTemplate.update("com.tiantian.mybatis.mapper.BlogMapper.updateBlog", blog); } public SqlSessionTemplate getSqlSessionTemplate() { returnsqlSessionTemplate; } @Resource publicvoid setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { this.sqlSessionTemplate = sqlSessionTemplate; } }
Note:
This article is written based on Mybatis3.2.1, Mybatis-Spring1.1.0 and Spring3.1.
The above is a brief analysis of the implementation process of the integration of mybatis and spring introduced in this article. I hope you like it. The next article will introduce to you the integration method of spring and mybatis.