在 MyBatis 中通过时间戳(Timestamp)作为查询条件,需注意数据库时间类型与 Java 类型的映射。以下是具体实现方式:
一、Java 实体类与数据库字段映射
-
实体类定义
使用java.sql.Timestamp
或java.time.LocalDateTime
(推荐)类型:public class Order {private Long id;private LocalDateTime createTime; // 对应数据库的 TIMESTAMP/DATETIME// getter/setter }
-
数据库字段类型
- MySQL:
TIMESTAMP
或DATETIME
- Oracle:
TIMESTAMP
- PostgreSQL:
TIMESTAMP
- MySQL:
二、XML 映射文件写法
方式1:直接参数传递
<select id="selectByTimeRange" resultType="Order">SELECT * FROM orders WHERE create_time BETWEEN #{startTime} AND #{endTime}
</select>
方式2:动态条件(if 标签)
<select id="selectByCondition" resultType="Order">SELECT * FROM orders<where><if test="startTime != null">AND create_time >= #{startTime}</if><if test="endTime != null">AND create_time <= #{endTime}</if></where>
</select>
三、接口方法与参数传递
场景1:精确时间查询
// Mapper 接口方法
List<Order> selectByCreateTime(@Param("targetTime") LocalDateTime targetTime);// 调用示例
mapper.selectByCreateTime(LocalDateTime.of(2025, 7, 4, 0, 0));
场景2:时间范围查询
List<Order> selectByTimeRange(@Param("startTime") Timestamp startTime,@Param("endTime") Timestamp endTime
);// 调用示例(使用 java.sql.Timestamp)
mapper.selectByTimeRange(new Timestamp(System.currentTimeMillis() - 86400000), // 前一天new Timestamp(System.currentTimeMillis()) // 当前时间
);
四、特殊场景处理
1. 时区问题
若存在时区差异,可在 SQL 中转换:
<select id="selectByUTC" resultType="Order">SELECT * FROM ordersWHERE CONVERT_TZ(create_time, '+00:00', '+08:00') = #{localTime}
</select>
2. 时间格式化查询
<select id="selectByDate" resultType="Order">SELECT * FROM ordersWHERE DATE_FORMAT(create_time, '%Y-%m-%d') = #{dateStr}
</select>
五、注意事项
- 类型匹配:确保 Java 类型(如
LocalDateTime
)与 JDBC 驱动兼容,MyBatis 3.4+ 默认支持 JSR-310 时间类型。 - 索引优化:对时间字段加索引可大幅提升范围查询性能。
- 参数传递:使用
@Param
注解明确参数名,避免 XML 中引用混乱。