通用mapper基础

介绍

技术 特性 适用场景 说明
通用mapper - 代码生成
- 扩展通用方法
- 二级缓存
与MyBatis结合使用 - 官网
- Github
- Doc
- MyBatis 通用 Mapper
- Mapper 接口大全

配置

配置Maven

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
<dependencies>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--配置Mybatis-Generator插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
</configuration>
<dependencies>
<!--MyBatis Generator及工具-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

配置实体生成

generatorConfig.xml(Postgresql版)

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<context id="webapi" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<!--处理sql中的`符号-->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>

<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
<property name="caseSensitive" value="true"/>
</plugin>

<!--数据库链接URL,用户名、密码 -->
<jdbcConnection driverClass="org.postgresql.Driver"
connectionURL="jdbc:postgresql://127.0.0.1:5432/postgres?characterEncoding=utf8"
userId="postgres"
password="postgres">
</jdbcConnection>

<!-- 生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径,如./src/main/java,
也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下 -->
<!-- 生成模型的包名和位置-->
<javaModelGenerator targetPackage="com.wanglibing.postgresql.pojo" targetProject="src/main/java" />
<javaClientGenerator targetPackage="com.wanglibing.postgresql.mapper" targetProject="src/main/java"
type="ANNOTATEDMAPPER"/>

<!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
<table tableName="demo1">
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>

generatorConfig.xml(MySQL版)

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<context id="webapi" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<!--处理sql中的`符号-->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>

<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
<property name="caseSensitive" value="true"/>
</plugin>

<!--数据库链接URL,用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/webapi?characterEncoding=utf8"
userId="root"
password="123456">
</jdbcConnection>

<!-- 生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径,如./src/main/java,
也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下 -->
<!-- 生成模型的包名和位置-->
<javaModelGenerator targetPackage="com.wanglibing.webapi.pojo" targetProject="src/main/java" />
<javaClientGenerator targetPackage="com.wanglibing.webapi.mapper" targetProject="src/main/java"
type="ANNOTATEDMAPPER"/>

<!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
<table tableName="User">
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>

使用

Select

方法 说明
List select(T record); 根据实体中的属性值进行查询,查询条件使用等号
T selectByPrimaryKey(Object key); 根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
List selectAll(); 查询全部结果,select(null)方法能达到同样的效果
T selectOne(T record); 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
int selectCount(T record); 根据实体中的属性查询总数,查询条件使用等号

Insert

方法 说明
int insert(T record); 保存一个实体,null的属性也会保存,不会使用数据库默认值
int insertSelective(T record); 保存一个实体,null的属性不会保存,会使用数据库默认值

Update

方法 说明
int updateByPrimaryKey(T record); 根据主键更新实体全部字段,null值会被更新
int updateByPrimaryKeySelective(T record); 根据主键更新属性不为null的值

Delete

方法 说明
int delete(T record); 根据实体属性作为条件进行删除,查询条件使用等号
int deleteByPrimaryKey(Object key); 根据主键字段进行删除,方法参数必须包含完整的主键属性

Example

方法 说明
List selectByExample(Object example); 根据Example条件进行查询
这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
int selectCountByExample(Object example); 根据Example条件进行查询总数
int updateByExample(T record, Object example); 根据Example条件更新实体record包含的全部属性,null值会被更新
int updateByExampleSelective(T record, Object example); 根据Example条件更新实体record包含的不是null的属性值
int deleteByExample(Object example); 根据Example条件删除数据

Condition

Condition方法和Example方法作用完全一样,只是为了避免Example带来的歧义,提供的的Condition方法。

方法 说明
List selectByCondition(Object condition); 根据Condition条件进行查询
int selectCountByCondition(Object condition); 根据Condition条件进行查询总数
int updateByCondition(T record,Object condition); 根据Condition条件更新实体record包含的全部属性,null值会被更新
int updateByConditionSelective(T record, Object condition); 根据Condition条件更新实体record包含的不是null的属性值
int deleteByCondition(Object condition); 根据Condition条件删除数据

RowBounds

默认为内存分页,可以配合PageHelper实现物理分页。

方法 说明
List selectByRowBounds(T record, RowBounds rowBounds); 根据实体属性和RowBounds进行分页查询
SelectByExampleRowBoundsMapper 根据example条件和RowBounds进行分页查询
List selectByConditionAndRowBounds(Object condition, RowBounds rowBounds); 根据example条件和RowBounds进行分页查询,该方法和selectByExampleAndRowBounds完全一样,只是名字改成了Condition

特殊

这些接口针对部分数据库设计,不是所有数据库都支持。

方法 说明
int insertList(List recordList); 批量插入,支持批量插入的数据库可以使用,例如MySQL,H2等,另外该接口限制实体包含id属性并且必须为自增列
int insertList(List recordList); 批量插入,支持批量插入的数据库可以使用,另外该接口限制实体包含id属性并且必须为自增列
int insertUseGeneratedKeys(T record); 插入数据,限制为实体包含id属性并且必须为自增列,实体配置的主键策略无效
List selectByIds(String ids) 根据主键字符串进行查询,类中只有存在一个带有@Id注解的字段
int deleteByIds(String ids) 根据主键字符串进行删除,类中只有存在一个带有@Id注解的字段

Example方法示例

