Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part B)(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part B)

三、通用Mapper实现复杂查询-ExampleMapper

3.1 QBC查询

QBC既Query By Criteria,QBC查询是将查询条件通过Java对象进行模块化封装。

Criterion是一个内部类,是Criterion的复数形式,既准则标准的意思;与MBG生成的复杂查询条件的实体类CatExample中的Criterion内部类代码是一样的,也都提供了createCriteria方法,创建复合查询条件

MBG生成的封装查询条件的XXXExample VS 通用Mapper的Example类

b8e6e17c3e4a42c9afef65eb8439b557_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

都封装了大量的查询条件。两者使用方法的不同,MBG直接针对Entity实体类生成了XXXExample,如在生成的CatExample、TeacherExample;而通用Mapper使用条件查询时则需要在新建一个Example时传入一个要查询的实体类class

Example porscheExample = new Example(Porsche.class);
复制代码

3.1.1 使用QBC查询

使用QBC创建如下复合查询

WHERE (por_id > 1 and por_stock > 20) OR ( por_price < 1000000 and por_stock > 20)
复制代码

在PorscheService中增加getPorschesByPriceAndStock方法

List<Porsche> getPorschesByPriceAndStock(Example porscheExample);
复制代码

在PorscheServiceImpl中增加getPorschesByPriceAndStock方法的实现

@Override
public List<Porsche> getPorschesByPriceAndStock(Example porscheExample) {
    return porscheMapper.selectByExample(porscheExample);
}
复制代码

在PorscheServiceTest增加getPorscheByPriceAndStock的测试方法,查询条件的构建过程查看注释。

@Test
public void getPorscheByPriceAndStock(){
    Example porscheExample = new Example(Porsche.class);
    // WHERE (por_id > 1 and por_stock > 20) OR ( por_price < 1000000 and por_stock > 20)
    // 创建两个查询条件,WHERE关键字后面的两个括号分别对应两个查询条件
    Example.Criteria criteria1 = porscheExample.createCriteria();
    Example.Criteria criteria2 = porscheExample.createCriteria();
    // 设置两个查询条件
    criteria1.andGreaterThan("porId",1)
            .andGreaterThan("porStock",20);
    criteria2.andLessThan("porPrice",1000000d)
            .andGreaterThan("porStock",20);
    // 通过OR连接查询条件1--criteria1和查询条件2--criteria2
    // porschExample就相当于select 字段名 from 表明 WHERE criteria 1
    // 只需要调用or方法将criteria2连接上,就构成了完成的SQL语句
    // select 字段名 from 表明 WHERE (criteria1) OR (criteria2)
    porscheExample.or(criteria2);
    List<Porsche> porscheList = porscheService.getPorschesByPriceAndStock(porscheExample);
    for (Porsche porsche : porscheList) {
        System.out.println("查询到的内容为:" + porsche);
    }
}
复制代码

执行测试

image.png

3.1.2 QBC其他设置

QBC查询同时可以设置如排序、去重、设置查询的字段等,在getPorscheByPriceAndStock测试方法中增加相关代码,

porscheExample.setDistinct(true);
porscheExample.orderBy("porPrice").asc().orderBy("porName").desc();
porscheExample.selectProperties("porName","porPrice");
复制代码

再次执行测试

image.png

查看控制台删除的SQL语句,构建的复合条件在SQL执行时生效。

四、通用Mapper实现分页-RowBoundsMapper

4.1 分页相关方法

// 根据example条件和RowBounds进行分页查询
List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds);
// 根据实体属性和RowBounds进行分页查询
List<T> selectByRowBounds(T record, RowBounds rowBounds);
复制代码

4.1.1 selectByRowBounds

在PorscheService接口中增加分页查询方法getPorschesByRowBounds

List<Porsche> getPorschesByRowBounds(Porsche record, RowBounds rowBounds);
复制代码

在PorscheServiceImpl中实现分页查询方法getPorschesByRowBounds

@Override
public List<Porsche> getPorschesByRowBounds(Porsche record, RowBounds rowBounds) {
    return porscheMapper.selectByRowBounds(record,rowBounds);
}
复制代码

增加该方法的测试代码

@Test
public void getPorschesByRowBounds(){
    int pageNo = 2;
    int pageSize = 3;
    int index = (pageNo - 1) * pageSize;
    RowBounds rowBounds = new RowBounds(index, pageSize);
    List<Porsche> porscheList = porscheService.getPorschesByRowBounds(null, rowBounds);
    for (Porsche porsche : porscheList) {
        System.out.println("查询到的内容为:" + porsche);
    }
}
复制代码

执行测试

image.png

根据控制台输出的SQL语句,说明通用Mapper还是查询出所有的数据,在内存中进行的分页操作,”假分页“,不推荐使用这个分页查询,推荐使用PageHelper插件实现真正的分页

