Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

news2025/6/12 20:24:51

今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。

那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议,那么话不多说直接上教程👏👏👏!!!

目录

正向工程 与 逆向工程

1、什么是Mybatis逆向工程

MyBatis 逆向工程使用注意事项

2、逆向工程生成代码

①、首先创建maven项目

②、创建日志文件log4j.properties

③、创建generatorConfig.xml配置文件

④、创建逆向工程核心生成代码GeneratorSql.java

⑤、运行逆向工程生成代码

3、逆向工程举例

(1)、EmpMapper接口生成的方法介绍:

测试不带条件的方法:

(2)、EmpExample条件扩展类介绍:

说明:

简单举例:


正向工程 与 逆向工程

  • 正向工程:先创建Java实体类,由框架负责根据实体类生成数据表。Hibernate 是支持正向工程的。

  • 逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成Java实体类、Mapper接口、Mapper配置文件

1、什么是Mybatis逆向工程

MyBatis逆向工程是一种自动化生成代码的工具,它能够根据数据库表结构自动创建对应的Java实体类、Mapper接口以及Mapper映射文件。

在MyBatis开发中,我们通常需要手动编写实体类、Mapper接口和XML映射文件,尤其是当数据库表较多或字段复杂时,这种重复性工作不仅效率低下,还容易因人为疏忽导致错误。例如,字段类型不匹配、遗漏字段或拼写错误等问题,排查起来相当耗时。

为了解决这一问题,MyBatis逆向工程应运而生。它通过扫描数据库表结构,自动生成标准化的基础代码,极大地减少了开发者的手动编码量,尤其适用于单表CRUD操作。这不仅提升了开发效率,也降低了出错概率,让开发者能更专注于业务逻辑的实现。

MyBatis 逆向工程使用注意事项

1. 避免直接在原项目中使用逆向工程

  • 风险: 逆向工程生成的代码(如 User.javaUserMapper.javaUserMapper.xml)可能会覆盖原有文件,导致手动编写的业务逻辑丢失。

  • 解决方案:

    • 新建一个临时项目,专门用于运行逆向工程生成代码。

    • 生成后,手动复制所需文件到目标项目,避免直接覆盖。

2. 生成代码后需检查调整

  • 自定义逻辑可能被覆盖:生成的 Mapper.xml 文件会包含基本的 CRUD 方法,如果原文件已有自定义 SQL(如复杂查询、关联查询),直接覆盖会导致功能失效。

  • 建议:

    • 仅复制新增的实体类或 Mapper 接口,避免覆盖已有业务代码。

    • 使用 @Mapper 扫描 + 自定义 XML 的方式,分离自动生成代码和手动编写代码。

3.版本管理(Git)备份:在运行逆向工程前,确保代码已提交到 Git,避免意外覆盖导致不可逆的损失。

2、逆向工程生成代码

①、首先创建maven项目

项目整体目录:

导入maven依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
​
    <!--组织名称-->
    <groupId>com.nanji</groupId>
    <!--项目唯一标识-->
    <artifactId>GeneratorSql</artifactId>
    <!--版本号-->
    <version>1.0</version>
    <!--打包方式-->
    <packaging>jar</packaging>
​
    <!--项目名称(显示用)-->
    <name>GeneratorSql</name>
    <!--项目的url地址-->
    <url>https://maven.apache.org</url>
​
    <!--
        声明可在pom文件中可以使用的键值对变量(用:${}引用)
        例如:${poject.build.sourceEncoding},值:UTF-8
    -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
​
    <!--以来列表容器,用来存放依赖的jar包-->
    <dependencies>
        <!--
            dependency:依赖项
            groupId:依赖项的组ID
            artifactId:依赖项的ID
            version:依赖项的版本
        -->
​
        <!--mybatis jar包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.11</version>
        </dependency>
​
        <!--mysql驱动 jar包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
​
        <!--log4j日志 jar包-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
