Mybatis:灵活掌控SQL艺术

在前面的文章中,小编分享了spring中相关的知识,但是没有分享到,如何去更高效操作数据库。

操作数据库传统的方法就是通过JDBC来进行操作。

这个传统方法使用上可谓是够麻烦的

  • 1.首先创建一个数据源对象
  • 2.设置该数据源的属性(密码、用户、位置......)
  • 3.获取数据库的连接
  • 3.构建sql语句、预编译sql语句、发送sql语句

这些操作,应用到开发中,是比较麻烦的,所以Mybatis就应运而生了。

Mybatis

这是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。

Mybatis避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程。

它最初是一个Apache软件基金会下发起的一个项目,最初名为ibatis,随着项目的演进,提供到的功能越来越多

ibatis团队决定从Apache软件基金会迁移出来,并改名为Mybatis。

持久层框架:持久层框架是一种用于简化数据库访问代码的软件工具,它位于应用程序的业务逻辑层和数据存储层之间。

Mybatis的核心功能:

  • SQL映射:Mybatis允许你通过XML或者注解的方式来编写SQL语句,并将其与Java方法进行映射。
  • 对象关系映射:通过简单的配置,可以告诉Mybatis如何将数据库表的列映射到Java对象属性上
  • 事务管理:Mybatis支持声明式事务管理,通常与Spring等框架集成使用,可以让你轻松管理事务,确保数据的一致性和完整性。
  • 缓存机制:Mybatis提供了一级缓存和二级缓存的支持。一级缓存是SqlSession级别的缓存,默认开启且不能关闭,二级缓存则是跨SqlSession的缓存,需要手动配置启用。合理运用缓存,可以提高应用性能
  • 动态SQL:Mybatis提供了强大的动态SQL功能,允许你根据不同的条件动态生成SQL语句。

那么接下来小编就来分享下Mybatis如何进行操作数据库的方式。

操作数据的方式,有两个方式,一是注解,二是XML。

注解:

准备工作:

引入依赖:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- 这个依赖项用于将 MyBatis 集成到 Spring Boot 应用程序中。它简化了配置过程,并提供了自动配置功能,使得开发者可以更轻松地使用 MyBatis 进行数据库操作。此外,它还整合了 MyBatis 和 Spring 的事务管理、依赖注入等功能。--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency> <!--此依赖项是 MySQL 数据库的 JDBC 驱动程序,允许你的应用程序连接到 MySQL 数据库。<scope>runtime</scope> 表示该依赖仅在运行时需要,编译期间不需要。--> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> |

非Springboot项目,比如像是Maven项目的话,那就这样引入:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!--对于基本的 MyBatis 功能,你需要添加 MyBatis 的核心依赖:--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>最新版本号</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>最新版本号</version> </dependency> |

数据准备:

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| SQL -- 创建数据库 DROP DATABASE IF EXISTS mybatis_test; CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4; -- 使用数据数据 USE mybatis_test; -- 创建表[用户表] DROP TABLE IF EXISTS user_info; CREATE TABLE `user_info` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `username` VARCHAR(127) NOT NULL, `password` VARCHAR(127) NOT NULL, `age` TINYINT(4) NOT NULL, `gender` TINYINT(4) DEFAULT '0' COMMENT '1-男 2-女 0-默认', `phone` VARCHAR(15) DEFAULT NULL, `delete_flag` TINYINT(4) DEFAULT 0 COMMENT '0-正常, 1-删除', `create_time` DATETIME DEFAULT now(), `update_time` DATETIME DEFAULT now() ON UPDATE now(), PRIMARY KEY (`id`) ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; --create_time字段:记录数据的创建时间(当前时间),仅在插入时生效。 --update_time字段:记录数据的最后更新时间,插入时默认值,更新时自动刷新(当前时间) -- 添加用户信息 INSERT INTO mybatis_test.user_info(username, `password`, age, gender, phone) VALUES ('admin', 'admin', 18, 1, '18612340001'); INSERT INTO mybatis_test.user_info(username, `password`, age, gender, phone) VALUES ('zhangsan', 'zhangsan', 18, 1, '18612340002'); INSERT INTO mybatis_test.user_info(username, `password`, age, gender, phone) VALUES ('lisi', 'lisi', 18, 1, '18612340003'); INSERT INTO mybatis_test.user_info(username, `password`, age, gender, phone) VALUES ('wangwu', 'wangwu', 18, 1, '18612340004'); |

这里,小编使用的是navicat客户端(文章最后会介绍)

sql语句执行效果如下:

配置application.yml文件

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| YAML spring: application: name: MyBatis #数据库配置 datasource: url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false username: 自行填写 password: 自行填写(纯数字要加单引号) driver-class-name: com.mysql.cj.jdbc.Driver #为什么要配置打印日志,这里小编觉得原版打印出来不太好看,所以加上了这个打印日志配置 mybatis: configuration: # 配置打印 MyBatis日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |

准备工作到这里结束了,接下来进行代码编写

持久层代码编写

首先在创建好的项目中,创建一个mapper包和一个model包。

model包是存储实体类信息的,实体类是什么?

通常指的是软件开发中与数据表结构相对应的Java类。

既然我们表创建好了,那么代码中也要有对应的字段去映射

