MyBatis中能否使用聚合函数?新手求教结果映射问题
在MyBatis中使用聚合函数的完全指南
嘿,作为MyBatis新手能想到这个问题真的很赞!当然可以在MyBatis里用聚合函数啦,不管是COUNT、SUM、AVG还是MAX/MIN这些,用法和普通SQL里一模一样,关键是怎么把查询结果映射对,我给你拆解几种常见场景:
1. 映射到自定义DTO(最推荐的方式)
如果你的聚合查询结果是一组统计数据,没有对应的现有实体类,最好新建一个专门的DTO(数据传输对象)来接收。比如你要统计用户总数:
首先创建一个UserStatsDTO类:
public class UserStatsDTO { private Integer totalUsers; // 对应聚合查询的别名 // Getter和Setter方法 public Integer getTotalUsers() { return totalUsers; } public void setTotalUsers(Integer totalUsers) { this.totalUsers = totalUsers; } }
然后在Mapper接口里定义方法:
public interface UserMapper { UserStatsDTO getTotalUserCount(); }
最后在MyBatis的XML映射文件里写SQL:
<select id="getTotalUserCount" resultType="com.example.dto.UserStatsDTO"> SELECT COUNT(*) AS total_users FROM user </select>
这里要注意:SQL里的别名total_users要和DTO里的属性名totalUsers对应(MyBatis默认支持下划线转驼峰命名,如果你开了这个配置的话),或者你也可以用resultMap手动指定映射关系。
2. 映射到现有实体类的扩展属性
如果聚合查询和现有实体类相关,比如要统计每个用户的订单数量,可以给实体类加一个扩展属性:
比如给User类加个orderCount属性:
public class User { private Integer id; private String username; private Integer orderCount; // 新增的聚合结果属性 // 省略其他Getter/Setter public Integer getOrderCount() { return orderCount; } public void setOrderCount(Integer orderCount) { this.orderCount = orderCount; } }
Mapper接口方法:
List<User> getUserWithOrderCount();
XML里的SQL:
<select id="getUserWithOrderCount" resultType="com.example.entity.User"> SELECT u.id, u.username, COUNT(o.id) AS order_count FROM user u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.username </select>
3. 临时查询用Map接收
如果只是一次性的临时查询,不想新建类,直接用Map<String, Object>接收最省事:
Mapper接口方法:
Map<String, Object> getOrderTotalAmount();
XML里的SQL:
<select id="getOrderTotalAmount" resultType="java.util.Map"> SELECT SUM(amount) AS total_amount FROM orders </select>
之后你就可以通过map.get("total_amount")拿到聚合结果啦。
小提示
- 不管用哪种方式,SQL里的聚合函数一定要加别名,不然MyBatis没法识别要映射到哪个属性(或者Map的key)。
- 如果你的MyBatis没开下划线转驼峰的配置,记得让别名和属性名完全一致,或者用
resultMap手动配置映射关系。
内容的提问来源于stack exchange,提问作者Jithin M V
相关产品推荐
相关产品推荐

