2026/1/27 7:06:49
网站建设
项目流程
曲靖市住房和城乡建设局网站,wordpress重新设置域名,容桂网站智能推广新闻,淘宝客建站模板1.查询和修改1.1 MyBatis中的where, set和trim标签详解1.1.1 where标签where标签用于动态生成SQL语句中的WHERE子句#xff0c;它会智能处理以下情况#xff1a;自动去除开头多余的AND或OR当所有条件都不满足时#xff0c;不会生成…1.查询和修改1.1 MyBatis中的where, set和trim标签详解1.1.1 where标签where标签用于动态生成SQL语句中的WHERE子句它会智能处理以下情况自动去除开头多余的AND或OR当所有条件都不满足时不会生成WHERE关键字简化了条件判断的书写示例用法select iddfFindUser parameterTypeentity.User resultTypeentity.User select * from user where if testusername ! null username like concat(%,#{username},%) /if if testphone ! null and phone like concat(%,#{phone},%) /if if testaddress ! null and address like concat(%,#{address},%) /if /where /select应用场景多条件查询时避免手动处理WHERE和AND/OR的逻辑不确定哪些条件会生效的动态查询1.1.2 set标签set标签用于动态生成UPDATE语句中的SET部分特点包括自动去除末尾多余的逗号当所有条件都不满足时不会生成SET关键字简化UPDATE语句的构建示例用法update iddfupdate parameterTypeentity.User update user set if testusername ! null username#{username}, /if if testpassword ! null password#{password}, /if if testsex ! null sex#{sex}, /if if testage ! null age#{age}, /if if testphone ! null phone#{phone} /if /set where id#{id} /update应用场景动态更新部分字段不确定哪些字段需要更新的情况1.1.3 trim标签trim标签是更通用的解决方案可以自定义前缀、后缀以及要移除的内容功能更灵活可以完全替代where和set标签可以自定义处理逻辑通过属性控制前缀、后缀和要移除的内容基本属性prefix添加前缀suffix添加后缀prefixOverrides移除前缀中的指定内容suffixOverrides移除后缀中的指定内容示例用法!-- 替代where标签 -- select idtrFindUser parameterTypeentity.User resultTypeentity.User select * from user trim prefixwhere prefixOverridesand | or if testusername ! null username like concat(%,#{username},%) /if if testphone ! null and phone like concat(%,#{phone},%) /if if testaddress ! null and address like concat(%,#{address},%) /if /trim /select !-- 替代set标签 -- update idtrupdate parameterTypeentity.User update user trim prefixset suffixOverrides, if testusername ! null username#{username}, /if if testpassword ! null password#{password}, /if if testsex ! null sex#{sex}, /if if testage ! null age#{age}, /if if testphone ! null phone#{phone} /if /trim where id#{id} /update应用场景需要更精细控制SQL片段生成的场景构建复杂的动态SQL语句需要自定义前缀后缀处理逻辑的情况1.1.4对比总结标签主要用途自动处理灵活性where生成WHERE子句去除开头AND/OR中set生成SET子句去除末尾逗号中trim通用片段生成可自定义高在实际开发中可以根据具体需求选择合适的标签trim标签虽然功能最强大但where和set标签在特定场景下使用更加简洁明了。1.2 选择查询choose-when-otherwise语法结构等同于编程中的if...else if...else逻辑结构说明choose作为整个条件结构的容器标签是父级标签包含所有when和otherwise子标签when对应编程中的if或else if语句每个when标签包含test属性用于指定判断条件表达式标签体条件满足时要执行的SQL片段或内容otherwise对应编程中的else语句不包含条件判断是默认执行分支查询示例根据用户输入执行不同查询逻辑当输入用户名时 → 按用户名查询当输入地址时 → 按地址查询当无输入时 → 默认按ID查询用法示意select idchoose parameterTypeentity.User resultTypeentity.User select * from user where choose when testusername ! null username #{username} /when when testaddress ! null address #{address} /when otherwise id #{id} /otherwise /choose /where /select1.3 批量操作1.3.1 批量删除使用 foreach 标签实现动态 SQL在 Mapper XML 文件中使用 foreach 标签构建 IN 语句collection: 数组或集合名称这个要和Mapper接口方法中的参数名称一致item: 自定义循环变量名称separator: 分割方式open: 循环开始方式close: 循环结束方式delete iddeleteMore delete from user where id in !--collection:数组或集合名称 item:自定义当前循环变量名称 -- !--separator:分割方式 open:当前循环开始方式 close当前循环结束方法-- foreach collectionids itemid open( separator, close) #{id} /foreach /delete对应的 Mapper 接口方法public int deleteMore(Param(ids) Integer[] ids);//Param强制注入这里必须使用Param注解将数据强制注入注意事项大量数据删除操作可能造成数据库锁表建议在低峰期执行删除前最好先备份数据考虑添加事务管理确保数据一致性对于关联表数据需要处理好外键约束1.3.2 批量添加sql语句insert into user (username,password,sex,age,phone,address) values (#{username},#{password},#{sex},#{age},#{phone},#{address}), (#{username},#{password},#{sex},#{age},#{phone},#{address}), (#{username},#{password},#{sex},#{age},#{phone},#{address});使用 foreach 标签在 XML 映射文件中使用foreach标签遍历集合拼接多条 INSERT 语句insert idinsertMore insert into user (username,password,sex,age,phone,address) values foreach collectionusers itemuser separator, (#{user.username},#{user.password},#{user.sex},#{user.age},#{user.phone},#{user.address}) /foreach /insert /mapper性能优化建议对于大数据量批量插入建议分批处理每批 500-1000 条数据 设置rewriteBatchedStatementstrue参数提升 MySQL 批量插入性能 考虑使用多线程并行插入提高效率1.4 Param注解在mybatis中的应用1.4.1 基本概念Param注解是MyBatis框架提供的一个注解用于在Mapper接口方法中为参数指定名称。当Mapper接口方法有多个参数时使用Param可以明确指定每个参数在SQL映射文件中的引用名称。1.4.2 主要用途多参数方法当Mapper接口方法需要接收多个参数时使用Param为每个参数命名User selectUser(Param(username) String username, Param(password) String password);集合/数组参数传递集合或数组参数时需要指定参数名ListUser findUsersByIds(Param(ids) ListInteger ids);参数映射清晰使SQL映射文件中的参数引用更加明确1.4.3 使用场景场景1基本使用public interface UserMapper { // 使用Param为参数命名 User selectByUsernameAndPassword( Param(username) String username, Param(password) String password ); }对应的XML映射select idselectByUsernameAndPassword resultTypeUser SELECT * FROM user WHERE username #{username} AND password #{password} /select场景2集合参数public interface UserMapper { ListUser findByIds(Param(ids) ListInteger ids); }对应的XML映射select idfindByIds resultTypeUser SELECT * FROM user WHERE id IN foreach itemitem collectionids open( separator, close) #{item} /foreach /select场景3对象参数public interface UserMapper { int updateUser( Param(user) User user, Param(status) Integer status ); }对应的XML映射update idupdateUser UPDATE user SET status #{status} WHERE id #{user.id} /update1.4.4 注意事项当方法只有一个参数时通常可以省略Param注解使用Param注解后XML中必须使用指定的名称引用参数参数名不能包含特殊字符或空格与Java 8的-parameters编译选项相比Param提供了更明确的参数命名方式1.4.5 最佳实践为所有非简单类型参数添加Param注解提高代码可读性保持参数命名一致性和描述性避免过度使用对于简单查询可以省略在团队中统一Param的使用规范1.4.6 替代方案(不推荐)如果不使用Param注解还可以使用Java 8的-parameters编译选项保留方法参数名使用param1, param2,...的默认命名方式将多个参数封装为一个DTO对象2. 关联查询2.1 数据库关键字映射2.1.1 resultMap标签的作用resultMap是MyBatis中用于定义数据库结果集与Java对象映射关系的核心标签。通过resultMap可以精确控制查询结果如何转换为Java对象特别是处理复杂对象关系时。2.1.2 标签和属性的具体说明id属性定义该resultMap的唯一标识符在SQL映射文件中通过这个id引用该映射关系。type属性指定映射的目标Java类型这里是entity.Order类表示查询结果将映射为Order对象。result子标签用于定义简单字段的映射关系propertyJava对象的属性名column数据库查询结果的字段名称association子标签处理对象类型的复杂属性映射集合使用collectionofType:泛型的类型信息property目标对象在父对象中的属性名这里是usersjavaType关联对象的Java类型这里是entity.Users 内部使用result标签定义关联对象的字段映射2.1.3 关键注意事项association标签用于处理一对一关系如果是一对多关系应使用collection标签。当列名与属性名不一致时如realname→realName必须显式声明映射关系。2.1.4 实际应用场景一对一分开写resultMap idUsersOrderMap typeentity.Order result propertyid columnid/ result propertyorder_number columnorder_number/ result propertytotal_price columntotal_price/ result propertystatus columnstatus/ result propertyuser_id columnuser_id/ !--复杂字段单独处理 对象使用association 集合使用collection-- association propertyusers javaTypeentity.Users result propertyid columnid/ result propertyusername columnusername/ result propertypassword columnpassword/ result propertyrealName columnrealname/ /association /resultMapselect idfindUsersOrder1 resultMapUsersOrderMap select users.*,orders.order_number,total_price,status from users left join orders on users.id orders.user_id /select一对一分布式分布式写法 select * from orders select * from users where id {user_id}select idgetOrders resultMaporders select * from orders /select resultMap idorders typeentity.Order result propertyid columnid/ result propertyorder_number columnorder_number/ result propertytotal_price columntotal_price/ result propertystatus columnstatus/ result propertyuser_id columnuser_id/ !--cloumn:这里比较特殊是用来传值的-- !--selectsql方法的调用-- association propertyusers javaTypeentity.Users columnuser_id selectgetUserById/ /resultMap select idgetUserById resultTypeentity.Users select * from users where id #{id} /select一对多select idfindUsersOrders resultMapUserOrders select users.*,orders.order_number,total_price,status from users left join orders on users.id orders.user_id /select resultMap idUserOrders typeentity.Users result propertyid columnid/ result propertyusername columnusername/ result propertypassword columnpassword/ result propertyrealName columnrealname/ !--ofType:泛型的类型信息-- collection propertyorders ofTypeentity.Order result propertyid columnid/ result propertyorder_number columnorder_number/ result propertytotal_price columntotal_price/ result propertystatus columnstatus/ result propertyuser_id columnuser_id/ /collection /resultMap !--分布式-- !--查询user-- select idgetUsers resultMapUserOrders1 select * from users /select resultMap idUserOrders1 typeentity.Users result propertyid columnid/ result propertyusername columnusername/ result propertypassword columnpassword/ result propertyrealName columnrealname/ collection propertyorders ofTypeentity.Order fetchTypelazy columnid selectgetOrders/ /resultMap select idgetOrders resultTypeentity.Order select * from orders where user_id #{user_id} /select2.2 懒加载延迟加载Lazy Loading是 MyBatis 提供的一种优化技术用于在需要时才加载关联对象的数据避免一次性加载所有关联数据导致性能问题。以下是关于 MyBatis 延迟加载的详细说明和配置方法。2.2.1 延迟加载的配置在 MyBatis 的全局配置文件中可以通过以下设置启用延迟加载settings !-- 启用延迟加载 -- setting namelazyLoadingEnabled valuetrue/ !-- 禁用积极加载按需加载 -- setting nameaggressiveLazyLoading valuefalse/ /settingslazyLoadingEnabled设置为true时启用延迟加载。aggressiveLazyLoading设置为false时MyBatis 会严格按需加载关联对象。如果设置为true任何方法调用都会触发加载所有延迟加载的属性。2.2.2 关联关系的延迟加载在映射文件Mapper XML中可以通过fetchTypelazy为关联关系如association或collection配置延迟加载resultMap idorderResultMap typeOrder id propertyid columnid/ result propertyorderNo columnorder_no/ !-- 延迟加载用户信息 -- association propertyuser columnuser_id javaTypeUser selectcom.example.mapper.UserMapper.selectById fetchTypelazy/ /resultMapfetchType设置为lazy时该关联对象会延迟加载设置为eager时会立即加载。2.2.3 使用注解配置延迟加载如果使用注解方式可以通过Lazy注解标记延迟加载public class Order { private Integer id; private String orderNo; Lazy private User user; }2.2.4 延迟加载的触发条件延迟加载的关联对象会在以下情况下被加载直接调用关联对象的getter方法。通过序列化或反射访问关联对象。2.2.5 注意事项序列化问题延迟加载的对象在序列化时可能会触发加载。可以通过实现Serializable接口并重写writeReplace方法避免。性能权衡延迟加载可以减少初始查询的数据量但可能增加后续查询的次数。需根据业务场景权衡。代理对象MyBatis 通过动态代理实现延迟加载因此关联对象是代理实例而非实际对象。