UserInfo(其他名字也可以):

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript @Data public class UserInfo { private Integer id; private String username; private String password; private Integer age; private Integer gender; private String phone; private Integer deleteFlag; private Date createTime; private Date updateTime; } |

在Mapper包,创建一个UserInfoMapper接口(其他名字也可以)。

|--------------------------------------------------|
| Java @Mapper public interface UserInfoMapper { } |

为什么要使用Mapper注解呢?

这个Mapper注解是一个标记注解,它的作用是:

  • 告诉 Spring 和 MyBatis:这个接口是一个 MyBatis Mapper。
  • Spring Boot 在启动时会扫描这些接口,并为它们生成动态代理对象(由 MyBatis 自动生成实现类)。
  • 有了这个注解,你就可以直接通过 @Autowired 注入这个接口并使用它进行数据库操作

动态代理简单解释下:

动态代理是Java中一种非常强大的机制,它允许你在运行时创建一个实现了一组接口的类的实例,而无需在编写的代码中显式地定义这些类。这个特性特别适用于像MyBatis这样的框架,它们需要在运行时根据配置或注解自动生成代码来处理数据库操作。

为什么要是一个接口呢?

这是因为Mybatis使用的是接口+动态代理的机制

这也是属于Mybatis的设计哲学之一:

  • 开发者只定义接口方法(比如:List<UserInfo> getAllUsers();)
  • MyBatis 会在运行时自动生成该接口的实现类(动态代理)
  • 实现类中封装了底层 JDBC 操作、SQL 执行、结果映射等逻辑

如若不想在之后的接口上,都写一Mapper注解,那么可以使用MapperScan注解

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript @SpringBootApplication @MapperScan("com.example.demo.mapper") // 自动扫描包下所有Mapper接口 public class MyBatiesApplication{ public static void main(String[] args) { SpringApplication.run(MyBatiesApplication.class, args); } } |

接下来写我们的增删改查代码了。

查询:

通过Mybatis提供的Select注解

方式一:

|---------------------------------------------------------------------------------------------------------|
| Java //不推荐 @Select("select * from user_info") List<UserInfo> selectUserInfo(); //返回的表中多行信息,所以用List接收 |

不推荐原因原因:*号还要被自动解析为各个表字段,消耗性能

那么如何进行测试呢?

这里提供一个测试快捷方式

在UsetInfoMapper代码中右键

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |

这里勾选下面selectUserInfo(),点击ok就自动生成测试类了

如若想手写测试,也是可以的,在该目录下创建一个测试类即可

