文章目录
[简介]
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
[在SpringBoot中集成]
步骤1、引入Mybatis依赖包
我们知道,SpringBoot项目中所有的操作都是一个个starter,所以我们再集成Mybatis时,需要先导入相关的依赖包。在maven仓库中搜索Mytabis,找到的springboot的相对应的Mybatis的starter,选择相适应的版本,添加pom.xml文件中的dependencies里面,如下所示:
<!--mybatis-spring-boot-starter -->
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
</dependencies>
步骤2、引入Mysql连接的驱动包
从Mybatis简介我们知道,Mybatis只是封装了对数据库的一些操作的一套orm框架,它并不能直接连接数据库,所以本质上我们需要先建立和数据库的连接,再基于数据库的连接做一些增删改查之类的操作。所以我们在使用Mybatis对数据库进行操作前,需要引入数据库连接的驱动包.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
步骤3、配置Mybatis的相关选项
上面我们知道使用mybatis之前需要先连接数据库,所以我们需要配置数据源的信息,以及mybatis的一些相关信息
3.1、配置数据源信息
在application.properties文件中添加如下内容
spring.datasource.username=root #数据库用户名
spring.datasource.password=123456 #数据库密码
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xdb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC #jdbc url
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #数据库连接驱动类
3.2、配置Mytabis的相关信息
在resource目录下建立mapping文件夹存放mapping文件,在application.properties文件中添加如下内容,指定mapping文件的路径
mybatis.mapper-locations=classpath:mapping/*.xml
Tips:classpath:指的是resource目录的路径,mapping前不需要带"/"。
3.3、Mybatis自动化配置源码解读
我们知道,mybatis不是springboot的官方出品,所以我们在springboot的官方文档中也不可能找到和mybatis的相关配置信息,那么我们怎么知道需要配置哪些配置项呢?其实不知道没关系,我们至少有两种方式可以解决我们的问题。
- 方式1:在网上搜索mybatis,Github的地址是:https://github.com/mybatis/spring-boot-starter,文档中有比较详细的操作说明。
- 方式2:查看源码
下面我将重点介绍这种方式:
正所谓源码在手,天下我有。我们在学一个新的东西的时候最重要的是要知其然更要知其所以然。所以解读源码是最好的学习方式,能够帮助我们起到举一反三的作用。我们知道,springboot最大的特点之一就是自动化装载配置,所以任何一个starter组件都需要实现一个AutoConfiguration的配置类注册到spingboot中完成自动化配置装载。
-
对于spingboot集成的官方组件,我们可以通过这种方式来搜索。通过对spingboot的源码解读(此文中不具体介绍),我们知道对于官方集成的所有组件的配置信息都在spring-boot-autoconfigure-2.4.5.jar下的META-INF目录下的spring.factories文件中,所以对于redis,mongodb,ElasticSearch等等官方组件的集成只需要在该文件中搜索其相关的配置类即可找到相关的配置信息以及使用操作。
-
对于非spingboot的官方组件,如果它需要被spingboot装载,同样他也需要实现类似的AutoConfiguration的配置类,所以我们只需要在依赖包中查找xxxx-spring-boot-autoconfigure-2.1.4.jar的jar包。根据这种思路,我们很容易就可以在依赖库中找到mybatis-spring-boot-autoconfigure-2.1.4.jar这个jar包。打开这个jar包,里面同样有一个 META-INF目录,在这个目录下同样有一个spring.factories文件。
mybatis-spring-boot-autoconfigure-2.1.4.jar!\META-INF\spring.factories文件内容如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
从以上文件内容我们找到了mybatis的配置类为:org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration,截取部分重点代码如下:
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
private final MybatisProperties properties;
private final Interceptor[] interceptors;
private final TypeHandler[] typeHandlers;
……
- @Configuration 注解,指定该类为一个config配置类
- @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})在有SqlSessionFactory,SqlSessionFactoryBean时配置才生效
- @ConditionalOnSingleCandidate(DataSource.class)在有DataSource类时条件成立时配置才生效
- @AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class}) 做一些在自动化配置完毕后的操作
- @EnableConfigurationProperties({MybatisProperties.class}) 启用配置属性,并指定配置属性的类为 MybatisProperties。这是我们需要关注的重点,在springboot中,基本上所有的starter组件的配置类信息都是通过这种方式来指定配置属性的。所以在源码中都能看到XXXProperties类。点击进去,查看源码,截取出MybatisProperties类的部分源码如下:
@ConfigurationProperties(
prefix = "mybatis"
)
public class MybatisProperties {
public static final String MYBATIS_PREFIX = "mybatis";
private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
private String configLocation;
private String[] mapperLocations;
private String typeAliasesPackage;
private Class<?> typeAliasesSuperType;
private String typeHandlersPackage;
private boolean checkConfigLocation = false;
private ExecutorType executorType;
private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;
private Properties configurationProperties;
@NestedConfigurationProperty
private Configuration configuration;
public MybatisProperties() {
}
……
- @ConfigurationProperties(prefix = “mybatis”) 指定配置属性的前缀为mybatis,所以在配置文件中我们可以配置的属性都是mybatis.XXX开头。配置项就是MybatisProperties的私有成员属性,所以看到这里,我们就可以很容的知道我们所能够配置的配置选项是什么,而不需要去死记硬背这些复杂繁琐的东西。
Tips:在类中使用驼峰命名规则,对应的在application.properties是使用的-分割开的命名规则,如typeAliasesPackage配置属性对应的就是mybatis.type-aliases-package
步骤4、编写代码
在com.zealink.hqchart下新建mapper包,model包,在resources目录下新建mapping文件夹
4.1、在model包下新建DayKline的model类,与数据库表的字段进行映射:
package com.zealink.hqchart.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DayKline implements Serializable {
private String orderBookId; //股票代码
private Integer tradeDate; //交易日期
private Double openPrice; //开盘价
private Double highPrice; //最高价
private Double lowPrice; //最低价
private Double closePrice; //收盘价
private Double yClosePrice; //昨日收盘价
private Double volume; //成交量
private Double amount; //成交额
@Override
public String toString() {
return "DayKline{" +
"orderBookId='" + orderBookId + '\'' +
", tradeDate=" + tradeDate +
", openPrice=" + openPrice +
", highPrice=" + highPrice +
", lowPrice=" + lowPrice +
", closePrice=" + closePrice +
", yClosePrice=" + yClosePrice +
", voluem=" + volume +
", amount=" + amount +
'}';
}
}
4.2、在mapper包(有的人也习惯命名为dao层)下新建DayKlineMapper接口封装与数据库表相关的增删改查操作
package com.zealink.hqchart.mapper;
import com.zealink.hqchart.model.DayKline;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Mapper
@Repository
public interface DayKlineMapper {
List<DayKline> history(@RequestParam("orderBookId") String orderBookId, @Param("startDate") int startDate, @Param("endDate") int endDate);
}
- @Mapper,mybatis原生注解,标记该类是一个Mapper类,必须使用@Mapper装饰类告诉springboot该类为一个mapper,否则不会被识别
- @Repository注解,它用于将数据访问层(DAO层)的类标识为Spring Bean,且只能标注于Dao类上。因为它不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。 Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
4.3 编写mapping xml文件
DayKlineMapping.xml 文件内容如下:
<?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.zealink.hqchart.mapper.DayKlineMapper">
<resultMap id="DayKline" type="com.zealink.hqchart.model.DayKline">
<result column="SECCODE" property="orderBookId"/><!--股票代码-->
<result column="TDATE" property="tradeDate"/><!--交易日期-->
<result column="F002N" property="openPrice"/><!--开盘价-->
<result column="F003N" property="highPrice"/><!--最高价-->
<result column="F004N" property="lowPrice"/><!--最低价-->
<result column="F005N" property="closePrice"/><!--收盘价-->
<result column="F001N" property="yClosePrice"/><!--昨日收盘价-->
<result column="F006N" property="volume"/><!--成交量-->
<result column="F007N" property="amount"/><!--成交额-->
</resultMap>
<sql id="Base_Column_List">
t.SECCODE,
t.TDATE,
t.F002N,
t.F003N,
t.F004N,
t.F005N,
t.F001N,
t.F006N,
t.F007N
</sql>
<select id="history" parameterType="hashMap" resultMap="DayKline">
SELECT <include refid="Base_Column_List"/>
FROM XTRD0001 AS t
<where>
<if test="orderBookId != null">
t.SECCODE = #{orderBookId}
</if>
<if test="startDate != null">
AND t.TDATE >= #{startDate}
</if>
<if test="endDate != null and endDate != 0">
AND t.TDATE <= #{endDate}
</if>
</where>
</select>
</mapper>
- 这里指定的是该xml文件与com.zealink.hqchart.mapper.DayKlineMapper接口类绑定
- 指定的是返回结果与model(pojo/entity)类的对应关系
- 数据库表字段名与类属性的对应关系。这里面,column只的是数据库表中字段名称,property指的是model类中的属性名称。
- t.SECCODE,t.TDATE,…… 这里可以配置基本的字段,可以简化后续操作,免得每次都需要去重复写一遍
- 查询操作,id指的是com.zealink.hqchart.mapper.DayKlineMapper接口中的需要实现的方法,如history方法。parameterType指定的是参数类型,resultMap指定的是结果类型, 中间是实现查询的sql语句
Tips:Mybatis配置XML语法的具体参考文档https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
4.3 编写测试代码类
package com.zealink.hqchart;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zealink.hqchart.mapper.DayKlineMapper;
import com.zealink.hqchart.model.DayKline;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class MybatisTests {
@Autowired
DayKlineMapper dayKlineMapper;
@Test
void testConnection() throws JsonProcessingException {
List<DayKline> klines = dayKlineMapper.history("600869.sh",20210101,20210418);
ObjectMapper objectWriter = new ObjectMapper();
String data = objectWriter.writeValueAsString(klines);
System.out.println(data);
}
}
输出正确结果值,由此,我们就成功在spring-boot中集成mybatis组件了。
- @Autowired 自动装载注解,修饰成员DayKlineMapper dayKlineMapper后,sping-boot会自动将该对象作为一个Bean加载到IOC容器中。
后续我会继续更新SpringBoot系列、大数据系列、以及Python系列的相关学习笔记。期待和跟大家一起学习进步。感兴趣的同学可以关注我的公众号,期待你的光临。