spring整合mybatis方式
环境准备
数据库 library,创建表 book
1 2 3 4 5 6 7 8 9 10
| CREATE TABLE `book` ( `book_id` int NOT NULL AUTO_INCREMENT , `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `number` int NOT NULL , PRIMARY KEY (`book_id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC ;
|
插入数据
1 2 3 4 5 6
| INSERT INTO `book` (`book_id`, `name`, `number`) VALUES (1000, 'Java程序设计', 10), (1001, '数据结构', 10), (1002, '设计模式', 10), (1003, '编译原理', 10);
|
创建项目
创建图书管理系统 library,使用 idea 创建一个空的 maven 项目,在 pom.xml 文件中添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.chenpeng</groupId> <artifactId>library</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.8.0-M1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.6</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> </project>
|
项目创建完成,接下来使用两种方式整合 Mybatis
方式一:通过映射文件
使用 MyBatis-Spring 将 MyBatis 代码无缝地整合到 spring 中,首先需要 spring 的配置
要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。
在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的。
1
| sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
|
而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建,只需要注入一些属性,比如数据源 dataSource,mybatis 配置文件等。
1 2 3 4 5
| <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/chenpeng/mapper/BookMapper.xml"/> </bean>
|
在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 session。
1 2 3 4
| SqlSession session = sqlSessionFactory.openSession().getSession(); Object mapper = session.getMapper(someMapper.class);
session.close()
|
使用 MyBatis-Spring 之后,不再需要直接使用 SqlSessionFactory 了,因为你的 bean 可以被注入一个线程安全的 SqlSession,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。
1 2 3
| <bean id="bookMapper" class="com.chenpeng.mapper.BookMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
|
上面配置中 sqlSession 可以使用SqlSessionTemplate 来实现。 SqlSessionFactory 作为构造方法的参数来创建 SqlSessionTemplate 对象。
1 2 3 4
| <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
|
根据以上结论,可以编写如下 spring-dao.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?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" 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">
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <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" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/chenpeng/mapper/BookMapper.xml"/> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
<bean id="bookMapper" class="com.chenpeng.mapper.BookMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean> </beans>
|
注意
我们使用了SqlSessionTemplate 作为sqlSession的一个实现,需要在bean中添加一个SqlSession 属性
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class BookMapperImpl implements BookMapper { private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; }
@Override public Book queryById(long id) { BookMapper mapper = sqlSession.getMapper(BookMapper.class); return mapper.queryById(id); } }
|
由于使用的MySQL是5.7,jdbc中的属性设置如下
1 2 3 4
| jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=chenpeng
|
如果使用的8.0以上版本,驱动driver和url有所不同
1 2
| jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/library?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
|
如果不使用 SqlSessionTemplate 提供sqlSession,可以使用 SqlSessionDaoSupport 抽象支持类,通过调用getSqlSession() 方法你会得到一个 SqlSessionTemplate。
1 2 3 4 5 6 7
| public class BookMapperImpl extends SqlSessionDaoSupport implements BookMapper { @Override public Book queryById(long id) { BookMapper mapper = getSqlSession().getMapper(BookMapper.class); return mapper.queryById(id); } }
|
SqlSessionDaoSupport 需要通过属性设置一个 sqlSessionFactory 或 SqlSessionTemplate。如果两个属性都被设置了,那么 SqlSessionFactory 将被忽略。
1 2 3
| <bean id="BookMapper" class="org.mybatis.spring.sample.dao.BookMapperImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
|
测试dao层
1 2 3 4 5 6 7 8
| @Test public void test01() { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); BookMapper bookMapper = context.getBean("bookMapper", BookMapper.class); long bookId = 1000L; Book book = bookMapper.queryById(bookId); System.out.println(book); }
|
可以得到如下输出
1 2 3
| 九月 10, 2021 10:55:39 上午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info 信息: {dataSource-1} inited Book{bookId=0, name='Java程序设计', number=10}
|
方式二:通过 Mapper 接口
上面的方法需要一个个地注册所有映射器 mapper,实际上 mybatis-spring 可以使用对类路径进行扫描来发现他们。
MapperScannerConfigurer 是一个 BeanDefinitionRegistryPostProcessor,这样就可以作为一个 bean,包含在经典的 XML 应用上下文中。为了配置 MapperScannerConfigurer,使用下面的 Spring 配置:
1 2 3 4
| <bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.chenpeng.mapper"/> </bean>
|
我们不用对 mapper 接口进行实现,MapperScannerConfigurer 会自动解析该类路径下的同名 xml 文件。
我们只需要得到该 Mapper 的class 类型,即可通过反射得到映射器 mapper
1
| BookMapper mapper = context.getBean(BookMapper.class);
|
参考资料
Spring的基本配置和Spring与Mybatis的整合_CodeChen-CSDN博客_spring整合mybatis
mybatis-spring