Mybatis之QBC风格

QBC 风格:Query By Criteria 一种查询方式,比较面向对象,看不到sql语句。

这里记录一下关于MyBatis中Example的and和or的使用,主要是如下两种场景:

  • where (条件1 and 条件2) or (条件3 and 条件4)
  • where (条件1 and 条件2) and (条件3 or 条件4)

where (条件1 and 条件2) or (条件3 and 条件4)

1
2
3
4
5
6
7
8
//条件1 and 条件2
example.createCriteria()
.andEqualTo("isDeleted",IsDeleted.NOT_DELETED)
.andEqualTo("name", projectCatalogEntity.getName());
//or (条件3 and 条件4)
example.or(example.createCriteria()
.andEqualTo("isDeleted",IsDeleted.NOT_DELETED)
.andEqualTo("code", projectCatalogEntity.getCode()));

WHERE ( is_deleted = ? and name = ? ) or ( is_deleted = ? and code = ? )

where (条件1 and 条件2) and (条件3 or 条件4)

1
2
3
4
5
6
7
8
//条件1 and 条件2
example.createCriteria()
.andEqualTo("isDeleted",IsDeleted.NOT_DELETED))
.andEqualTo("parentId", projectCatalogEntity.getParentId());
//and (条件3 or 条件4)
example.and(example.createCriteria()
.andEqualTo("name", projectCatalogEntity.getName())
.orEqualTo("code", projectCatalogEntity.getCode()));

WHERE ( is_deleted = ? and parent_id = ? ) and ( name = ? or code = ? )

显示定义条件构造器

上述QBC查询代码中使用了链式编程方式,省去了Example.Criteria对象的创建。

多条件查询时,可以直接使用同一个条件构造器(不知道这个Example.Criteria criteria叫什么,就暂且叫他构造器),往里面直接添加条件就行.

多重条件查询时,如上面的两个括号中的条件都要分别满足时,可以分别创建条件构造器,然后分别往里添加条件

1
2
Example.Criteria criteria = example.createCriteria();
Example.Criteria criteria2 = example.createCriteria();

两个括号之间(也就是两个条件构造器之间)使用example的and或or来连接

1
2
example.and(criteria2);
example.or(criteria2);

Mybatis配置驼峰命名规则自动转换

简述

  mybatis驼峰式命名规则自动转换:

  • 使用前提:数据库表设计按照规范“字段名中各单词使用下划线”_”划分”;
  • 使用好处:省去mapper.xml文件中繁琐编写表字段列表与表实体类属性的映射关系,即resultMap。

示例:

1
2
3
4
5
6
<resultMap id ="UserInfoMap" type="com.example.mybaitsxml.dao.entity.User">
<result column="name_" property="name"/>
<result column="sex" property="sex"/>
<result column="age" property="age"/>
<result column="class_no" property="classNo"/>
</resultMap>

SpringBoot整合mybatis,开启mybatis驼峰式命名规则自动转换,通常根据配置文件不同分为两种方式。

1、方式一

直接application.yml文件中配置开启

1
2
3
4
5
6
#mybatis配置
mybatis:
typeAliasesPackage: com.example.mybaitsxml.dao.entity
mapperLocations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true

2、方式二

mybatis-config.xml文件中配置开启,application.yml文件指定配置文件。

  • application.yml文件:

