这篇记录Mybatis Spring的一些简单使用。
MyBatis在Spring中,相比在MyBatis中有了一些变化
配置上:
- 仍然需要创建
SqlSessionFactory
,但是不是通过SqlSessionFactoryBuilder
了,而是需要通过SqlSessionFactoryBean
,配置也是在这里配置。这里用的是Spring Bean的factory
构造方式,其实是用于构造了SqlSession
的。 - 可以通过Spring中的
transactionManager
管理MyBatis中的SqlSession事务,这样需要定义transactionManager
的bean - 使用Spring中依赖注入的DataSource,一般不在mybatis的配置中配置了
使用上
- 仍然可以通过SqlSession使用,但是不受Spring管理,Spring中一般是通过Spring中的
SqlSessionTemplate
来进行管理,完全替代mybatis中的SqlSession
。 - 更好的Mapper类支持:相比使用
SqlSessionTemplate
,定义一个接口类,通过接口去管理MyBatis中实际的查询
sqlsession
方式
配置
spring bean相关配置
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<bean name="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url"
value="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations"
value="classpath*:mappers/*.xml" />
<property name="configLocation"
value="classpath:conf/mybatis-config.xml" />
</bean>
<bean id="sqlSession"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
需要关注一下sqlSessionFactory
(实际是SqlSessionFactoryBean
的类型):
- 通过
dataSource
属性指明datasource - 通过
configLocation
指明mybatis配置文件的位置,当然也可以不指定,因为很多基本内容在这里就能配置了 - 通过
mapperLocations
指明mapper的配置xml文件的位置,这个信息也可以在mybatis配置文件中指定,但是我测试的时候发现只有在这里才能使用*
这种通配符
另外这里注入了SqlSessionTemplate
类型的sqlSession
,这样在代码中就能直接通过DI得到SqlSessionTemplate
。
这里没有粘贴了对应的Mapper XML文件和mybatis文件,因为内容并没有特别的变化
使用
注入sqlSession
后,像普通mybatis一样使用即可
@Repository
public class UserRepository {
@Autowired
private SqlSession sqlSession;
public User getById(int id) {
return sqlSession.selectOne("UserMapper.getById", id);
}
public List<User> getAll() {
return sqlSession.<User>selectList("UserMapper.getAll");
}
}
注意这里的SqlSession,实际是SqlSessionTemplate
类型的bean了
Mapper接口方式
通过字符串指明一个查询并不直观,不利于错误识别,而且传入的参数也不好确定,需要看文件。
MyBatis中,可以通过定义一个mapper
接口,接口中标明所有的方法,实际使用时,通过接口访问。
配置
通过spring配置
<mybatis:scan
base-package="com.mosakashaka.mybatisspringsample.mapper" />
将某一个包下面的所有接口扫描为mapper接口类。
使用
通过上述配置,如下类:
package com.mosakashaka.mybatisspringsample.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.mosakashaka.mybatisspringsample.model.User;
public interface UserMapper {
public User getById(int id);
public List<User> getAll();
@Select("select * from tb_user limit 1")
User getOne();
}
注意:这里使用了一个mybatis内嵌@Select
注解生成了一个内联sql接口。
就能在需要使用的时候被注入。替换之前SqlSession的方式:
@Repository
public class UserRepository {
//这个不再需要了
@Autowired
private SqlSession sqlSession;
@Autowired
private UserMapper userMapper;
public User getById(int id) {
// return sqlSession.selectOne("UserMapper.getById", id);
return userMapper.getById(id);
}
public User getOne() {
// return sqlSession.selectOne("UserMapper.getById", id);
return userMapper.getOne();
}
public List<User> getAll() {
// return sqlSession.<User>selectList("UserMapper.getAll");
return userMapper.getAll();
}
}
那么接口中getAll
和getById
并没有实现,是如何找到的?
mybatis会根据这个mapper类的pacage和类名,匹配它加载的xml配置文件中的namespace。
比如上述类UserMapper.java在包com.mosakashaka.mybatisspringsample.mapper
中,而定义一个mapper xml时,如果指定它的namespace如下:
<mapper namespace="com.mosakashaka.mybatisspringsample.mapper.UserMapper">
则就会自动跟这个接口关联,并且mapper文件中的sql方法会按照id和mapper类中的方法名关联找到实现。
后记
不过写mapper类其实相对来说也是个工作量,如果不能简化这个过程,还不如直接在repository层写查询id呢。
像Spring JPA中,可以通过方法名自动生成查询,还有一些预先定义的JpaRepository
,CrudRepository
类可以集成。
相对的,mybatis有一个mybatis generator
工具,可以自动生成常用的查询接口类和mapper文件,通过这种方式简化了mybatis的使用过程。