引言
当我们想操作数据库的时候,有多种选择,比如上一篇文章用的JDBC,或者Spring的JdbcTemplate,或者Hibernate,在就是MyBatis。
Mybatis是一种半自动ORM框架,需要手动维护SQL,一般是xml文件,优点就是好控制,缺点就是维护的数据多。项目中现在使用springboot+tk-Mybatis,使用起来很方便,对用户屏蔽内部实现,但是对于学习来说,还是使用最基础的配置,能够更好的理解。
1、Spring+Mybatis例子准备
这里简单的写个Spring+Mybatis的小例子跑起来,之后分析:
1.1、test库:
1 2 3 4
| CREATE TABLE `people` ( `id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
1.2、entity:
1 2 3 4 5 6 7
| import lombok.Data;
@Data public class PeopleEntity { private int id; private String name; }
|
1.3、mapper.java:
1 2 3
| public interface PeopleMapper { List<PeopleEntity> query(); }
|
1.4、mapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?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.demo.mybatis.mapper.PeopleMapper"> <resultMap id="BaseResultMap" type="com.demo.mybatis.entity.PeopleEntity"> <result column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> </resultMap>
<select id="query" resultMap="BaseResultMap"> SELECT id,name from people </select>
</mapper>
|
1.5、因为我是以springboot2.0的架子学习,所以引入pom:
1 2 3 4 5 6 7 8 9
| <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
|
上面为准备阶段,下面通过两种方式使用MyBatis。
2、两种方式使用mybatis
2.1、springboot默认配置实现
2.1.1、application.properties
1 2 3 4 5 6
| mybatis.type-aliases-package=com.demo.mybatis.entity spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 mybatis.mapper-locations=classpath:mapper/*.xml
|
2.1.2、Application
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @SpringBootApplication @MapperScan("com.demo.mybatis.mapper") public class Application { public static void main(String[] args) { ConfigurableApplicationContext confApp = null; try { confApp = SpringApplication.run(Application.class, args); } finally { close(confApp); } } private static void close(ConfigurableApplicationContext confApp) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { if (confApp != null) { confApp.close(); } } }); } }
|
2.1.3、AppApplicationTests
1 2 3 4 5 6 7 8 9 10
| @RunWith(SpringRunner.class) @SpringBootTest public class AppApplicationTests { @Autowired private PeopleMapper peopleMapper; @Test public void test() { System.out.println(JSONObject.toJSONString(peopleMapper.query())); } }
|
2.1.4、结果
1 2 3 4 5 6
| com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. [{"id":1,"name":"李四"}] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
顺利读取出结果,这里HikariDataSource为数据库连接池,springboot2.0默认连接池,看了一下它的介绍,感觉确实不错,有时间会研究一下为啥它那么快。
接下来换一种方式实现上面的功能:
2.2、xml配置文件实现
首先注释掉application.properties中相关配置:
之后注视掉Application的MapperScan注解:
1 2 3 4 5
| @SpringBootApplication
public class Application { ... }
|
接下来就是重点了:
2.2.1、新增jdbc.properties
1 2 3 4
| jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=123456
|
2.2.2、mybatis-config.xml
1 2 3 4 5 6 7 8 9 10 11 12
| <?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> <settings> <setting name="cacheEnabled" value="true"/> </settings> <typeAliases> <typeAlias alias="People" type="com.demo.mybatis.entity.PeopleEntity"/> </typeAliases> </configuration>
|
2.2.3、spring-mybatis.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
| <?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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="jdbcUrl" 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="configLocation" value="classpath:mybatis-config.xml"/> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.demo.mybatis.mapper"/> </bean> </beans>
|
这里也使用HikariDataSource数据源。
2.2.4、AppApplicationTests
1 2 3 4 5 6 7 8 9 10 11
| @RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration("classpath:spring-mybatis.xml") public class AppApplicationTests { @Autowired private PeopleMapper peopleMapper; @Test public void test() { System.out.println(JSONObject.toJSONString(peopleMapper.query())); } }
|
比以前增加了@ContextConfiguration(“classpath:spring-mybatis.xml”),扫描配置文件生成bean。
2.2.5、结果
1 2 3 4 5 6
| com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. [{"id":1,"name":"李四"}] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
发现结果和用注解的一样。但是发现用springboot默认确实省去了使用者的很多工作量,但是为了便于学习,我这分析的时候采用配置文件的方式,这中理解起来可能会更好一点。
之后要分析配置文件的读取,即有两个大方面的内容:
- MyBatis配置最终解析成什么样了?
- MyBatis是怎么样和Spring结合的,为什么可以直接注入进来Mapper?