4.2 @Transient

一般情况下,实体类中的属性和数据库表中的字段都是一一对应的,但是有些属性可能在数据库中没有对应的字段,这时候就需要使用@Transient注解标明这不是表中的字段。

五、通用Mapper的逆向工程

5.1 通用Mapper的逆向工程

通用Mapper的逆向工程生成的代码与原生MyBatis生成的代码稍有区别,首先都包含Entity实体类、XxxMapper接口以及XxxMapper.xml,但是通用Mapper生成的Entity实体类中会包含如@Table注解、@Column注解、@Id注解以及@GeneratedValue等注解;生成的XxxMapper接口继承Mapper<Xxx>类;生成的XxxMapper.xml中没有SQL语句,只有一个resultMap标签。

5.2 使用通用Mapper的逆向工程

新建一个项目common-mapper-mbg,该项目的用到的依赖、Spring配置及MyBatis配置与general-mapper项目用到的一致,差异在于新建的general-mapper-mbg项目中不包含Entity实体类Mapper接口以及Service类和测试类等。

在common-mapper-mbg项目的pom.xml文件中增加通用Mapper的代码生成器依赖及maven插件,通过maven插件执行代码生成器生成代码,通过用Java代码或者命令行的方式也可运行代码生成器,这里不再赘述。

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-generator</artifactId>
    <version>1.0.0</version>
</dependency>
复制代码

resources目录下新增generatorConfig.xml

<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <properties resource="db.properties"/>
    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!--通用Mapper的MBG插件-->
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
            <property name="caseSensitive" value="true"/>
        </plugin>
        <jdbcConnection driverClass="${jdbc_driver}"
                        connectionURL="${jdbc_url}"
                        userId="${jdbc_username}"
                        password="${jdbc_password}">
        </jdbcConnection>
        <javaModelGenerator targetPackage="com.citi.entity"
                            targetProject="./src/main/java"/>
        <sqlMapGenerator targetPackage="mappers"
                         targetProject="./src/main/resources"/>
        <javaClientGenerator targetPackage="com.citi.mapper"
                             targetProject="./src/main/java"
                             type="XMLMAPPER"/>
        <!--tableName="%"表示所有表都参与逆向工程-->
        <table tableName="t_teacher" domainObjectName="Teacher">
            <generatedKey column="id" sqlStatement="Mysql"/>
        </table>
    </context>
</generatorConfiguration>
复制代码

pom.xml中增加插件

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.7</version>
            <configuration>
                <configurationFile>
                    ${basedir}/src/main/resources/generatorConfig.xml
                </configurationFile>
                <overwrite>true</overwrite>
                <verbose>true</verbose>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.16</version>
                </dependency>
                <dependency>
                    <groupId>tk.mybatis</groupId>
                    <artifactId>mapper</artifactId>
                    <version>4.0.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
复制代码

运行通用Mapper的MBG

image.png

代码生成器运行成功

5.3 测试通用Mapper生成的代码

新建代码生成器生成的TeacherMapper的测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class TeacherMapperTest {
    @Resource
    private TeacherMapper teacherMapper;
    @Test
    public void selectAll(){
        List<Teacher> teachers = teacherMapper.selectAll();
        for (Teacher teacher : teachers) {
            System.out.println("查询到的内容为:" + teacher.getTeacherName());
        }
    }
}
复制代码

执行该测试

image.png

控制台成功输出查询内容,通用Mapper的逆向工程生成的代码验证成功。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
37 10
|
3月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
48 1
|
3月前
|
XML Java 数据库连接
Mybatis 模块拆份带来的 Mapper 扫描问题
Mybatis 模块拆份带来的 Mapper 扫描问题
46 0
|
4月前
|
SQL
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
|
4月前
|
Java 数据库连接 Maven
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
|
5月前
|
SQL Java 数据库连接
Mybatis如何使用mapper代理开发
Mybatis如何使用mapper代理开发
|
5月前
|
XML 关系型数据库 数据库
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
522 0
|
5月前
|
SQL Java 数据库连接
Mybatis中一对多mapper配置
Mybatis中一对多mapper配置
|
5月前
|
Java 数据库连接 mybatis
Mybatis mapper动态代理解决方案
该文介绍了Mybatis中使用Mapper接口的方式代替XML配置执行SQL。Mapper接口规范包括:namespace与接口类路径相同,select ID与接口方法名一致,parameterType和方法参数类型匹配,resultType与返回值类型一致。实现过程中,需配置Mapper.xml,编写Mapper.java接口,并在Mybatis-config.xml中设置。测试类中,通过SqlSession的getMapper方法获取接口的动态代理对象,调用方法执行SQL。
138 0