那么一定义要加上@SpringBootTest,这样才会注入我们想要的UserInfoMapper对象

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @SpringBootTest class UserInfoMapperTest { //要用到该方法,那么首先要注入对象,这是手写的。 @Autowired private UserInfoMapper userInfoMapper; @Test void selectUserInfo() { System.out .println(userInfoMapper.selectUserInfo()); } } |

此时在测试类中,点击该方法的左边的绿色三角形按钮即可允许

结果

方式二:

|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select id,username,password,age," + "gender,phone,delete_flag,create_time,update_time from user_info") List<UserInfo> selectUserInfo(); |

生成测试:

|----------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserInfo2() { userInfoMapper.selectUserInfo2().forEach(x-> System.out .println(x)); } |

结果:

此时,我们发现,为什么create_time字段没有值呢?

这是因为当用一个集合作为范围类型的的时候,此时,返回的结果会与UserInfo的属性进行一一映射

当发现字段不一样的的时候,就映射失败,默认为null了,基础数据类型就会默认为0。

为什么字段不能都合为一致呢?

这是因为java有java的开发规范,数据库有数据库的建表规范,这些规范形成一个行业共识,一般都不会去改的。

当然还是有办法的

方法三:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select id,username,password,age," + "gender,phone,delete_flag as deleteFlag,create_time as createTime," + "update_time as updateTime from user_info") List<UserInfo> selectUserInfo(); |

测试类一样的,就不再生成

结果:

方法四:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Python //注解实现 @Select("select id,username,password,age," + "gender,phone,delete_flag,create_time,update_time from user_info") @Results( { @Result(column = "delete_flag",property = "deleteFlag"), @Result(column = "create_time",property = "createTime"), @Result(column = "update_time",property = "updateTime") }) List<UserInfo> selectUserInfo2(); |

@Results 注解用于定义结果映射(Result Mapping),它允许你更精细地控制如何将查询结果中的列映射到Java对象的属性。

生成测试:

|----------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserInfo2() { userInfoMapper.selectUserInfo2().forEach(x-> System.out .println(x)); } |

结果是和方法三中是一致的,不再展示。

而该注解还可以进行复用

将Restults注解修改下:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Results(id="baseMap",value = { @Result(column = "delete_flag",property = "deleteFlag"), @Result(column = "create_time",property = "createTime"), @Result(column = "update_time",property = "updateTime") }) |

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Python //复用注解 @Select("select id,username,password,age," + "gender,phone,delete_flag,create_time,update_time from user_info") @ResultMap("baseMap") List<UserInfo> selectUserInfo3(); |

运行该生成的测试代码后,结果与方法三一致

方法五:

通过配置文件修改

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| YAML mybatis: # 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件 mapper-locations: classpath:mapper/**Mapper.xml configuration: # 配置打印 MyBatis日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true #配置驼峰自动转换 |

此时呢,不用Restults注解也可以进行字段映射了

查询(带有条件):

上面刚刚使用的是不带条件查询,接下来介绍下带有条件查询的。

既然是带有条件,那么用到where或者order by等等,需要个参数。

如何写呢?

方法一:

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //以下为非唯一主键查询,返回结果建议使用list //该查询方式推荐使用 @Select("select * from user_info where gender=#{age} and age=#{gender}") List<UserInfo> selectUserByGenderAndAge( Integer age, Integer gender); |

此时,where中的参数和方法中参数,要一一对应,特别是顺序上,使用#占位符,预编译时,对应参数用?代替

#{}占位符:

  • 预编译 SQL 语句:使用 #{} 时,MyBatis 会将传入的参数视为一个预编译 SQL 语句的参数。这意味着参数会被当作 JDBC 预编译语句中的参数来处理,可以有效地防止 SQL 注入攻击。
  • 类型安全:MyBatis 会自动根据 Java 类型对参数进行适当的转换。例如,如果你传递的是一个整数类型的参数,MyBatis 会确保它以正确的格式插入到 SQL 语句中。

测试前,修改下表中数据

生成测试:

|-----------------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserByGenderAndAge() { System.out .println(userInfoMapper.selectUserByGenderAndAge(20, 0)); } |

结果:

值得一提的是,这样写,参数对应不上,会报出参数异常错误

|----------------------------------------------------------------------------------------|
| Java //参数异常 @Select("select * from user_info where gender=#{age1} and age=#{gender}") |

方法二:

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //参数排序,不推荐 @Select("select * from user_info where gender=#{param1} and age=#{param2}") List<UserInfo> selectUserByGenderAndAge( Integer gender, Integer age); |

方法中参数,gender和age,会被mybatis默认为param1为gender,age为param2.

所以这样写的话,可读性不是那么高

测试结果,与刚刚结果一致,不再展示

方法三:

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //参数重命名,param中的参数要和@select中参数一致 @Select("select * from user_info where gender=#{gender} and age=#{age}") List<UserInfo> selectUserByGenderAndAge(@Param("gender") Integer gender, @Param("age")Integer age); |

测试结果,与刚刚结果一致,不再展示

增加:

通过Mybatis提供的Insert注解

这里可以通过方法,方法中,要求传入一个个参数,进行插入。

但这里,小编使用的是,通过参数中传递对象进行插入

当参数中是对象的时候,此时呢,mybatis会将对象中设置好的值,与插入语句中参数一一映射

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //插入操作:(传递对象),返回影响行数 @Insert("insert into user_info (username,`password`,age,gender) " + "values (#{username},#{password},#{age},#{gender})") Integer insertUserInfo(UserInfo userInfo); |

values中,不需要userInfo.username相关操作,因为,这里没有涉及到重命名参数。

生成测试:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Test void insertUserInfo() { UserInfo userInfo=new UserInfo(); userInfo.setUsername("李四"); userInfo.setPassword("123"); userInfo.setAge(18); userInfo.setGender(0); System.out .println(userInfoMapper.insertUserInfo(userInfo)); } |

结果展示:

有时候,我们插入一个数据的时候,需要返回它的ID值,作为参数去传递到其他接口,那么此时该如何做呢?

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //同样传递对象,此时进行重命名,同时返回自增主键的值 @Options(useGeneratedKeys = true,keyProperty ="id") @Insert("insert into user_info (username,`password`,age,gender)" + " values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})") Integer insertUserInfo2(@Param("userInfo") UserInfo userInfo); |

此时,使用了重命名后,values中的参数就要使用userInfo.username了。

生成测试:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Test void insertUserInfo2() { UserInfo userInfo=new UserInfo(); userInfo.setUsername("王五"); userInfo.setPassword("456"); userInfo.setAge(20); userInfo.setGender(0); System.out .println(userInfoMapper.insertUserInfo2(userInfo)+"返回ID:"+ userInfo.getId()); } |

结果展示:

修改:

通过Mybatis提供的Update注解

|-------------------------------------------------------------------------------------------------------------------------------------------|
| Java //修改数据 @Update("update user_info set password=#{newPassword} where id=#{id}") Integer updateUserInfo(String newPassword,Integer id); |

当然,方法传入的参数也可以是对象。

生成测试:

|-------------------------------------------------------------------------------------------------------|
| Java @Test void updateUserInfo() { System.out .println(userInfoMapper.updateUserInfo("12345",4)); } |

结果展示:

删除:

通过Mybatis提供的Delete注解

|-------------------------------------------------------------------------------------------------|
| Java //删除数据 @Delete("delete from user_info where id=#{id}") Integer deleteUserInfo(Integer id); |

生成测试

|-----------------------------------------------------------------------------------------------|
| Java @Test void deleteUserInfo() { System.out .println(userInfoMapper.deleteUserInfo(5)); } |

结果展示:

排序:

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time" + "from user_info order by id #{sort}")//(报错) List<UserInfo> selectUserInfoByOrder(String sort); |

生成测试:

|------------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserInfoByOrder() { System.out .println(userInfoMapper.selectUserInfoByOrder("desc")); } |

结果展示:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript 重要的一条: Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''desc'' at line 1 |

此时发现报错信息后,我们查看信息是从下往上看,找到你看得懂的地方。

可以发现,这是语法错误

这是因为使用#{}占位符的时候,当参数为String类型,此时,就会自动单引号,导致最终的结果会多一个单引号。

修改方法,使用${}占位符

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time " + "from user_info order by age ${sort}") List<UserInfo> selectUserInfoByOrder(String sort); |

测试代码一样的,这里就展示为结果

那么,也可以发现,使用$占位符的时候,就会直接将结果进行填入,不会使用?符号代替

like查询

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java //由于方法参数为String类型,会自动为填入结果增加单引号,所以这里就用占位符 @Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time " + "from user_info where username like '%{key}%'") List<UserInfo> selectUserInfoByLike(String key); |

测试之前,改下数据库信息

测试用例:

|----------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserInfoByLike() { System.out .println(userInfoMapper.selectUserInfoByLike("java")); } |

结果展示:

当然,除了这个方法,还可以使用更安全的:

使用数据库自带的contact拼接方法

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time " + "from user_info where username like concat ('%',#{key},'%')") List<UserInfo> selectUserInfoByLike(String key); |

测试用例和结果一样,就不做展示。

由刚刚的例子得知,使用#号占位符和$占位符也是可以进行参数替换的,那么它们有什么区别呢?

#{}占位符和${}区别

|------|--------------|-------------------|
| 特性 | #{} | ${} |
| 处理方式 | 预编译参数 | 直接字符串替换 |
| 安全性 | 安全,防止 SQL 注入 | 不安全,可能导致 SQL 注入 |
| 适用场景 | 绝大多数情况下的参数传递 | 动态 SQL 片段,如表名、列名等 |
| 类型转换 | 支持类型转换 | 不支持类型转换 |

刚刚提到了SQL注入,那么SQL注入是什么呢?

SQL注入:

SQL注入(SQL Injection)是一种代码注入技术,攻击者通过将恶意的SQL代码插入到查询字符串中,进而操控数据库执行非授权的操作。

举例:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Select("select * from user_info where username= '{username}' and password= '{password}'") List<UserInfo> selectUserInfoByNameAndPassword(String username,String password); |

此时,当我们的${password}被用户输入用户和密码分别为为admin和 ' or 1='1后

此时呢,我们的SQL语句,就变成

|--------------------------------------------------------------------------------|
| Java select * from user_info where username='admin'and password= '' or 1='1'; |

那么此时,后面or语句总是为真,所以就会把所有用户信息参数出来,这是很危险的

  1. 防止SQL注入简单建议:
    核心建议:始终使用预编译语句和参数化查询
  1. 不要信任任何外部输入:所有来自用户的输入都应该被视为潜在的安全威胁,确保对这些输入进行验证和清理。
  1. 最小权限原则:为应用程序使用的数据库账户分配尽可能少的权限。例如,如果应用不需要删除表的功能,那么就不要给这个账户赋予删除权限。
  1. 保持软件更新:定期更新你的数据库管理系统、操作系统以及所使用的框架或库,以利用最新的安全补丁。

注解的方式就介绍到这里,接下来就介绍下XML的方式

XML

准备工作:

配置文件修改:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| YAML mybatis: # 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件 mapper-locations: classpath:mapper/**Mapper.xml configuration: # 配置打印 MyBatis日志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true #配置驼峰自动转换 |

文件创建:

在resources目录下创建个mapper目录,以及一个UserInfoMapper.xml(名字可以随心取),最后在启动类所在包的mapper包下,创建UserInfoXMLMapper接口(名字可以随心取)

在resources包下的xml文件中,填入以下基本内容

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!--这是 XML 文件的标准声明,表示该文件遵循 XML 1.0 规范,并且使用 UTF-8 编码格式。UTF-8 是一种字符编码方式,支持几乎所有的字符集,适合用于国际化的应用程序。 --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.nanxi.mybatis.mapper.UserInfoXmlMapper"> </mapper> |

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">:

简单解释下:

  • <!DOCTYPE mapper ... >:这是一个文档类型声明(Document Type Definition, DTD),它指定了当前 XML 文档遵循的规则。在这个例子中,mapper 元素必须符合 MyBatis 提供的 Mapper 3.0 规范。
  • "-//mybatis.org//DTD Mapper 3.0//EN":这是 DTD 的公共标识符,用来唯一标识该 DTD。
  • "http://mybatis.org/dtd/mybatis-3-mapper.dtd":这是 DTD 的系统标识符,通常是一个 URL,指向实际的 DTD 文件位置。虽然现代开发环境中可能不需要直接访问这个 URL,但它有助于验证 XML 文件是否符合 MyBatis 的规范

namespace这个是说明,该XML下的SQL语句与哪个接口下的接口方法对应起来

插件下载(推荐):

该插件有助于我们定义好接口方法后,快速生成对应的SQL语句标签。

XML代码编写

XML中编写的SQL语句,是基于一对对SQL语句标签的,比如<select> </select>。

查询:

方法一:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <select id="selectUserInfo" resultType="com.nanxi.mybatis.model.UserInfo"> select id,username,password,age,gender,phone, delete_flag as deleteFlage,create_time as createTime,update_time as updateTime from user_info; </select> |

resultType="com.nanxi.mybatis.model.UserInfo":

这个代表的是,返回类型是哪种的。

接口类中:

|----------------------------------------------------------------------------------------|
| Java @Mapper public interface UserInfoXmlMapper { List<UserInfo> selectUserInfo(); } |

生成测试:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript @SpringBootTest class UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper mapper; @Test void selectUserInfo() { mapper.selectUserInfo().forEach(x-> System.out .println(x)); } |

结果展示:

不想写AS去规范变量名的话,可以使用到resultMap标签

方法二:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <resultMap id="BaseMap" type="com.nanxi.mybatis.model.UserInfo"> <!-- 表中id涉及到主键,强烈建议写上id标签--> <id property="id" column="id"></id> <result column="delte_flage" property="deleteFlag"></result> <result column="update_time" property="updateTime"></result> <result column="create_time" property="createTime"></result> </resultMap> <select id="selectUserInfo" resultMap="BaseMap"> select id,username,password,age,gender,phone,delete_flag,create_time,update_time from user_info; </select> |

测试、接口以及结果都一样,这里就不做展示

以上这个是一种复用写法,如若想对单个查询标签起效

可以把resultMap中的id和type去掉,以及select标签下的resultMap去掉即可。

除了这个方法,还有一个就是修改配置文件,这个与注解那里一模一样,就不做讲解。

增加:

方法一:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- 插入操作--> <insert id="insertUserInfo"> insert into user_info(username,password,age,gender) values(#{username},#{password},#{age},#{gender}) </insert> |

接口方法:

|-------------------------------------------------|
| Java Integer insertUserInfo(UserInfo userInfo); |

生成测试:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java void insertUserInfo() { UserInfo userInfo=new UserInfo(); userInfo.setUsername("java"); userInfo.setPassword("java112"); userInfo.setAge(18); userInfo.setGender(0); System.out .println(mapper.insertUserInfo(userInfo)); } |

结果展示:

方法二:

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- 插入操作(重命名方式)--> <insert id="insertUserInfo2"> insert into user_info(username,password,age,gender) values(#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender}) </insert> |

接口方法:

|---------------------------------------------------------------------|
| Java Integer insertUserInfo2(@Param("userInfo") UserInfo userInfo); |

生成测试内容与结果,与方法一类似,所以就不做展示。

更新:

|-----------------------------------------------------------------------------------------------------------------------------|
| XML <!-- 更新操作--> <update id="updateUserInfo"> update user_info set `password`=#{password} where id=#{id}; </update> |

接口方法:

|-----------------------------------------------------------------------------------------------------------|
| Java //(也可以通过对象)进行传入 Integer updateUserInfo(@Param("password") String password, @Param("id") Integer id); |

生成测试:

|----------------------------------------------------------------------------------------------------|
| Java @Test void updateUserInfo() { System.out .println(mapper.updateUserInfo("123wangwu", 4)); } |

结果展示:

删除:

|-----------------------------------------------------------------------------------------------------------|
| XML <!-- 删除操作--> <delete id="deleteUserInfo"> delete from user_info where id=#{deleteId}; </delete> |

接口方法

|-------------------------------------------------------------|
| Java Integer deleteUserInfo(@Param("deleteId") Integer id); |

生成测试:

|---------------------------------------------------------------------------------------|
| Java @Test void deleteUserInfo() { System.out .println(mapper.deleteUserInfo(5)); } |

结果展示

对于XML中的一些基础增删查改就介绍到这。

接下来介绍下动态SQL语句。

动态SQL语句

举个例子

比如你进行用户信息编辑的时候,页面让你填入电话号码,但这个电话号码不一定是必选项,此时呢,你填入了电话号码,编辑后信息就有电话号码,如若你没有填入,编辑后信息就没有电话号码。

如何去实现呢?

接下来用到了if标签了

if标签:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML if标签使用 <!-- 插入选项是可选的--> <insert id="insertUserInfoByCondition"> insert into user_info (username, `password`, age, <if test="phone!=null"> phone, </if> gender ) values ( #{username}, #{password}, #{age}, <if test="phone!=null"> #{phone}, </if> #{phone} ) </insert> |

接口方法:

|-----------------------------------------------------------|
| XML Integer insertUserInfoByCondition(UserInfo userInfo); |

生成测试:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript @Test void insertUserInfoByCondition() { UserInfo userInfo=new UserInfo(); userInfo.setUsername("c++112"); userInfo.setPassword("c++1234"); userInfo.setAge(20); userInfo.setGender(0); // userInfo.setPhone("134879924"); System.out .println(mapper.insertUserInfoByCondition(userInfo)); } |

结果展示:

把setPhone的注释去掉后:

结果:

那么这个if标签要谨慎使用

比如

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bash <insert id="insertUserInfoByCondition"> insert into user_info (username, `password`, age, <if test="phone!=null"> phone, </if> <if test="gender!=null"> gender </if> ) values ( #{username}, #{password}, #{age}, <if test="phone!=null"> #{phone}, </if> <if test="gender!=null"> #{gender} </if> ) </insert> |

当phone和gender都没有填入,此时呢,sql语句这里,到age就结束,但是多了逗号没有去处理,那么就会出现

语法错误

那么接下来用到了trim标签了

trim标签:

它有这几个属性值:

  • suffixOverrides:去除后缀
  • suffix:添加 后缀
  • prefix:添加前缀
  • prefixOverrides:去除前缀

这些属性根据情况进行选择即可

这里小编当if语句不生效时,前一个的字段后逗号会去掉,使用到了去除后缀属性

代码:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- 分割标签--> <insert id="insertUserInfoByTrim"> insert into user_info ( <trim suffixOverrides=","> <if test="username!=null"> username, </if> <if test="password!=null"> `password`, </if> <if test="age!=null"> age, </if> <if test="gender!=null"> gender, </if> <if test="phone!=null"> phone </if> </trim> ) values ( <trim suffixOverrides=","> <if test="username!=null"> #{username}, </if> <if test="password!=null"> #{password}, </if> <if test="age!=null"> #{age}, </if> <if test="gender!=null"> #{gender}, </if> <if test="phone!=null"> #{phone} </if> </trim> ) </insert> |

接口方法:

|-------------------------------------------------------|
| Java Integer insertUserInfoByTrim(UserInfo userInfo); |

生成测试:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TypeScript @Test void insertUserInfoByTrim() { UserInfo userInfo=new UserInfo(); userInfo.setUsername("JS112"); userInfo.setPassword("Js12345"); userInfo.setAge(20); userInfo.setGender(0); // userInfo.setPhone("13712661733"); System.out .println(mapper.insertUserInfoByTrim(userInfo)); } |

结果:

where标签:

它存在以下特性:

  1. 自动添加 WHERE 关键字:如果 <where> 标签内的内容非空,则会自动添加 WHERE 关键字。这意味着你不需要手动在 SQL 中写 WHERE,这可以减少一些潜在的错误。
  1. 去除不必要的 AND 或 OR:当多个条件组合时,可能会出现第一个条件前有 AND 或 OR 的情况。<where> 标签会自动移除这些多余的关键词,确保生成的 SQL 语句正确无误。
  1. 支持动态条件:可以在 <where> 标签内部使用其他动态 SQL 元素(如 <if>、<choose> 等),根据不同的条件构建灵活的查询条件。

代码:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- where标签--> <select id="selectUserInfoByWhere" resultType="com.nanxi.mybatis.model.UserInfo"> select id,username,password,age,gender,phone,delete_flag,create_time,update_time from user_info <where> <if test="age!=null"> age=#{age} </if> <if test="gender!=null"> and gender=#{gender} </if> <if test="password!=null"> and password=#{password} </if> </where> </select> |

接口方法:

|-----------------------------------------------------------------|
| Java List<UserInfo> selectUserInfoByWhere(UserInfo userInfo); |

生成测试:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Test void selectUserInfoByWhere() { UserInfo userInfo=new UserInfo(); userInfo.setAge(18); userInfo.setGender(0); System.out .println(mapper.selectUserInfoByWhere(userInfo)); } |

结果:

set标签:

它存在以下特性:

  1. 自动添加 SET 关键字:如果 <set> 标签内的内容非空,则会自动添加 SET 关键字。
  1. 去除多余的逗号:当多个条件组合时,可能会出现最后一个字段前有多余逗号的情况。<set> 标签会自动移除这些多余的逗号,确保生成的 SQL 语句正确无误。
  1. 支持动态更新字段:可以在 <set> 标签内部使用其他动态 SQL 元素(如 <if>、<choose> 等),根据不同的条件构建灵活的更新操作。

代码:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- set标签--> <update id="updateUserInfoBySet"> update user_info set <if test="password!=null"> `password` = #{password}, </if> <if test="age!=null"> age=#{age}, </if> <if test="phone!=null"> phone=#{phone} </if> where id=#{id}; </update> |

接口方法:

|------------------------------------------------------|
| Java Integer updateUserInfoBySet(UserInfo userInfo); |

测试代码:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Test void updateUserInfoBySet() { UserInfo userInfo=new UserInfo(); userInfo.setId(11); userInfo.setPhone("1242533"); System.out .println(mapper.updateUserInfoBySet(userInfo)); } |

结果:

当我们想进行批量删除的时候,可以使用到foreach标签:

foreach标签

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- foreach标签--> <delete id="deleteUserInfoByDelete"> delete from user_info where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> |

collection参数是要和传入的集合参数名一致

item参数是代表中,从ids集合取出来的元素用id去接收

separator是代表着分隔符,是逗号

open和close代表着,从那里开始从哪里结束

接口方法:

|-----------------------------------------------------------|
| Java Integer deleteUserInfoByDelete(List<Integer> ids); |

生成测试:

|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Test void deleteUserInfoByDelete() { List<Integer> list = List.of (10, 11, 12); System.out .println(mapper.deleteUserInfoByDelete(list)); } |

结果:

include标签

当我们发现,对于XML编写中,一些语句是重复出现了,所以整体看起来比较繁重。

使用include标签,可以把它合在一起,然后增删查改标签页也可以使用了

代码:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <!-- include标签--> <sql id="allColumn"> id,username,password,age,gender,phone,delete_flag,create_time,update_time </sql> <select id="selectUserInfo" resultMap="BaseMap"> select <include refid="allColumn"></include> from user_info; </select> |

结果与之前展示过,这里就不再展示。

注解使用动态SQL语句

对于注解来说,就不可以使用动态SQL语句吗?

当然不是,只是会显示稍微麻烦,可读性没那么好罢了。

这里举个例子:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java @Delete({ "<script>", "DELETE FROM users WHERE id IN", "<foreach item='id' collection='list' open='(' separator=',' close=')'>", "#{id}", "</foreach>", "</script>" }) Integer deleteUsersByIds(@Param("list") List<Integer> ids); |

测试和结果就不做展示,与foreach标签那里,大差不差。

所以注解使用动态SQL语句,只需把<script> </script>标签即可

所以总的来说,这个mybatis可是方便了广大程序员,毕竟少些了很多共性代码。

既然这样的话,mybatis何不再努力下,把一些增删改查的基本代码一并帮写了?

接下来,介绍这个一个mybatis的增强工具

Mybatis Generator

是一个用于生成 MyBatis 相关代码的工具,旨在减少开发人员的手动编码工作量。它能够自动生成与数据库表对应的实体类(JavaBeans)、Mapper接口以及相应的XML映射文件.

快速使用:

1.引入插件:

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.1</version> <executions> <execution> <id>Generate MyBatis Artifacts</id> <phase>deploy</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <!--generator配置文件所在位置--> <configurationFile>src/main/resources/generator/generator.xml</configurationFile> <!-- 允许覆盖生成的文件, mapxml不会覆盖, 采用追加的方式--> <overwrite>true</overwrite> <verbose>true</verbose> <!--将当前pom的依赖项添加到生成器的类路径中--> <includeCompileDependencies>true</includeCompileDependencies> </configuration> <dependencies> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> </dependencies> </plugin> |

2.解释相关信息:

|-------------------------------------------------------------------------------------------------------------------------------------------|
| XML <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.1</version> |

这部分表示引入了 MyBatis Generator 的 Maven 插件。

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <executions> <execution> <id>Generate MyBatis Artifacts</id> <phase>deploy</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> |

  • <executions>:定义插件的执行方式和时机。
  • <execution>:一个具体的执行配置项。
  • <id>:执行 ID,用于唯一标识这个 execution,便于调试和日志查看。
  • <phase>:绑定到 Maven 生命周期中的哪个阶段,默认是 none,这里设置为 deploy 阶段执行 MBG。
  • <goals>:要执行的目标(即插件的功能),这里调用的是 generate,表示运行 MyBatis Generator 生成代码。

添加配置文件:

值得注意的是,配置文件要和pom.xml文件中,指定的一样

配置文件如下:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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> <!-- 一个数据库一个context --> <context id="MysqlTables" targetRuntime="MyBatis3" defaultModelType="flat"> <!--去除注释--> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库链接信息--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis_test?serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true" userId="root" password='12345'> </jdbcConnection> <!-- 生成实体类 --> <javaModelGenerator targetPackage="com.nanxi.mybatis.generator" targetProject="src/main/java" > <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- 生成mapxml文件 --> <sqlMapGenerator targetPackage="generator" targetProject="src/main/resources" > <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- 生成mapxml对应client,也就是接口dao --> <javaClientGenerator targetPackage="com.nanxi.mybatis.generator" targetProject="src/main/java" type="XMLMAPPER" > <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- table可以有多个,每个数据库中的表都可以写一个table,tableName表示要匹配的数据库表,也可以在tableName属性中通过使用%通配符来匹配所有数据库表,只有匹配的表才会自动生成文件 --> <table tableName="user_info"> <property name="useActualColumnNames" value="false" /> <!-- 数据库表主键 --> <generatedKey column="id" sqlStatement="Mysql" identity="true" /> </table> </context> </generatorConfiguration> |

3.对配置文件相关信息解释:

|------------------------------------------------------------------------------------|
| Java <context id="MysqlTables" targetRuntime="MyBatis3" defaultModelType="flat"> |

  • targetRuntime:
  • 指定目标运行时框架版本。
  • 常用值:
  • MyBatis3:适用于最新版 MyBatis。
  • MyBatis3Simple:不生成 Example 查询方法。
  • defaultModelType:
  • 控制模型类(实体类)的生成方式。
  • 常见值:
  • flat:为每张表只生成一个实体类(推荐使用)。
  • hierarchical:按层次结构生成多个类(如主键类、查询条件类等

|------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true" /> </commentGenerator> |

  • 常见 property:
  • suppressDate:
  • 设置为 true 表示在注释中不显示生成时间。
  • 默认会加上生成时间,例如:* @generated Thu May 27 09:45:00 CST 2025
  • suppressAllComments:
  • 设置为 true 表示完全禁用所有注释(包括警告信息)。
  • 如果你不希望看到"不要修改此文件"的警告注释,可以开启这个。

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <javaModelGenerator targetPackage="com.nanxi.mybatis.generator" targetProject="src/main/java" > <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="true"/> </javaModelGenerator> |

属性解释:

  • targetPackage:生成的 Java 类所在的包名。
  • targetProject:生成的 Java 类所在项目的路径(相对于项目根目录)。
  • enableSubPackages:
  • 是否根据表名自动创建子包(如 user -> com.example.model.user)。
  • 设置为 false 表示不自动创建子包。
  • trimStrings:
  • 设置为 true 表示对字符串类型的字段进行 trim 处理(防止空格问题)

|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <sqlMapGenerator targetPackage="generator" targetProject="src/main/resources" > <property name="enableSubPackages" value="false" /> </sqlMapGenerator> |

  • 属性解释:
  • targetPackage:XML 文件的包路径(通常是资源目录下的子路径)。
  • targetProject:XML 文件输出位置。
  • enableSubPackages:
  • 是否根据表名自动生成子包。
  • 设置为 false 表示统一放在指定目录下。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <javaClientGenerator targetPackage="com.nanxi.mybatis.generator" targetProject="src/main/java" type="XMLMAPPER" > <property name="enableSubPackages" value="false" /> </javaClientGenerator> |

  • 属性解释:
  • targetPackage:接口类所在的包名。
  • targetProject:接口类输出路径。
  • type:
  • 接口类型,常用值:
  • ANNOTATEDMAPPER:基于注解的 Mapper(不需要 XML)。
  • MIXEDMAPPER:混合模式(有注解也有 XML)。
  • XMLMAPPER:纯 XML 模式(最常用)。
  • enableSubPackages:
  • 是否根据表名生成子包。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <table tableName="user_info"> <property name="useActualColumnNames" value="false" /> <generatedKey column="id" sqlStatement="Mysql" identity="true" /> </table> |

  • 属性解释:
  • tableName:要生成代码的数据库表名,支持通配符 %,比如 "%" 表示所有表。
  • useActualColumnNames:
  • 设置为 false 表示列名转换为驼峰命名法(如 user_name → userName)。
  • 设置为 true 表示保留实际列名(不建议)。
  • <generatedKey>:
  • 用于处理主键自增字段。
  • 属性解释:
  • column="id":主键字段名。
  • sqlStatement="Mysql":数据库类型(MySQL)。
  • identity="true":表示是自增主键,插入数据后会回填 ID。

如若遇到generator.xml中,dtd信息报错:

可以对它进行临时忽略:

点击idea->file->setting->Languages & FrameWorks->Schemas and DTDS

点击下面的Ignored上的+号

出现的页面中,加入xml中,对应出错的URL即可

4.运行使用:

如若想生成动态SQL,按照以下步骤:

pom文件引入该依赖:

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| XML <dependency> <groupId>org.mybatis.dynamic-sql</groupId> <artifactId>mybatis-dynamic-sql</artifactId> <version>1.3.1</version> <!-- 或者更高版本,比如1.4.0+ --> </dependency> |

generator.xml修改:

|---------------------------------------------------------------------------------------------|
| XML <context id="MysqlTables" targetRuntime="MyBatis3DynamicSql" defaultModelType="flat"> |

注意,版本要相互对应,提供官方的链接,可以自行去比对

Introduction to MyBatis Generator

最后点击运行即可。

这个增强工具,更多是在项目初期的时候使用,一键生成代码,减少工作量。

介绍Navicat

Navicat 是一款功能强大且广受欢迎的数据库管理和开发工具,支持多种数据库系统。它由 PremiumSoft CyberTech Ltd. 开发,并面向数据库管理员、软件开发者等专业人士设计,旨在简化数据库管理流程,提高工作效率。

下载软件:

Navicat | 产品

下载这个免费轻量版

下载安装。

安装成功后,进入该页面:

点击连接:

点击MySQL,小编本地是MySQL,所以,这个具体数据,看个人电脑是什么,或者说远程的SQL是什么

进入该页面

输入对应内容连接即可

连接成功后:

右键demo可以创建数据库,点击数据库下的表,右键它可以创建表。

如若想输入SQL语句来完成,那么点击对应最上面的新建查询,打开后,输入对应的SQL语句。

到这里,mybatis一些基础使用,小编分享到这。

相关推荐
不剪发的Tony老师2 小时前
sqlite-vec:谁说SQLite不是向量数据库?
数据库·人工智能·sqlite
abcnull2 小时前
springboot配置mybatis debug的sql日志输出
spring boot·sql·mybatis
敢敢变成了憨憨3 小时前
java操作服务器文件(把解析过的文件迁移到历史文件夹地下)
java·服务器·python
苇柠3 小时前
Java补充(Java8新特性)(和IO都很重要)
java·开发语言·windows
Lin_XXiang3 小时前
java对接bacnet ip协议(跨网段方式)
java·物联网
白总Server3 小时前
C++语法架构解说
java·网络·c++·网络协议·架构·golang·scala
敲键盘的小夜猫3 小时前
Milvus向量Search查询综合案例实战(下)
数据库·python·milvus
咖啡啡不加糖3 小时前
雪花算法:分布式ID生成的优雅解决方案
java·分布式·后端
小杜-coding3 小时前
天机学堂(初始项目)
java·linux·运维·服务器·spring boot·spring·spring cloud
钢铁男儿4 小时前
深入剖析C#构造函数执行:基类调用、初始化顺序与访问控制
java·数据库·c#