1
2
3
4
5
6
7
8
// 创建Example
Example example = new Example(Demo1.class);
// 设置排序字段
example.setOrderByClause("字段名 ASC/DESC");
// 创建Criteria
Example.Criteria criteria = example.createCriteria();
// 添加条件
criteria.andEqualTo("name","wlb");

配置Mapper和PageHelper整合

mybatis-config.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
<plugins>
<!-- 分页插件 分页插件配置在通用Mapper上面,否则会报错 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
<!--5.0以后自动识别数据库-->
<!--<property name="dialect" value="mysql"/>-->
<!-- reasonable:value=true时,pageNum小于1会查询第一页,如果pageNum大于pageSize会查询最后一页 -->
<property name="reasonable" value="true"/>
<!--
默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页。
如果你在 Spring 中配置了动态数据源,并且连接不同类型的数据库,这时你可以配置 autoRuntimeDialect 为 true
-->
<property name="autoRuntimeDialect" value="true"/>
<!-- autoRuntimeDialect:默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 -->
<property name="autoRuntimeDialect" value="true"/>
</plugin>
<!-- 通用Mapper -->
<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
<!--主键自增回写方法,默认值MYSQL,详细说明请看文档 -->
<property name="IDENTITY" value="MYSQL" />
<!--通用Mapper接口,多个通用接口用逗号隔开 -->
<property name="mappers" value="com.github.abel533.mapper.Mapper" />
</plugin>
</plugins>

自定义Mapper接口

mybatis-generator 添加自定义注释自动生成swagger注解

配置pom.xml

1
2
3
4
5
6
7
<!-- generator-core 自动添加swagger实体类注解 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<!-- generator-core 自动添加swagger实体类注解 -->

配置generatorConfig.xml

1
2
3
4
5
<!-- 自定义插件,自动为entity生成swagger2文档-->
<plugin type="com.springboot.MybatisGenerator">
<property name="apiModelAnnotationPackage" value="io.swagger.annotations.ApiModel" />
<property name="apiModelPropertyAnnotationPackage" value="io.swagger.annotations.ApiModelProperty" />
</plugin>

配置MybatisGenerator.java

添加自定义实体类MybatisGenerator.java,路径要和配置文件路径一致。

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
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.util.List;
import java.util.Objects;

/**
* @author: iamwlb
* @date: 2019-08-28 11:37
*/
public class MybatisGenerator extends PluginAdapter {


public static void main(String[] args) {
generate();
}

public static void generate() {
String config = Objects.requireNonNull(MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml")).getFile();
String[] arg = { "-configfile", config, "-overwrite" };
ShellRunner.main(arg);
}

@Override
public boolean validate(List<String> list) {
return true;
}


/**
* 实体类添加swagger注解
* @param field
* @param topLevelClass
* @param introspectedColumn
* @param introspectedTable
* @param modelClassType
* @return
*/
@Override
public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable, Plugin.ModelClassType modelClassType) {
String classAnnotation = "@ApiModel(value=\"" + topLevelClass.getType().getShortName() + "\")";
if (!topLevelClass.getAnnotations().contains(classAnnotation)) {
topLevelClass.addAnnotation(classAnnotation);
}
String apiModelAnnotationPackage = this.properties.getProperty("apiModelAnnotationPackage");
String apiModelPropertyAnnotationPackage = this.properties.getProperty("apiModelPropertyAnnotationPackage");
if (null == apiModelAnnotationPackage) {
apiModelAnnotationPackage = "io.swagger.annotations.ApiModel";
}
if (null == apiModelPropertyAnnotationPackage) {
apiModelPropertyAnnotationPackage = "io.swagger.annotations.ApiModelProperty";
}
topLevelClass.addImportedType(apiModelAnnotationPackage);
topLevelClass.addImportedType(apiModelPropertyAnnotationPackage);
field.addAnnotation("@ApiModelProperty(value=\"" + introspectedColumn.getRemarks() +
"\",name=\""+introspectedColumn.getJavaProperty()+
"\",dataType=\""+introspectedColumn.getFullyQualifiedJavaType().getShortName()+
"\")");
return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
}

/**
* 生成dao
*/
/*@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
FullyQualifiedJavaType fqjt = new FullyQualifiedJavaType("BaseDao<" + introspectedTable.getBaseRecordType() + ","+introspectedTable.getBaseRecordType()+"Example>");
FullyQualifiedJavaType imp = new FullyQualifiedJavaType("com.springboot.dao.base.BaseDao");
interfaze.addSuperInterface(fqjt);// 添加 extends BaseDao<User>
interfaze.addImportedType(imp);// 添加import common.BaseDao;
interfaze.getMethods().clear();
return true;
}*/
}

常见错误

通用mapper无法注入问题

问题描述

1
2
3
4
5
6
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.wanglibing.webapi.mapper.UserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1506)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)
... 42 more

解决办法

在Application.java上加上注解@MapperScan(mapper所在的包路径)。

1
@MapperScan("com.wanglibing.webapi.mapper")

could not autowire

问题描述

Could not autowire.No beans of "Demo1Mapper" type found. 虽然不影响使用,但是看着不爽。

解决办法

在Mapper加一个注解。如所示:

1
2
3
@Component(value = "demo1Mapper")
public interface Demo1Mapper extends Mapper<Demo1> {
}

参考

坚持原创技术分享,您的支持将鼓励我继续创作!
0%