​
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
        <!-- 构建过程中用到的插件 -->
        <plugins>
            <!--
                plugin:具体插件,逆向工程的操作是以构建过程中插件形式出现的
                groupId:插件的组ID
                artifactId:插件的ID
            -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <!-- 插件的依赖列表容器 -->
                <dependencies>
                    <!-- 逆向工程的核心依赖 -->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.4.0</version>
                    </dependency>
                    <!-- 数据库连接池 -->
                    <dependency>
                        <groupId>com.alibaba</groupId>
                        <artifactId>druid</artifactId>
                        <version>1.2.24</version>
                    </dependency>
​
                    <!-- MySQL驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.33</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

②、创建日志文件log4j.properties

# 配置日志输出到控制台(STDOUT)
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.Encoding=UTF-8
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n
​
# 设置 java.sql 的日志级别为 debug
log4j.logger.java.sql=debug
​
# 设置 org.apache.ibatis 的日志级别为 info
log4j.logger.org.apache.ibatis=info
​
# 配置根日志记录器,日志级别为 debug,输出到 STDOUT
log4j.rootLogger=debug, STDOUT

③、创建generatorConfig.xml配置文件

文件名必须是 generatorConfig.xml

<?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>
    <!-- targetRuntime: 执行生成的逆向工程的版本
        MyBatis3Simple: 生成基本的CRUD(清新简洁版)
        MyBatis3: 生成带条件的CRUD(奢华尊享版) -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--
            TODO 配置自己的数据库连接信息:驱动类、连接地址、用户名、密码
            连接地址中的 &amp; 实际上就是 & 符号的转义字符,由于 xml 文件中直接写 & 时,xml 解析器会认为 & 后面的是实体,从而报错
         -->
        <jdbcConnection
                driverClass="com.mysql.cj.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai"
                userId="nanji"
                password="123456">
        </jdbcConnection>
        <!--
            默认false:把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,
            为true时:把JDBC DECIMAL 和 NUMERIC 类型解析为 java.math.BigDecimal
        -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--
            javaBean的生成策略
            targetProject:POJO类生成的位置
        -->
        <javaModelGenerator targetPackage="com.nanji.mybatis.pojo" targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!--
            SQL映射文件的生成策略
            targetProject:mapper映射文件生成的位置
         -->
        <sqlMapGenerator targetPackage="com.nanji.mybatis.mapper" targetProject=".\src\main\resources">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--
            Mapper接口的生成策略
            targetPackage:mapper接口生成的位置
         -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.nanji.mybatis.mapper"
                             targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="t_emp" domainObjectName="Emp">
            <!--
                property:实体类属性名
                    columnOverride:对数据库字段的设置
                    column:数据库字段名
                    javaType:实体类属性的数据类型
             -->
            <!--<property column="" javaType=""/>-->
        </table>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

注意:数据库连接地址中的 &amp; 实际上就是 & 符号的转义字符,由于 xml 文件中直接写 & 时,xml 解析器会认为 & 后面的是实体,从而报错

<jdbcConnection
    driverClass="com.mysql.cj.jdbc.Driver"
    connectionURL="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai"
    userId="nanji"
    password="123456">
</jdbcConnection>

还有就是不同的数据库中不能含有相同的表,例如数据库A有t_user表,数据库B也有t_user表,那么到时候代码不知道生成哪个

④、创建逆向工程核心生成代码GeneratorSql.java

package com.nanji;
​
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
​
import java.io.File;
import java.util.ArrayList;
import java.util.List;
​
/**
 * @version 1.0
 * @ClassName GeneratorSql
 * @Description 逆向工程生成代码的核心类
 * @Author NanJi
 * @Date 2025/6/10 : 16:01
 */
