资讯动态

mybatis(二)

发布时间:2026/10/17 11:57:54 来源:尧图企业网站定制
一动态SQL动态SQL是Mybatis的强大特性之一能够完成不同条件下不同的sql拼接1.1 if标签在注册用户的时候可能会有这样⼀个问题注册分为两种字段必填字段和非必填字段那如果在添加用户的时候有不确定的字段传入程序应该如何实现呢这个时候就需要使用动态标签来判断了比如添加的时候性别gender为非必填字段具体实现如 下接口定义Integer insertUserInfoByCondition(UserInfo userInfo);Mapper.xml实现:insert idinsertUserInfoByCondition insert into user_info(username,password,age, if testgender!null gender, /if phone) values (#{username},#{password},#{age}, if testgender!null #{gender}, /if #{phone}) /insert不加if标签时运行结果如下未传参的会赋值为null加了标签之后运行结果为其中未传参的会赋上默认值或者使用注解方式Insert( script insert into user_info trim suffixOverrides, prefix( suffix) if testusername!nullusername,/if if testpassword!nullpassword,/if if testage!nullage,/if if testgender!nullgender,/if if testphone!nullphone/if /trim values trim suffixOverrides, prefix( suffix) if testusername!null#{username},/if if testpassword!null#{password},/if if testage!null#{age},/if if testgender!null#{gender},/if if testphone!null#{phone}/if /trim /script ) Integer insertUserInfoByCondition(UserInfo userInfo);注意test中的gender是传入对象中的属性不是数据库字段上述例子中test里面是判断条件判断 #{gender}是否为空Q: 可不可以不进行判断直接把字段设置为null呢?A: 不可以, 这种情况下如果gender字段有默认值就会设置为默认值1.2 trim标签之前的插入用户功能只是有⼀个gender字段可能是选填项如果有多个字段⼀般考虑使用标签结合标签对多个字段都采取动态生成的方式。标签中有如下属性• prefix表示整个语句块以prefix的值作为前缀• suffix表示整个语句块以suffix的值作为后缀• prefixOverrides表示整个语句块要去除掉的前缀• suffixOverrides表示整个语句块要去除掉的后缀调整Mapper.xml的插入语句为insert idinsertUserInfoByCondition insert into user_info trim suffixOverrides, prefix( suffix) if testusername!null username, /if if testpassword!null password, /if if testage!null age, /if if testgender!null gender, /if if testphone!null phone /if /trim values trim suffixOverrides, prefix( suffix) if testusername!null #{username}, /if if testpassword!null #{password}, /if if testage!null #{age}, /if if testgender!null #{gender}, /if if testphone!null #{phone} /if /trim /insert在以上sql动态解析时会将第⼀个部分做如下处理• 基于 prefix 配置开始部分加上 (• 基于 suffix 配置结束部分加上 )• 多个组织的语句都以 , 结尾在最后拼接好的字符串还会以 , 结尾会基于suffixOverrides 配置去掉最后一个• 注意 username 是传入对象的属性1.3 where标签需求:传⼊的⽤⼾对象根据属性做where条件查询⽤⼾对象中属性不为null的都为查询条件.如 username为a则查询条件为whereusernamea接⼝定义:ListUserInfo queryByCondition();Mapper.xml实现:select idqueryByCondition resultTypecom.luoyaoyun.mybatisdemo.model.UserInfo !-- SELECT * FROM user_info WHERE 11-- !-- trim prefixOverridesAND-- !-- if testage!null-- !-- age #{age}-- !-- /if-- !-- if testgender!null-- !-- AND gender #{gender}-- !-- /if-- !-- if testdeleteFlag!null-- !-- AND delete_flag #{deleteFlag}-- !-- /if-- !-- /trim-- SELECT * FROM user_info where if testage!null age #{age} /if if testgender!null AND gender #{gender} /if if testdeleteFlag!null AND delete_flag #{deleteFlag} /if /where /select上述代码有两种方法其中where标签就完成了第一种方法中实现的两种方法1去除最前面的and 2如果查询条件为空则不添加where关键字where只会在⼦元素有内容的情况下才插⼊where⼦句⽽且会⾃动去除⼦句的开头的AND或 OR以上标签也可以使用trim prefixwhere prefixOverridesAND替换,但是此种情况下,当⼦元素都没有内容时,where关键字也会保留1.4 set标签需求根据传入的⽤⼾对象属性来更新⽤⼾数据可以使⽤标签来指定动态内容接⼝定义根据传⼊的⽤⼾id属性修改其他不为null的属性Integer updateUserByCondition(UserInfo userInfo);Mapper.xmlupdate idupdateByCondition !-- update user_info-- !-- set-- !-- trim suffixOverrides,-- !-- if testusername!null-- !-- username#{username},-- !-- /if-- !-- if testage!null-- !-- age #{age},-- !-- /if-- !-- if testgender!null-- !-- gender #{gender},-- !-- /if-- !-- if testdeleteFlag!null-- !-- delete_flag #{deleteFlag}-- !-- /if-- !-- /trim-- !-- where id #{id}-- update user_info set if testusername!null username#{username}, /if if testage!null age #{age}, /if if testgender!null gender #{gender}, /if if testdeleteFlag!null delete_flag #{deleteFlag} /if /set where id #{id} /updateset : 动态的在SQL语句中插⼊set关键字并会删掉额外的逗号.(用于update语句中)1.5 foreach标签对集合进⾏遍历时可以使⽤该标签。标签有如下属性• collection绑定⽅法参数中的集合如ListSetMap或数组对象• item遍历时的每⼀个对象• open语句块开头的字符串• close语句块结束的字符串• separator每次遍历之间间隔的字符串需求:根据多个userid,删除用户数据接⼝⽅法:void deleteByIds(ListInteger ids);UserInfoMapper.xmldelete idbatchDelete delete from user_info where id in foreach collectionids open( close) itemid separator, #{id} /foreach /delete1.6 include标签在xml映射⽂件中配置的SQL有时可能会存在很多重复的⽚段此时就会存在很多冗余的代码我们可以对重复的代码⽚段进⾏抽取将其通过sql 标签封装到⼀个SQL⽚段然后再通过include标签进⾏引⽤。sql定义可重⽤的SQL⽚段include通过属性refid指定包含的SQL⽚段sql idallColumn id, username, age, gender, phone, delete_flag, create_time, update_time /sql通过include标签在原来抽取的地⽅进⾏引⽤。select idqueryAllUser resultMapBaseMap select include refidallColumn/include from user_info /select select idqueryById resultTypecom.example.demo.model.UserInfo select include refidallColumn/include from user_info where id #{id} /select二. 案例练习2.1 表白墙2.1.1 数据准备DROP TABLE IF EXISTS message_info; CREATE TABLE message_info ( id INT ( 11 ) NOT NULL AUTO_INCREMENT, from VARCHAR ( 127 ) NOT NULL, to VARCHAR ( 127 ) NOT NULL, message VARCHAR ( 256 ) NOT 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;ON UPDATE now()当数据发生更新操作时自动把该列的值设置为now(),now() 可以替换成其他获取时间的标识符,⽐如:CURRENT_TIMESTAMP(),LOCALTIME()等2.1.2 引入MyBatis和MySQL驱动依赖修改pom文件dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version4.0.1/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency2.1.4 编写后端代码ModelData public class MessageInfo { private Integer id; private String from; private String to; private String message; private Integer deleteFlag; private Date createTime; private Date updateTime; }MessageInfoMapperMapper public interface MessageInfoMapper { Select(select id, from, to, message from message_info where delete_flag0) ListMessageInfo queryAll(); Insert(insert into message_info (from,to, message) values(#{from},#{to},#{message})) Integer addMessage(MessageInfo messageInfo); }MessageInfoServiceService public class MessageInfoService { Autowired private MessageInfoMapper messageInfoMapper; public ListMessageInfo queryAll() { return messageInfoMapper.queryAll(); } public Integer addMessage(MessageInfo messageInfo) { return messageInfoMapper.addMessage(messageInfo); } }MessageControllerRequestMapping(/message) RestController public class MessageController { Autowired private MessageInfoService messageInfoService; GetMapping(/getList) public ListMessageInfo getList(){ return messageInfoService.queryAll(); } PostMapping(value /publish) public boolean publish(MessageInfo messageInfo) { System.out.println(messageInfo); if (StringUtils.hasLength(messageInfo.getFrom()) StringUtils.hasLength(messageInfo.getTo()) StringUtils.hasLength(messageInfo.getMessage())) { messageInfoService.addMessage(messageInfo); return true; } return false; } }访问这个网址即可

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