mybatis使用时遇到的一些问题------模糊查询、处理大于号小于号、相关函数替换空值...

本文介绍了在MyBatis中实现模糊查询的方法,如何在XML文件中正确处理大于号和小于号,以及在不同数据库中替换空值的策略。同时,详细展示了如何使用数据库函数如IFNULL、ISNULL、NVL和COALESCE处理NULL值。

在mybatis中可能会用到的方法

1.模糊查询

    <select id="showByIdName" parameterType="User" resultMap="resultmap">
        SELECT r.*,u.id,u.age,u.`password`,u.username FROM role r
        LEFT JOIN user u ON r.role_id=u.role_id
        <where>
            <if test="username != null and username != ''">
                username LIKE concat(concat('%',#{username}),'%')
            </if>
        </where>
    </select>

 

2.在xml文件中处理大于号小于号的方法

(1)用了转义字符把>和<替换掉

XML转义字符表格如下:

 

                 &lt;                                 

                     <

                     小于号                                           

                     &gt;

                     >                                      

                     大于号

                     &amp;

                     &

                     和

                     &apos;

                     ’

                     单引号

                     &quot;

                     "

                     双引号

 

(2)使用<![CDATA[ ]]>符号进行说明,将此类符号不进行解析

<![CDATA[ when min(starttime)<='12:00' and max(endtime)<='12:00' ]]>  

3.利用数据库相关函数替换空值

(1)在MYSQL中可以这样来写:

select IFNULL(sum(data),0)

(2)在SQLSERVER中可以这样写:

select ISNULL(sum(data),0)

(3)在ORACLE中可以这样写:

select NVL(sum(data),0) 

(4)对于所有数据库适用的方法可以这样写:

select COALESCE(sum(data),0)

COALESCE()用法:

COALESCE(value,...) 

返回第一个不是null的值,如果参数列表全是null,则返回null

  SELECT COALESCE(NULL,1);
          -> 1

  SELECT COALESCE(NULL,NULL,NULL);
          -> NULL

 

转载于:https://www.cnblogs.com/javJoker/p/7260195.html

<think>我们根据接口文档要求,实现班级列表的条件分页查询功能,其中包含按日期范围(结课间)筛选。 接口要求: 请求路径:/clazzs 请求方式:GET 请求参数(queryString): name: 班级名称(模糊查询) begin: 开始日期(结课间范围) end: 结束日期(结课间范围) page: 页码(必须) pageSize: 每页记录数(必须) 实现步骤: 1. 实体类(Entity): 对应数据库的班级表,假设表名为`clazz`,包含字段(示例): id, name, create_time, graduate_time(结课间)等。 2. Mapper层:使用MyBatis的XML方式编写动态SQL查询,支持按班级名称模糊查询和结课间范围查询,并实现分页。 3. Service层:调用Mapper的分页查询方法,并返回分页结果。 4. Controller层:接收请求参数,调用Service方法,返回分页数据。 注意:分页使用MyBatis-Plus的分页插件(如果使用MyBatis-Plus)或者使用PageHelper(如果使用MyBatis原生分页)。这里我们使用MyBatis-Plus,因为其集成较为方便。 下面按照三层架构实现: 步骤1:实体类 假设班级表对应的实体类为Clazz(注意:数据库表字段与实体类属性映射,这里使用下划线转驼峰) 步骤2:Mapper接口和XML Mapper接口继承BaseMapper,并自定义分页查询方法(使用MyBatis-Plus的分页功能) 步骤3:Service接口和实现 步骤4:Controller 具体实现如下: 1. 实体类(Clazz.java): 使用注解@TableName("clazz")指定表名 注意:结课间字段,假设数据库字段为graduate_time,实体类中为graduateTime。 2. Mapper层: 接口:ClazzMapper.java XML:ClazzMapper.xml 3. Service层: 接口:ClazzService 实现:ClazzServiceImpl 4. Controller层:ClazzController 另外,需要配置MyBatis-Plus的分页插件。 详细代码: 1. 实体类: ```java package com.example.demo.entity; import com.baomidou.mybatisplus.annotation.TableName; import java.time.LocalDateTime; @Data @TableName("clazz") public class Clazz { private Long id; private String name; // 班级名称 private LocalDateTime createTime; // 创建间 private LocalDateTime graduateTime; // 结课间 // 其他字段... } ``` 2. Mapper接口: ```java package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.entity.Clazz; import org.apache.ibatis.annotations.Param; public interface ClazzMapper extends BaseMapper<Clazz> { Page<Clazz> selectClazzPage(Page<Clazz> page, @Param("name") String name, @Param("begin") String begin, @Param("end") String end); } ``` 3. Mapper XML(ClazzMapper.xml): 在resources/mapper目录下创建ClazzMapper.xml 这里使用动态SQL,根据参数判断是否添加条件 注意:日期范围查询,数据库字段graduate_time在实体中为graduateTime,但我们在XML中直接使用数据库字段名。 假设数据库字段为graduate_time,我们使用`graduate_time`进行条件筛选。 ```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.demo.mapper.ClazzMapper"> <select id="selectClazzPage" resultType="com.example.demo.entity.Clazz"> SELECT * FROM clazz <where> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> <!-- 日期范围查询:注意begin和end都是字符串,格式为'yyyy-MM-dd' --> <if test="begin != null and begin != ''"> AND graduate_time >= #{begin} </if> <if test="end != null and end != ''"> AND graduate_time <= #{end} </if> </where> ORDER BY graduate_time DESC </select> </mapper> ``` 4. Service层: 接口: ```java package com.example.demo.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.entity.Clazz; public interface ClazzService { Page<Clazz> getClazzByPage(int page, int pageSize, String name, String begin, String end); } ``` 实现类: ```java package com.example.demo.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.entity.Clazz; import com.example.demo.mapper.ClazzMapper; import com.example.demo.service.ClazzService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ClazzServiceImpl implements ClazzService { @Autowired private ClazzMapper clazzMapper; @Override public Page<Clazz> getClazzByPage(int page, int pageSize, String name, String begin, String end) { Page<Clazz> pageObj = new Page<>(page, pageSize); return clazzMapper.selectClazzPage(pageObj, name, begin, end); } } ``` 5. Controller层: ```java package com.example.demo.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.entity.Clazz; import com.example.demo.service.ClazzService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/clazzs") public class ClazzController { @Autowired private ClazzService clazzService; @GetMapping public Page<Clazz> getClazzList( @RequestParam(required = false) String name, @RequestParam(required = false) String begin, @RequestParam(required = false) String end, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int pageSize) { return clazzService.getClazzByPage(page, pageSize, name, begin, end); } } ``` 6. 配置MyBatis-Plus分页插件(在配置类中): ```java package com.example.demo.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` 7. 在application.properties或application.yml中配置Mapper XML的位置: ```properties # application.properties mybatis-plus.mapper-locations=classpath:mapper/*.xml ``` 注意:日期范围查询,我们这里传递的是字符串(格式为'yyyy-MM-dd'),在SQL中直接与datetime类型的字段比较。如果数据库存储的是date类型,也可以直接比较。如果数据库存储的是datetime,而传入的是日期字符串(如'2023-01-01'),那么数据库会自动转换为当天的00:00:00,所以范围查询是包含当天的。 但是,如果传入的日期字符串包含间,那么需要确保格式匹配。这里接口要求传入的是日期(如2023-01-01),所以没有问题。 另外,在XML中,我们使用了`<where>`标签,它会自动处理AND和OR的条件连接,并且如果条件为空,则不会添加WHERE关键字。 关于分页:MyBatis-Plus的分页插件会自动在查询语句外面加上分页的SQL(LIMIT),所以我们在XML中不需要写LIMIT语句。 测试请求: GET /clazzs?name=黄埔&begin=2023-01-01&end=2023-12-31&page=1&pageSize=10 返回结果:Page对象会被MyBatis-Plus自动转换为JSON格式,包含分页信息和记录列表。 以上实现了按班级名称模糊查询和按结课间范围查询的分页功能。 相关问题: 1.MyBatis中如何防止SQL注入? 2. MyBatis-Plus的分页原理是什么? 3. 如何优化MyBatis动态SQL的编写? 4. 在日期范围查询中,如果数据库存储的是间戳,应该如何查询? 5. 如何配置MyBatis-Plus使用不同的数据库(如Oracle)? 注意:在XML中,小于号`<`需要使用`<`转义,如`<=`表示`<=`。 另外,如果日期范围查询需要包含边界值,并且数据库字段是datetime类型,那么使用`>=`和`<=`可以包含当天的全部间。但是,如果结束日期是2023-12-31,那么会包含2023-12-31 00:00:00到23:59:59的间。如果传入的结束日期字符串是'2023-12-31',那么SQL中的条件为`graduate_time <= '2023-12-31'`,实际上会包含'2023-12-31 00:00:00',而不会包含'2023-12-31 23:59:59'。因此,如果需要包含一整天,可以将结束日期加一天,或者使用`< 结束日期的下一天`。 但是,根据接口文档,参数begin和end是范围匹配的开始和结束间(结课间),且示例为日期格式。所以,我们按照文档要求,直接使用`>=`和`<=`。 如果要求精确到间,那么接口参数应该传递间字符串(如'2023-01-01 00:00:00'),但文档只要求日期,所以按日期处理即可。 如果数据库存储的日期字段是date类型(只有日期,没有间),那么直接比较没有问题。 因此,我们按照上述实现即可。</think>### MyBatis XML Mapper 实现日期范围查询 是的,MyBatis XML Mapper 完全可以支持通过 `beginDate` 和 `endDate` 进行日期范围筛选查询。以下是具体实现方案: #### 1. XML Mapper 配置示例 ```xml <!-- src/main/resources/mapper/ClazzMapper.xml --> <select id="selectClazzByDateRange" resultType="com.example.entity.Clazz"> SELECT * FROM clazz <where> <!-- 日期范围条件 --> <if test="beginDate != null"> AND graduate_time >= #{beginDate} </if> <if test="endDate != null"> AND graduate_time <= #{endDate} </if> <!-- 其他条件 --> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> </where> ORDER BY graduate_time DESC </select> ``` #### 2. 关键实现说明 1. **日期范围查询**: - `graduate_time >= #{beginDate}`:筛选结课间大于等于开始日期的记录 - `graduate_time <= #{endDate}`:筛选结课间小于等于结束日期的记录 - 使用`<=`避免XML解析错误(小于等于符的XML转义) 2. **动态SQL**: - `<if>`标签确保条件为空不生成无效SQL - 支持同处理日期范围和其他查询条件(如班级名称) 3. **参数处理**: - 参数类型应为`java.util.Date`或`java.time.LocalDate`(推荐) - MyBatis自动处理Java日期类型与SQL日期类型的转换 #### 3. Mapper 接口定义 ```java public interface ClazzMapper { List<Clazz> selectClazzByDateRange( @Param("beginDate") Date beginDate, @Param("endDate") Date endDate, @Param("name") String name ); } ``` #### 4. 日期范围查询优化建议 1. **日期格式处理**: ```xml <!-- 使用DATE_FORMAT处理不同格式的日期 --> AND DATE_FORMAT(graduate_time, '%Y-%m-%d') BETWEEN #{beginDate} AND #{endDate} ``` 2. **处理**: ```xml <!-- 显式指定--> AND CONVERT_TZ(graduate_time, '+00:00', 'Asia/Shanghai') BETWEEN #{beginDate} AND #{endDate} ``` 3. **索引优化**: ```sql -- 确保graduate_time字段有索引 CREATE INDEX idx_graduate_time ON clazz(graduate_time); ``` #### 5. 完整查询示例 ```java // 服务层调用 public List<Clazz> getClazzByDateRange(Date begin, Date end, String name) { return clazzMapper.selectClazzByDateRange(begin, end, name); } // 控制器 @GetMapping("/clazzs") public List<Clazz> getClazzs( @RequestParam(required = false) @DateTimeFormat(pattern="yyyy-MM-dd") Date begin, @RequestParam(required = false) @DateTimeFormat(pattern="yyyy-MM-dd") Date end, @RequestParam(required = false) String name) { return clazzService.getClazzByDateRange(begin, end, name); } ``` ### 日期范围查询注意事项 1. **日期格式**: - 使用`@DateTimeFormat`注解确保参数正确转换 - 数据库字段类型需与Java类型匹配(DATE/DATETIME ↔ java.util.Date/LocalDateTime) 2. **边界处理**: - 包含开始日期和结束日期:`BETWEEN ... AND ...` - 排除结束日期:`graduate_time < #{endDate}` 3. **空值处理**: - 当只提供开始日期:查询该日期之后的所有记录 - 当只提供结束日期:查询该日期之前的所有记录 4. **性能优化**: - 避免在WHERE子句中使用函数包裹字段(会导致索引失效) - 大数据量考虑分页查询[^2] ### 相关问题 1. MyBatis中如何处理不同数据库的日期函数差异(如MySQL/Oracle)?[^1] 2.MyBatis XML中如何实现动态排序(按不同字段升降序)? 3. 如何优化MyBatis日期范围查询在大数据量下的性能?[^2] 4. MyBatis中`#{}`和`${}`在日期处理中有何区别?[^4] 5. 三层架构中如何统一处理日期格式转换?[^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值