public class GeneratorSql {
    // 执行main方法以生成代码
    public static void main(String[] args) {
        try {
            GeneratorSql generatorSql = new GeneratorSql();
            generatorSql.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public void generator() throws Exception {
        List<String> warnings = new ArrayList<>();
        boolean overwrite = true;
        // 指定逆向工程配置文件
        String file = GeneratorSql.class.getResource("/generatorConfig.xml").getFile();
        System.out.println(file);
        File configFile = new File(file);
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}

⑤、运行逆向工程生成代码

运行上面的程序,如果控制台打印了如下日志,说明生成代码成功了。

或者

使用maven插件进行代码生成

如果控制台打印了如下日志,说明生成代码成功了。

然后我们的项目结构会发生变化,生成了如下文件:

3、逆向工程举例

首先我们将上面生成的文件复制到目标项目中。在使用逆向工程举例之前,先来介绍生成的文件有哪些东西:

(1)、EmpMapper接口生成的方法介绍:

方法说明
long countByExample(EmpExample example);按条件计数
int deleteByExample(EmpExample example);按条件删除
int deleteByPrimaryKey(Integer empid);按主键删除
int insert(Emp record);插入数据(返回值为ID)
int insertSelective(Emp record);插入数据,只插入值不为null的字段,内部动态sql判断
List<Emp> selectByExample(EmpExample example);按条件查询,传入null表示查询所有
Emp selectByPrimaryKey(Integer empid);按主键查询
int updateByExampleSelective(@Param("record") Emp record, @Param("example") EmpExample example);按条件更新值不为null的字段
int updateByExample(@Param("record") Emp record, @Param("example") EmpExample example);按条件更新
int updateByPrimaryKeySelective(Emp record);按主键更新值不为null的字段
int updateByPrimaryKey(Emp record);按主键更新
测试不带条件的方法:
package com.nanji.mybatis.mapper;
​
​
import com.nanji.mybatis.pojo.Emp;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
public class EmpMapperTest {
    //定义 SqlSession
    private SqlSession sqlSession = null;
    //定义 EmpMapper对象
    private EmpMapper mapper = null;
​
    @Before//在测试方法执行之前执行
    public void getSqlSession() {
        //1、加载 mybatis 全局配置文件
        InputStream is = EmpMapperTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //2、创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3、根据 sqlSessionFactory 产生session
        sqlSession = sqlSessionFactory.openSession();
        //4、创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成EmpMapper的代理实现类
        mapper = sqlSession.getMapper(EmpMapper.class);
    }
​
    @After//在测试方法执行完成之后执行
    public void destroy() throws IOException {
        sqlSession.commit();
        sqlSession.close();
    }
​
    //查询所有用户信息
    @Test
    public void selectAllUser() {
        List<Emp> Emps = mapper.selectByExample(null);//传入null表示查询所有
        for (Emp Emp : Emps) {
            System.out.println(Emp);
        }
    }
​
    //根据用户id查询用户
    @Test
    public void selectByUserId() {
        Emp Emp = mapper.selectByPrimaryKey(1);
        System.out.println(Emp);
    }
​
    //添加用户信息
    @Test
    public void inserEmp() {
        Emp Emp = new Emp();
        Emp.setEmpName("凡尔赛");
        Emp.setAge(18);
        Emp.setSex("男");
        Emp.setEmail("piaoliang@gmail.com");
        Emp.setDeptid(1);
        int i = mapper.insertSelective(Emp);
        System.out.println(i > 0 ? "添加成功" : "添加失败");
    }
​
    //更新用户信息
    @Test
    public void updateUser() {
        Emp Emp = new Emp();
        Emp.setEmpid(15);   //这里要设置id才能修改成功,否则不知道修改哪一条数据
        Emp.setEmpName("奥德赛");
        Emp.setAge(18);
        Emp.setSex("男");
        Emp.setEmail("aodesai@gmail.com");
        Emp.setDeptid(1);
        int i = mapper.updateByPrimaryKeySelective(Emp);
        System.out.println(i > 0 ? "修改成功" : "修改失败");
    }
​
    //删除用户信息
    @Test
    public void deleteUser() {
        int i = mapper.deleteByPrimaryKey(8);
        System.out.println(i > 0 ? "删除成功" : "删除失败");
    }
}

(2)、EmpExample条件扩展类介绍:

上面的测试方法是不带条件的操作,那么接下来学习一下按条件如何进行增删改查操作,我们在逆向工程中已经生成了这个类EmpExample,这个类就是一个条件扩展类,里面定义了一系列方法用来做条件,比如:排序、去重、大于、小于、等于、模糊查询、数据在某某之间等等。

我们在EmpExample类中可以看到定义了一个内部类GeneratedCriteria,这个内部类就定义了一系列条件的方法,这些条件最后都会拼接在SQL中,但是我们一般不用它,都用它的子类Criteria来进行操作,Criteria继承了内部类GeneratedCriteria。

方法说明
isValid()判断当前查询条件列表是否非空,即是否有有效的查询条件
getAllCriteria()获取所有的查询条件(Criterion 对象列表)
getCriteria()获取当前查询条件列表
addCriterion(String condition)添加一个无参数的查询条件(如 "empId is null"
addCriterion(String condition, Object value, String property)添加一个带单个值的查询条件,并校验值是否为空
addCriterion(String condition, Object value1, Object value2, String property)添加一个区间类型的查询条件(如 BETWEEN),并校验两个值是否都非空
andEmpidIsNull()添加 empId IS NULL 查询条件
andEmpidIsNotNull()添加 empId IS NOT NULL 查询条件
andEmpidEqualTo(Integer value)添加 empId = value 查询条件
andEmpidNotEqualTo(Integer value)添加 empId <> value 查询条件
andEmpidGreaterThan(Integer value)添加 empId > value 查询条件
andEmpidGreaterThanOrEqualTo(Integer value)添加 empId >= value 查询条件
andEmpidLessThan(Integer value)添加 empId < value 查询条件
andEmpidLessThanOrEqualTo(Integer value)添加 empId <= value 查询条件
andEmpidIn(List<Integer> values)添加 empId IN (values) 查询条件
andEmpidNotIn(List<Integer> values)添加 empId NOT IN (values) 查询条件
andEmpidBetween(Integer value1, Integer value2)添加 empId BETWEEN value1 AND value2 查询条件
andEmpidNotBetween(Integer value1, Integer value2)添加 empId NOT BETWEEN value1 AND value2 查询条件
andEmpNameIsNull()添加 emp_name IS NULL 查询条件
andEmpNameIsNotNull()添加 emp_name IS NOT NULL 查询条件
andEmpNameEqualTo(String value)添加 emp_name = value 查询条件
andEmpNameNotEqualTo(String value)添加 emp_name <> value 查询条件
andEmpNameGreaterThan(String value)添加 emp_name > value 查询条件
andEmpNameGreaterThanOrEqualTo(String value)添加 emp_name >= value 查询条件
andEmpNameLessThan(String value)添加 emp_name < value 查询条件
andEmpNameLessThanOrEqualTo(String value)添加 emp_name <= value 查询条件
andEmpNameLike(String value)添加 emp_name LIKE value 查询条件
andEmpNameNotLike(String value)添加 emp_name NOT LIKE value 查询条件
andEmpNameIn(List<String> values)添加 emp_name IN (values) 查询条件
andEmpNameNotIn(List<String> values)添加 emp_name NOT IN (values) 查询条件
andEmpNameBetween(String value1, String value2)添加 emp_name BETWEEN value1 AND value2 查询条件
andEmpNameNotBetween(String value1, String value2)添加 emp_name NOT BETWEEN value1 AND value2 查询条件
andAgeIsNull()添加 age IS NULL 查询条件
andAgeIsNotNull()添加 age IS NOT NULL 查询条件
andAgeEqualTo(Integer value)添加 age = value 查询条件
andAgeNotEqualTo(Integer value)添加 age <> value 查询条件
andAgeGreaterThan(Integer value)添加 age > value 查询条件
andAgeGreaterThanOrEqualTo(Integer value)添加 age >= value 查询条件
andAgeLessThan(Integer value)添加 age < value 查询条件
andAgeLessThanOrEqualTo(Integer value)添加 age <= value 查询条件
andAgeIn(List<Integer> values)添加 age IN (values) 查询条件
andAgeNotIn(List<Integer> values)添加 age NOT IN (values) 查询条件
andAgeBetween(Integer value1, Integer value2)添加 age BETWEEN value1 AND value2 查询条件
andAgeNotBetween(Integer value1, Integer value2)添加 age NOT BETWEEN value1 AND value2 查询条件
andSexIsNull()添加 sex IS NULL 查询条件
andSexIsNotNull()添加 sex IS NOT NULL 查询条件
andSexEqualTo(String value)添加 sex = value 查询条件
andSexNotEqualTo(String value)添加 sex <> value 查询条件
andSexGreaterThan(String value)添加 sex > value 查询条件
andSexGreaterThanOrEqualTo(String value)添加 sex >= value 查询条件
andSexLessThan(String value)添加 sex < value 查询条件
andSexLessThanOrEqualTo(String value)添加 sex <= value 查询条件
andSexLike(String value)添加 sex LIKE value 查询条件
andSexNotLike(String value)添加 sex NOT LIKE value 查询条件
andSexIn(List<String> values)添加 sex IN (values) 查询条件
andSexNotIn(List<String> values)添加 sex NOT IN (values) 查询条件
andSexBetween(String value1, String value2)添加 sex BETWEEN value1 AND value2 查询条件
andSexNotBetween(String value1, String value2)添加 sex NOT BETWEEN value1 AND value2 查询条件
andEmailIsNull()添加 email IS NULL 查询条件
andEmailIsNotNull()添加 email IS NOT NULL 查询条件
andEmailEqualTo(String value)添加 email = value 查询条件
andEmailNotEqualTo(String value)添加 email <> value 查询条件
andEmailGreaterThan(String value)添加 email > value 查询条件
andEmailGreaterThanOrEqualTo(String value)添加 email >= value 查询条件
andEmailLessThan(String value)添加 email < value 查询条件
andEmailLessThanOrEqualTo(String value)添加 email <= value 查询条件
andEmailLike(String value)添加 email LIKE value 查询条件
andEmailNotLike(String value)添加 email NOT LIKE value 查询条件
andEmailIn(List<String> values)添加 email IN (values) 查询条件
andEmailNotIn(List<String> values)添加 email NOT IN (values) 查询条件
andEmailBetween(String value1, String value2)添加 email BETWEEN value1 AND value2 查询条件
andEmailNotBetween(String value1, String value2)添加 email NOT BETWEEN value1 AND value2 查询条件
andDeptidIsNull()添加 deptId IS NULL 查询条件
andDeptidIsNotNull()添加 deptId IS NOT NULL 查询条件
andDeptidEqualTo(Integer value)添加 deptId = value 查询条件
andDeptidNotEqualTo(Integer value)添加 deptId <> value 查询条件
andDeptidGreaterThan(Integer value)添加 deptId > value 查询条件
andDeptidGreaterThanOrEqualTo(Integer value)添加 deptId >= value 查询条件
andDeptidLessThan(Integer value)添加 deptId < value 查询条件
andDeptidLessThanOrEqualTo(Integer value)添加 deptId <= value 查询条件
andDeptidIn(List<Integer> values)添加 deptId IN (values) 查询条件
andDeptidNotIn(List<Integer> values)添加 deptId NOT IN (values) 查询条件
andDeptidBetween(Integer value1, Integer value2)添加 deptId BETWEEN value1 AND value2 查询条件
andDeptidNotBetween(Integer value1, Integer value2)添加 deptId NOT BETWEEN value1 AND value2 查询条件
说明:
  • 所有 andXXX 方法均用于构建针对 t_emp 表中字段的查询条件。

  • 这些方法基于 MyBatis Generator 自动生成,常用于动态 SQL 查询,配合 MyBatis 框架使用。

  • Criteria 继承自 GeneratedCriteria,提供对外使用的 API。

简单举例:
package com.nanji.mybatis.mapper;
​
​
import com.nanji.mybatis.pojo.Emp;
import com.nanji.mybatis.pojo.EmpExample;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
public class EmpMapperExampleTest {
​
    //定义 SqlSession
    private SqlSession sqlSession = null;
    //定义 UserMapper对象
    private EmpMapper mapper = null;
​
    @Before//在测试方法执行之前执行
    public void getSqlSession() {
        //1、加载 mybatis 全局配置文件
        InputStream is = EmpMapperExampleTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //2、创建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3、根据 sqlSessionFactory 产生session
        sqlSession = sqlSessionFactory.openSession();
        //4、创建Mapper接口的的代理对象,getMapper方法底层会通过动态代理生成UserMapper的代理实现类
        mapper = sqlSession.getMapper(EmpMapper.class);
    }
​
    @After//在测试方法执行完成之后执行
    public void destroy() throws IOException {
        sqlSession.commit();
        sqlSession.close();
    }
​
    //模糊查询用户信息
    @Test
    public void selecEmpLike() {
        EmpExample example = new EmpExample();
        EmpExample.Criteria criteria = example.createCriteria();
        //模糊条件
        criteria.andEmpNameLike("%三%");
        /*sql语句相当于:select id, username, age, birthday, sex, address 
                        from t_user WHERE ( username like ? )*/
        List<Emp> Emps = mapper.selectByExample(example);
        for (Emp Emp : Emps) {
            System.out.println(Emp);
        }
    }
​
    //查询年龄在18-30岁之间的用户信息
    @Test
    public void selecEmpBetween() {
        EmpExample example = new EmpExample();
        EmpExample.Criteria criteria = example.createCriteria();
        //Between条件
        criteria.andAgeBetween(18, 30);
        example.or(criteria);
        example.setDistinct(true);
        /*sql语句相当于:select distinct id, username, age, birthday, sex, address 
                        from t_user WHERE ( age between ? and ? ) or( age between ? and ? )*/
        List<Emp> Emps = mapper.selectByExample(example);
        for (Emp Emp : Emps) {
            System.out.println(Emp);
        }
    }
​
    //查询用户名A或B
    @Test
    public void selecEmpOr() {
        EmpExample example = new EmpExample();
        EmpExample.Criteria criteria1 = example.createCriteria();
        criteria1.andEmpNameEqualTo("黄飞鸿");
​
        EmpExample.Criteria criteria2 = example.createCriteria();
        criteria2.andEmpNameEqualTo("马保国");
        //将criteria2条件拼接在 or 关键字字后面
        example.or(criteria2);
        /*sql语句相当于:select id, username, age, birthday, sex, address
            from t_user WHERE ( username = ? ) or( username = ? )*/
        List<Emp> Emps = mapper.selectByExample(example);
        for (Emp Emp : Emps) {
            System.out.println(Emp);
        }
    }
​
    //根据用户名删除用户
    @Test
    public void deleteUserExample() {
        EmpExample example = new EmpExample();
        EmpExample.Criteria criteria = example.createCriteria();
        criteria.andEmpNameEqualTo("凡尔赛");
        //sql语句相当于:delete from t_user WHERE ( username = ? )
        int i = mapper.deleteByExample(example);
        System.out.println(i > 0 ? "删除成功" : "删除失败");
    }
}

欧了,到这里我应该解释的差不多啦,我是南极,大胆做自己,活出精彩的人生👊👊👊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…