1
2
3
4
5
#mybatis配置
mybatis:
typeAliasesPackage: com.example.mybaitsxml.dao.entity
mapperLocations: classpath:mapper/*.xml
configLocation: classpath:/mybatis-config.xml
  • mybatis-config.xml文件:

1
2
3
4
5
6
7
8
9
10
11
<?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="mapUnderscoreToCamelCase" value="true" />
</settings>
</configuration>

注:关于xml文件,如果删除或者注释掉所有内容,会报错:”Valid XML document must hava a root tag”,若忽略这个报错直接运行,程序报错:

“Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 24; 文件提前结束。”

小结

  开启mybatis驼峰式命名规则转换可以省去xml文件中resultMap编写的麻烦,只需要为resultType指定数据库表对应的实体类即可,但是考虑程序的安全性以及映射灵活性,通常开发中还是将resultMap结合使用。


SpringBoot配置文件优先级

一、SpringBoot 配置文件加载优先级

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order

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
1. 开发者工具 Devtools 全局配置参数;  

2. 单元测试上的 [@TestPropertySource](mailto:@TestPropertySource)` 注解指定的参数;

3. 单元测试上的 [@SpringBootTest](mailto:@SpringBootTest)` 注解指定的参数;

4. 命令行指定的参数,如 java -jar springboot.jar --name="xxx";

5. 命令行中的 SPRING_APPLICATION_JSON 指定参数, 如 java -Dspring.application.json='{"name":"xxx"}' -jar springboot.jar

6. ServletConfig初始化参数;

7. ServletContext初始化参数;

8. JNDI参数(如 java:comp/env/spring.application.json);

9. Java系统参数(来源:System.getProperties());

10. 操作系统环境变量参数;

11. RandomValuePropertySource 随机数,仅匹配:ramdom.*;

12. JAR包外面的配置文件参数(application-{profile}.properties(YAML))

13. JAR包里面的配置文件参数(application-{profile}.properties(YAML))

14. JAR包外面的配置文件参数(application.properties(YAML))

15. JAR包里面的配置文件参数(application.properties(YAML))

16. @Configuration (mailto:@Configuration)配置文件上 @PropertySource(mailto:@PropertySource) 注解加载的参数;

17. 默认参数(通过 SpringApplication.setDefaultProperties 指定);

这里我们只对比常用的几个地方的配置优先级:

命令行参数 > JAR包外面的 application-{profile}.properties > JAR包内的 application-{profile}.properties > JAR包外的 application.properties > JAR包内的 application.properties

这样可能不太直观,而且有的项目会将 application.properties 文件放在config文件夹内,于是进一步对比了这两个位置的优先级,结果如下

SpringBoot 应用程序在启动时会遵循以下顺序进行加载配置文件

  1. 类路径下的配置文件
  2. 类路径内config子目录的配置文件
  3. 项目根目录下的配置文件
  4. 项目根目录下config子目录的配置文件
1
2
3
4
5
6
7
8
9
10
. project-sample  
├── config
│ ├── application.yml (4)
│ └── src/main/resources
| │ ├── application.yml (1)
| │ └── config
| | │ ├── application.yml (2)
├── application.yml (3)

注:src/main/resources下的配置文件在项目编译时,会放在target/classes下

启动时加载配置文件顺序:1 -> 2 -> 3 -> 4,优先级 4 > 3 > 2 > 1

注意:

  • 如果在IDEA中是多 module 项目,3 和 4 的位置是指的是项目根目录下的位置
  • 当 .properties 和 .yml 文件同时存在时,.properties会失效,.yml会起作用。

二、bootstrap.yml配置文件

SpringCloud 的项目中,我们常常会碰到另外一个配置文件 bootstrap.yml。这个配置文件主要是用于应用程序上下文的引导阶段,该配置文件的加载是在 application.yml 之前。

bootstrap.yml 和 application.yml 文件的区别可参考:What is the difference between putting a property on application.yml or bootstrap.yml in spring boot

在 SpringCloud 中有两种上下文,一种是 bootstrap, 另外一种是 application, bootstrap 是应用程序的父上下文。官方的原话是 A Spring Cloud application operates by creating a “bootstrap” context, which is a parent context for the main application

bootstrap.yml配置文件的使用场景:

  • 使用配置中心时,这时需要在bootstrap配置文件中添加连接到配置中心的信息,来加载外部配置中心的配置信息
  • 一些固定的不能被覆盖的属性
  • 一些加密/解密的信息

项目中 bootstrap.yml 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
application:
name:
profiles:
active: local
cloud:
nacos:
# 远程配置
config:
server-addr:
namespace:
group: ${spring.profiles.active}
file-extension: yml
# 服务发现
discovery:
server-addr:
namespace:
group: ${spring.profiles.active}

引入配置中心Nacos

首先我们需要明确的是在没有Nacos之前,Spring Boot加载配置文件的顺序是怎样的。

在没有 Nacos 之前,项目启动时,第一个加载的是 bootstrap.yml,其次是加载 application.yml。如果在 application.yml 中设置了 profile 属性,那么最后加载的就是对应激活的文件,如 application-dev.yml 或者 application-prod.yml。

无论如何,在 Spring 家族中 bootstrap.yml 拥有最高的优先级。

无Nacos情境下 Spring Boot 的启动过程:

1
启动-->读取bootstrap.yml配置文件(本地没有就加载默认的)-->读取项目本地配置文件application.yml-->创建Spring容器-->加载Bean

引入Nacos之后,上面的顺序会发生少许变化。

在加载bootstrap.yml完之后,Spring不再是去读取本地的application.yml配置文件,而是去读取Nacos的配置文件,之后才是本地的application.yml配置文件。

有Nacos情境下 Spring Boot 的启动过程:

1
启动-->读取bootstrap.yml配置文件(本地没有就加载默认的)-->读取Nacos的配置文件-->读取项目本地配置文件application.yml-->创建Spring容器-->加载Bean

可以通过在远程配置中心中做如下配置,设置本地配置覆盖远程配置:

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
config:
# 是否允许本地配置覆盖远程配置
allow-override: true
# 是否一切以本地配置为准,默认false
override-none: false
# 系统环境变量或系统属性才能覆盖远程配置文件的配置
# 本地配置文件中配置优先级低于远程配置,默认true
override-system-properties: true