本文主要来讲解6大标签,以便更好的MyBatis操作数据库!
- <if>标签
- <trim>标签
- <where>标签
- <set>标签
- <foreach>标签
- <include>标签
前提需求:
MyBatis是一个持久层框架,和Spring没有任何关系,可以用来简化数据库的操作!
创建工作:
创建Spring Boot工程,并导入MyBatis的起步依赖,Mysql的依赖等
配置数据
#配置数据库的连接字符串
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8
username: root
password: 你自己设置的密码
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #自动驼峰转换
#配置mybatis xml的文件路径,在resources/mapper创建所有表的xml文件
mapper-locations: classpath:mapper/**Mapper.xml
本文主要讲解MyBatis来操作数据库!!
然而操作数据库主要是用来增删改查四个方面,因此,本文着重于增删改查来讲解!!
在操作数据库之前,我们需要创建一个数据库:
-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
`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(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
那么,此时我们需要创建一个UserInfo类,使其各个参数名称与数据库参数名称相同(类似)
@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 LocalDateTime createTime;
private LocalDateTime updateTime;
}
值得注意的是:由于Java参数名称语法的原因,不能带有"_"(下划线),因此,Java中参数名称与数据库中参数名称出现了不一样的情况!!
另外还需要在application.xml中引入配置:(必须)
mybatis:
# mapper-locations: classpath:mapper/*Mapper.xml
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #自动驼峰转换
#配置mybatis xml的文件路径,在resources/mapper创建所有表的xml文件
mapper-locations: classpath:mapper/**Mapper.xml
新创建的UserInfoXMLMapper.xml文件中存储:
<?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.example.mapper.UserInfoXMLMapper">
<!-- UserInfoXMLMappe指的是:要实现哪个接口?要写接口的全限定类名!(包名+类名) -->
</mapper>
有了上述的前提,我们便开始步入正题吧!
<if>标签:
比如我要注册某账号,但是在填写信息页面,有着必填项,非必填项,那么,填写数据就需要往数据库增加某条数据,但是,对于一些数据我不确定要不要增加,因此,这就需要我们理性写SQL语句了!
@Mapper
public interface UserInfoXML2Mapper {
//增
Integer insert(UserInfo userInfo);
}
<?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.example.mapper.UserInfoXML2Mapper">
<!-- UserInfoXMLMappe指的是:要实现哪个接口?要写接口的全限定类名!(包名+类名) -->
<insert id="insert">
insert into userinfo(
<trim suffixOverrides=",">
<if
test="id != null">
id,
</if>
<if
test="username != null">
username,
</if>
<if
test="password != null">
password,
</if>
<if
test="phone != null">
phone,
</if>
<if
test="gender != null">
gender,
</if>
<if
test="age != null">
age,
</if>
</trim>
)
values(
<trim suffixOverrides=",">
<if
test="id != null">
#{id},
</if>
<if
test="username != null">
#{username},
</if>
<if
test="password != null">
#{password},
</if>
<if
test="phone != null">
#{phone},
</if>
<if
test="gender != null">
#{gender},
</if>
<if
test="age != null">
#{age},
</if>
</trim>
)
</insert>
</mapper>
Spring Boot测试代码:
@SpringBootTest
@Slf4j
class UserInfoXML2MapperTest {
@Autowired
private UserInfoXML2Mapper userInfoXML2Mapper;
@Test
void insert() {
UserInfo userInfo=new UserInfo();
userInfo.setId(47);
userInfo.setAge(4);
userInfo.setUsername("test");
userInfo.setPassword("123456");
userInfo.setPhone("13511111111");
userInfo.setUpdateTime(LocalDateTime.now());
userInfo.setCreateTime(LocalDateTime.now());
userInfoXML2Mapper.insert(userInfo);
}
}
代码的运行结果为:
查询数据库为:
当我们随机不输入几个参数的时候:
具有选择性质的填写功能就可得以实现!!
MyBatis的if标签是一个功能强大的动态SQL元素,它允许你在SQL语句中包含条件判断。以下是if标签的一些主要用法:
- 字段非空判断:你可以使用if标签来判断某个字段是否为空。如果字段不为空,则在SQL语句中添加相应的条件。这对于避免因null值而导致的查询错误非常有用。
- 参数比较:if标签还可以用来判断传入的参数是否满足某些条件。例如,你可以检查一个传入的参数是否等于某个特定值,如果是,则在SQL语句中添加相应的条件。
- 逻辑组合:if标签可以用于构建复杂的逻辑条件。你可以使用多个if标签来构建AND或OR的逻辑组合,从而创建更加精确的查询条件。
- 灵活的查询条件:通过if标签,你可以根据实体类属性的值来动态生成查询条件。这允许你根据实际需要包含或排除某些查询条件,从而提高SQL语句的灵活性。
- OGNL表达式:if标签的test属性必须填写,它是一个OGNL(Object-Graph Navigation Language)表达式,通常以true或false作为结果。这意味着你可以使用任何符合OGNL语法的表达式来进行条件判断。
- 备选条件:在某些情况下,你可以使用if标签来提供备选条件。例如,如果name字段无效,你可能会选择使用nickName或id作为过滤条件。
- 与其他标签结合:if标签可以与其他MyBatis标签(如trim、choose、when等)结合使用,以实现更复杂的SQL逻辑。
总的来说,if标签是MyBatis动态SQL中一个非常有用的工具,它允许开发者根据不同的条件构建灵活且强大的SQL语句。在实际开发中,合理运用if标签可以帮助你编写更加简洁和高效的代码。
<trim>标签:
简单来说,<trim>标签有四个对应的属性:添加前缀后缀,删除前缀后缀!该功能非常强大!
rim标签在MyBatis中用于格式化SQL语句,它可以添加前缀和后缀,也可以覆盖掉内容的首部或尾部。具体来说,trim标签有以下几种用法:
- 包裹where条件:使用trim标签可以去除WHERE或AND前的空格或逗号,以及SELECT或SET后的空格或逗号。
- 添加前缀和后缀:通过prefix属性添加前缀,suffix属性添加后缀。这些属性可以帮助构建完整的SQL语句。
- 覆盖前缀和后缀:prefixOverrides属性用于去除内容的首部某些内容,suffixOverrides属性用于去除尾部的某些内容。这在构建复杂的SQL语句时非常有用。
- 拼接select语句:在拼接select语句的where部分时,可以使用trim标签和prefixOverrides属性来消除可能存在的多余AND关键字。
- 拼接insert语句:在拼接insert语句时,可以使用trim标签为表名后添加括号,并消除末尾不需要的逗号。同时,需要添加"values ("前缀和")"后缀,并消除末尾不需要的逗号。
- 拼接update语句:在拼接update语句的set部分时,可以使用trim标签来消除末尾不需要的逗号。
- 替代where或set标签:trim标签可以完成where或set标签的功能,使得SQL语句更加简洁和易于管理。
- 组合使用:trim标签可以与其他动态SQL标签(如if、foreach等)结合使用,以实现更复杂的SQL逻辑。
总的来说,trim标签是MyBatis中一个非常灵活且强大的工具,它可以帮助开发者构建更加干净、高效的SQL语句。在实际开发中,合理运用trim标签可以简化SQL语句的书写,提高代码的可读性和可维护性。
<?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.example.mapper.UserInfoXML2Mapper">
<!-- UserInfoXMLMappe指的是:要实现哪个接口?要写接口的全限定类名!(包名+类名) -->
<insert id="insert">
insert into userinfo
<trim suffixOverrides="," prefix="(" suffix=")">
<if
test="id != null">
id,
</if>
<if
test="username != null">
username,
</if>
<if
test="password != null">
password,
</if>
<if
test="phone != null">
phone,
</if>
<if
test="gender != null">
gender,
</if>
<if
test="age != null">
age,
</if>
</trim>
values
<trim suffixOverrides="," prefix="(" suffix=")">
<if
test="id != null">
#{id},
</if>
<if
test="username != null">
#{username},
</if>
<if
test="password != null">
#{password},
</if>
<if
test="phone != null">
#{phone},
</if>
<if
test="gender != null">
#{gender},
</if>
<if
test="age != null">
#{age},
</if>
</trim>
</insert>
<insert id="insert2">
insert into userinfo(
<trim suffixOverrides=",">
<if
test="id != null">
id,
</if>
<if
test="username != null">
username,
</if>
<if
test="password != null">
password,
</if>
</trim>
)
values(
<trim suffixOverrides=",">
<if
test="id != null">
#{id},
</if>
<if
test="username != null">
#{username},
</if>
<if
test="password != null">
#{password},
</if>
</trim>
)
</insert>
</mapper>
<where>标签:
比如我要删除某条数据,但是,我需要根据参数id,或者参数username,或者参数age等各种参数来进行筛选一下!因此,这就需要我们理性写SQL语句了!
@Mapper
public interface UserInfoXML2Mapper {
//删
Integer delete(UserInfo userInfo);
}
<?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.example.mapper.UserInfoXML2Mapper">
<!-- UserInfoXMLMappe指的是:要实现哪个接口?要写接口的全限定类名!(包名+类名) -->
<delete id="delete">
delete from userinfo
<trim suffixOverrides=",">
<where>
<if
test="id != null">
id = #{id}
</if>
<if
test="username != null">
and username = #{username}
</if>
<if
test="password != null">
and password = #{password}
</if>
</where>
</trim>
</delete>
</mapper>
Spring Boot测试代码:
@SpringBootTest
@Slf4j
class UserInfoXML2MapperTest {
@Autowired
private UserInfoXML2Mapper userInfoXML2Mapper;
@Test
void delete() {
UserInfo userInfo=new UserInfo();
userInfo.setId(45);
// userInfo.setUsername("<trim>标签");
// userInfo.setPassword("123456");
userInfoXML2Mapper.delete(userInfo);
}
}
代码的运行结果为;
查看数据库:
MyBatis的标签是一个用于动态生成SQL语句中的WHERE子句的标签。它的主要作用是自动处理WHERE关键字和AND关键字之间的空格,以及去除多余的逗号。以下是标签的一些主要用法:
- 自动处理WHERE关键字:当使用标签时,MyBatis会自动在WHERE关键字前添加一个空格,并在AND关键字前添加一个空格。这样可以避免手动编写这些空格,减少代码量并提高可读性。
- 去除多余逗号:在使用标签时,如果条件列表中存在多个条件,MyBatis会自动去除最后一个条件的末尾逗号。这可以避免手动编写这些逗号,减少代码量并提高可读性。
- 组合使用:标签可以与其他动态SQL标签(如if、foreach等)结合使用,以实现更复杂的SQL逻辑。例如,你可以使用标签来构建包含多个条件的查询语句,然后使用if标签来判断某些条件是否满足,从而动态地生成最终的SQL语句。
- 嵌套使用:标签可以嵌套在其他标签内部使用,以实现更复杂的SQL逻辑。例如,你可以使用一个标签来构建主查询条件,然后在另一个标签中使用if标签来判断某些条件是否满足,从而动态地生成最终的SQL语句。
- 灵活的查询条件:通过标签,你可以根据实体类属性的值来动态生成查询条件。这允许你根据实际需要包含或排除某些查询条件,从而提高SQL语句的灵活性。
- 简化代码:使用标签可以减少手动编写SQL语句时的代码量,使代码更加简洁易读。
总的来说,标签是MyBatis动态SQL中一个非常有用的工具,它可以帮助开发者自动处理WHERE关键字和AND关键字之间的空格,以及去除多余的逗号。在实际开发中,合理运用标签可以帮助你编写更加简洁和高效的代码。
<set>标签:
在某app中,我们需要经常的更改某些个人信息啥的,但是对于很多的个人信息,有些需要改,有些又不想改,那么,我们该如何处理呢?因此,这就需要我们理性写SQL语句了!
@Mapper
public interface UserInfoXML2Mapper {
//改
Integer update(UserInfo userInfo);
}
<?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.example.mapper.UserInfoXML2Mapper">
<!-- UserInfoXMLMappe指的是:要实现哪个接口?要写接口的全限定类名!(包名+类名) -->
<update id="update">
update userinfo
<trim suffixOverrides=",">
<set>
<if test="phone != null">
phone = #{phone},
</if>
<if test="age != null">
age = #{age},
</if>
</set>
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</trim>
</update>
</mapper>
Spring Boot测试代码:
@SpringBootTest
@Slf4j
class UserInfoXML2MapperTest {
@Autowired
private UserInfoXML2Mapper userInfoXML2Mapper;
@Test
void update() {
log.info("userInfoXML2Mapper.update()");
UserInfo userInfo=new UserInfo();
userInfo.setAge(3);
userInfo.setPhone("1099");
userInfo.setId(5);
// userInfo.setUsername("test");
userInfoXML2Mapper.update(userInfo);
}
}
代码的运行结果为:
查看数据库:
set标签在MyBatis中用于动态构建UPDATE语句的SET部分,主要用于更新列信息。以下是它的一些用法特点:
- 动态包含列:set标签可以动态地包含需要更新的列,忽略那些不需要更新的列,这样可以避免在SQL语句中出现多余的逗号。
- 结合if使用:通常set标签会和if标签一起使用,以便根据条件来决定是否包含某个列的更新。例如,只有当某个属性值不为空时,才在SET子句中包含该属性的更新。
- 去除多余逗号:set标签还具有自动去除末尾多余逗号的功能,这有助于保持SQL语句的整洁性。
- 简化代码:使用set标签可以减少代码量,使得编写的SQL语句更加简洁和易于维护。
- 示例用法:在编写UPDATE语句时,可以使用标签包裹一系列的标签,每个标签内包含一个属性的更新条件。例如,如果用户的name或gender属性不为空,则在SET子句中添加相应的更新语句。
总的来说,set标签是MyBatis动态SQL中一个非常实用的工具,它可以帮助开发者更灵活地构建UPDATE语句,实现对数据库记录的精确更新。在实际开发中,合理运用set标签可以提高代码的效率和可读性。
<foreach>标签:
MyBatis的标签是一个用于动态生成SQL语句中的循环结构的标签。它的主要作用是遍历一个集合或数组,并根据集合中的元素生成相应的SQL语句片段。以下是标签的一些主要用法:
- 遍历集合:标签可以遍历一个集合或数组,并根据集合中的元素生成相应的SQL语句片段。例如,你可以使用标签来遍历一个用户列表,并为每个用户生成一条INSERT语句。
- 动态构建IN子句:标签可以用于动态构建SQL语句中的IN子句,以便根据集合中的元素生成多个条件。例如,你可以使用标签来遍历一个ID列表,并生成一个包含多个ID条件的IN子句。
- 结合其他标签使用:标签通常与其他动态SQL标签(如if、choose等)结合使用,以实现更复杂的SQL逻辑。例如,你可以使用标签遍历一个订单列表,并结合if标签来判断订单状态是否满足某个条件,从而动态地生成相应的SQL语句。
- 嵌套使用:标签可以嵌套在其他标签内部使用,以实现更复杂的SQL逻辑。例如,你可以使用一个标签来遍历一个部门列表,然后在另一个标签中使用if标签来判断某个部门下的员工数量是否满足某个条件,从而动态地生成最终的SQL语句。
- 示例用法:在编写SELECT语句时,可以使用标签遍历一个ID列表,并生成一个包含多个ID条件的WHERE子句。例如,如果需要查询ID为1、2、3的用户信息,可以使用以下代码
<select id="selectUsers" resultType="User"> SELECT * FROM user WHERE id IN <foreach item="id" collection="ids" open="(" separator="," close=")"> #{id} </foreach> </select>
在这个例子中,
collection="ids"
表示你要遍历的集合名为ids
,item="id"
表示集合中每个元素的别名为id
,open="("
和close=")"
定义了整个IN子句的开始和结束字符,而separator=","
则定义了集合中每个元素之间的分隔符。这样,如果ids
集合包含[1, 2, 3],那么生成的SQL语句将会是:SELECT * FROM user WHERE id IN (1, 2, 3)
总的来说,标签是MyBatis动态SQL中一个非常实用的工具,它可以帮助开发者更灵活地构建SQL语句,实现对数据库记录的精确查询和更新。在实际开发中,合理运用标签可以提高代码的效率和可读性。
<include>标签:
MyBatis的标签用于引用其他映射文件中的内容,可以将多个映射文件组合在一起,提高代码复用性和可维护性。
具体来说,当你需要在不同的映射文件中使用相同的SQL片段时,你可以将这些SQL片段定义在一个单独的映射文件中,然后在其他映射文件中使用标签来引用这些SQL片段。这样可以避免重复编写相同的SQL语句,提高代码的可读性和可维护性。
例如,假设你有一个名为
common.xml
的映射文件,其中包含了一些常用的SQL片段:<!-- common.xml --> <sql id="selectColumns"> id, name, age </sql> <sql id="orderByAgeDesc"> ORDER BY age DESC </sql>
然后,在另一个映射文件中,你可以使用标签来引用这些SQL片段:<!-- userMapper.xml --> <select id="selectUsers" resultType="User"> SELECT <include refid="selectColumns"/> FROM user <include refid="orderByAgeDesc"/> </select>
在这个例子中,
<include refid="selectColumns"/>
表示引用了common.xml
文件中的selectColumns
SQL片段,而<include refid="orderByAgeDesc"/>
则表示引用了common.xml
文件中的orderByAgeDesc
SQL片段。这样,你就可以在不同的映射文件中共享相同的SQL片段,提高代码的复用性和可维护性