#整合MyBatis ##SqlSessionFactory 在一般的数据库项目当中,我们需要构建SqlSessionFactoryBuilder,获取session,在使用MyBatis的session API去操作数据库。
在Spring中,MyBatis提供了SqlSessionFactoryBean来整合MyBatis所提供的功能
##添加mybatis-spring依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
除了Mybatis-Spring还要添加MyBatis本身的依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
##在Spring配置中定义SqlSessionFactoryBean
<!-- MyBatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
</bean>
如下方式执行配置文件,分别制定configLocation和mapperLocations
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
</bean>
##Annotation定义Mapper - 注解 通过Annotation方式声明接口,接口与查询分开
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{userId}")
User getUser(@Param("userId") String userId);
}
##XML方式定义Mapper
public interface UserMapper{
User getUser(String userId);
}
对应的mapper定义
<mapper namespace="com.netease.course.UserMapper">
<select id="getUser" resultType="User">
SELECT * FROM users WHERE id = #{userId}
</select>
</mapper>
一般情况下,自己的项目更倾向于Annotation方式来定义Mapper,不用多XML文件,项目看起来更干净。
定义完毕Mapper,要告诉Spring注册成为Bean
##定义Mapper Bean Mapper Bean可以理解成DAO,完成的工作就是CRUD,都可以定义在Mapper里面。 ###通过XML配置文件方式 需要制定MapperFactoryBean的Class,需要这个类把接口转换成Bean。属性有声明接口
实际项目当中,会有很多Mapper
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.netease.course.MybatisUserDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
###自动发现机制Mapper 需要添加额外配置, 需要定义mybatis的tag,xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
,然后填写对应xsd,添加自动扫描的包名称
<mybatis:scan base-package="com.netease.course" />
一般情况下,我们不需要执行sqlSessionFactory,默认会自动注入,但是如果多个数据源定义了不同的SqlSessionFactory,则按照如下进行配置
<mybatis:scan base-package="com.netease.course" factory-ref="sqlSessionFactory" />
###另外一种自动发现机制
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.netease.course" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
##使用与注入Mapper 可以通过Autowired Annotation进行注入使用。这样我们可以直接使用预定义好的方法,可以把SQL封装好。但是并没有把session相关的接口暴露出来,执行逻辑都封装掉了。但我们有时候需要更细致的控制。
public class SomeService{
@Autowired
private UserMapper userMapper;
}
##SqlSessionTemplate
- 定义
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
- 使用 以下方式是通过XML方式定义SQL,则可以直接调用
public class UserDao {
@Autowired
Private SqlSession sqlSession;
public User getUSer(String userId) {
return (User) sqlSession.selectOne("com.netease.course.UserMapper.getUser",userId);
}
}
##MyBatis与Spring事务管理整合
- 向用户透明
在配置与代码里面,不需要显示指定任何东西,MyBatis-Spring把TransactionManager与MyBatis的SQL操作会无缝的整合起来,这种方式不需要做额外声明。可以直接使用Spring事务管理的内容功能 - 支持声明式事务及编程式事务
直接在Mapper和Dao上支持事务,进行配置事务的属性
##实际整合MyBatis 接口
package com.hava.spring_data.repository;
import com.hava.spring_data.entity.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* Created by yanfa on 2016/10/26.
*/
public interface MyBatisDao {
@Select("SELECT * FROM user WHERE first_name= #{firstName}")
public User findOne(String firstName);
@Select("SELECT * FROM user")
public List<User> findAll();
}
配置
<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
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.xsd
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd">
<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<context:property-placeholder location="db.properties" />
<!-- MyBatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
<!--<property name="configLocation" value="classpath:sqlMapConfig.xml" />-->
<!--<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />-->
</bean>
<!--<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!--<property name="mapperInterface" value="com.netease.course.MybatisUserDao" />-->
<!--<property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
<!--</bean>-->
<mybatis:scan base-package="com.hava.spring_data.repository" />
</beans>
运行类
package com.hava.spring_data;
import com.hava.spring_data.entity.User;
import com.hava.spring_data.repository.MyBatisDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by yanfa on 2016/10/26.
*/
public class MyBatisSpringMain {
public static void main(String [] args){
ApplicationContext context = new ClassPathXmlApplicationContext("mybatis-context.xml");
MyBatisDao myBatisDao = context.getBean("myBatisDao",MyBatisDao.class);
for(User user : myBatisDao.findAll())
System.out.println(user.getFirst_name() + " " + user.getLast_name());
User user = myBatisDao.findOne("Zhan");
System.out.println(user.getId() + ":" + user.getFirst_name() + " " + user.getLast_name());
((ConfigurableApplicationContext) context).close();
}
}
运行结果
Meimie Han
Lei Li
Meimie Han
Lei Li
Zhan Peng
7:Zhan Peng
##需要添加映射Annotation 如果在查询之后,一些值为空,说明实际的数据库列与对象属性无法进行对应,这个时候需要添加@Results的注解来进行映射
@Results({
@Result(property = "id",column = "id"),
@Result(property = "firstName",column = "first_name"),
@Result(property = "lastName",column = "last_name"),
})
@Select("SELECT * FROM user")
public List<BigUser> getUserList();
注意:@Results是进行的对象映射,并不针对是否是List,也就是说findOne也是这样映射的。