持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
一、整合mybatis
1-1、使用自动生成器生成mybatis代码
在上篇文章中,创建springboot项目的时候,已经引入了相关依赖:jdbc/drui/web/mysql/mybatis这四个,现在首先通过generator生成相关mybatis代码。
1-1-1、在pom中引入generator插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Mybatis-Generator插件,自动生成代码 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<configurationFile>${project.basedir}/src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<!--必須要引入数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--必须制定版本-->
<version>8.0.22</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
1-1-2、创建generatorConfig.xml
这个文件如果不知道怎么写可以去官网拷贝一下,连接为:mybatis.org/generator/c…
我之前文章中也有介绍mybatis-generator的使用方式,里面也有这个配置文件的详解,感兴趣同学可以去看下,这里就直接使用之前的文件了,内如如下:
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--如果需要使用 command的方式生成需要配置数据库驱动的jar包路径
<classPathEntry location="指定数据驱动的磁盘路径"/>-->
<!--context 生成上下文 配置生成规则
id 随意写
targetRuntime 生成策略
MyBatis3DynamicSql 默认的,会生成 动态生成sql的方式(没有xml)
MyBatis3 生成通用的查询,可以指定动态where条件
MyBatis3Simple 只生成简单的CRUD
-->
<context id="simple" targetRuntime="MyBatis3Simple">
<commentGenerator>
<!--设置是否生成注释 true 不生成 注意: 如果不生成注释,下次生成代码就不会进行合并-->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据源 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/springboot_mybatis"
userId="root"
password="root"/>
<!--pojo
javaModelGenerator java实体生成规则(POJO)
targetPackage 生成到哪个包下
targetProject 生成到当前文件的哪个相对路径下
-->
<javaModelGenerator targetPackage="com.jony.pojo" targetProject="src/main/java"/>
<!--mapper xml映射文件
sqlMapGenerator mapper xml映射文件生成规则
targetPackage 生成到哪个包下
targetProject 生成到当前文件的哪个相对路径下
-->
<sqlMapGenerator targetPackage="com.jony.mapper" targetProject="src/main/resources"></sqlMapGenerator>
<!--mapper接口
javaClientGenerator mapper mapper接口生成规则
type 指定生成的方式
1.使用注解的方式生成
2.使用接口绑定的方式生成(要配置sqlMapGenerator)
targetPackage 生成到哪个包下
targetProject 生成到当前文件的哪个相对路径下-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.jony.mapper" targetProject="src/main/java"/>
<!--配置哪些表需要进行代码生成
tableName 表名
domainObjectName pojo类名
mapperName 对应mapper接口的类名 和 mapper xml文件名
-->
<table tableName="emp" domainObjectName="Emp" mapperName="EmpMapper" />
<table tableName="dept" domainObjectName="Dept" mapperName="DeptMapper" />
</context>
</generatorConfiguration>
1-1-3、启动generator
选择maven插件,然后选择到当前项目,找到mybatis-generator插件,点击标红的双击
1-1-3-1、运行错误
运行的时候,可能会报如下错误
我们只需要在generator.xml中的数据库地址加上serverTimezone=UTC即可,最终数据源配置如下:
再此运行就可以成功了,如下:
1-2、配置mybatis
1-2-1、在application.yml中配置Mapper.xml路径
1-2-2、配置扫描Mapper接口
将Mapper扫描注解配置到启动类上,并输入Mapper接口的包路径
1-2-3、测试一下是否成功
1-2-3-1、创建一个控制器
创建一个查询所有的方法,为了省事就不创建service层了。
1-2-3-2、启动项目浏览器访问
可以正常访问成功,如下
1-3、mybatis的自动配置原理
要了解mybatis给我们提供了哪些配置信息,就需要去看一下源码了,还是按照之前的办法查找自动配置类,如下:
进入这个类如图
1-3-1、mybatis自动配置类核心注解
@EnableConfigurationProperties(MybatisProperties.class)
这个注解主要配置了mybatis的相关配置信息,进入这个类如下:
1-3-1-1、configLocation设置mybatis配置文件
通过这个配置,就可以指定mybatis的配置文件,这样mybatis加载配置的时候就回去指向的配置文件获取相关配置
1-3-1-1-1、mybatis-config.xml
在mybatis-config.xml配置文件中设置了,驼峰命名法,以及在Mapper.xml中的package别名,这样在mapper.xml中返回pojo的type就不用写类的完整限定名了。
如下在未设置pojo别名的情况下启动项目是报错的
启用别名之后就正常了,这样在Mapper.xml中,就不用繁琐的写pojo的完整想顶面了
实际上如果没有mybatis配置文件,也可以在application.yml中进行配置如下:
1-3-2、mybatis中的setting设置
mytabis中的setting设置同样可以在mybatis-config.xml中进行配置,也可以在application.yml中进行配置,看源码如下
进入这个方法,主要通过如下配置进行获取相关配置的
Configuration configuration = this.properties.getConfiguration();
其中this.properties.getConfiguration();实际在配置文件中就是configuration
而Configuration类中实际就是mybatis的所有信息
如下这些都是setting的配置
1-3-2-1、设置驼峰命名
一般情况下我们会设置全局的resultMap,将数据库的蛇形命名对应到pojo的驼峰命名,但是在没有做映射的情况下,还可以通过mybatis.configuration.map-underscore-to-camel-case: true来进行设置,如下:
1-3-2-1-1、测试一下驼峰命名映射关系
1-3-2-1-1-1、取消驼峰命名映射关系以及Mapper.xml中的映射关系
首先将mybatis全局配置文件以及application.yml配置文件中的驼峰命名注释掉,同时将Mapper.xml中的映射关系也注释掉如下:
不加载配置文件,并且驼峰命名已注释
再将数据库字段和pojo的映射关系注释
1-3-2-1-1-2、访问测试
启动项目访问接口,可以看到查询出来的deptName的值为Null,数据中的dept_name并没有映射到deptName
1-3-2-1-1-3、启用application中的驼峰命名映射关系
再次将application.yml中的驼峰命名启用
再次访问接口,就可以成功将dept_name映射到deptName了,如下:
1-4、核心方法
上面解析的配置信息,都是在这个方法中进行加载处理的
@Bean
@ConditionalOnMissing
Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
/ 设置Mybaits的全局配置文件
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
applyConfiguration(factory);
// 相当于mybatis全局配置文件中 -之前mybatis文章中有介绍这个属性
/*<properties>
<property name="" value=""/>
</properties>
*/
if (this.properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
// 就是配置插件-拦截器 只需要配置一个实现了Interceptor的接口为Bean
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
// 设置数据库厂商id-- 之前mybatis文章中有介绍这个属性
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
// 设置别名:去application.yml中获取is.typeAliasesPackage
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
// 可以通过父类过滤哪些类需要使用别名
比如:pojo.user extends basePojo
pojo.user2
去application.yml中设置mybatis.typeAliasesSuperType: com.tulingxueyuan.pojo.basePojo
这样就只有user设置了别名,user2未进行设置
if (this.properties.getTypeAliasesSuperType() != null) {
factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
}
//设置类型处理器
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
//设置类型处理器
if (!ObjectUtils.isEmpty(this.typeHandlers)) {
factory.setTypeHandlers(this.typeHandlers);
}
// 设置mapper.xml映射文件:mapper-locations: classpath:com/tulingxueyuan/mapper/*Mapper.xml
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
Set<String> factoryPropertyNames = Stream
.of(new BeanWrapperImpl(SqlSessionFactoryBean.class).getPropertyDescriptors()).map(PropertyDescriptor::getName)
.collect(Collectors.toSet());
Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
// Need to mybatis-spring 2.0.2+
factory.setScriptingLanguageDrivers(this.languageDrivers);
if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
defaultLanguageDriver = this.languageDrivers[0].getClass();
}
}
if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
// Need to mybatis-spring 2.0.2+
factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
}
return factory.getObject();
}
private void applyConfiguration(SqlSessionFactoryBean factory) {
Configuration configuration = this.properties.getConfiguration();
if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
configuration = new Configuration();
}
if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
customizer.customize(configuration);
}
}
factory.setConfiguration(configuration);
}