当前位置: 首页 > news >正文

MyBatis 查询结果接收类型的总结与实践

MyBatis 查询结果接收类型的总结与实践

      • 基本情况
        • 1. 实体类型(Java Bean)
        • 2. Map 类型
        • 3. 自定义结果类型
        • 4. List 集合
        • 5. List<Map<String, Object>>
        • 6. 多参数接收
        • 7. 自定义对象
        • 8. 动态结果类型
      • 复杂情况
        • 1. 多表关联查询
          • 示例代码
        • 2. 分页查询
          • 示例代码
        • 3. 动态 SQL
          • 示例代码
        • 4. 批量更新/插入
          • 示例代码
        • 5. 存储过程
          • 示例代码
        • 6. 嵌套查询
          • 示例代码
          • 示例代码
        • 8. 事务管理
          • 示例代码

基本情况

1. 实体类型(Java Bean)

实体类型是最常用的接收方式之一,适用于结果集与实体类字段一一对应的情况。这种方式不仅便于后续处理,还能够充分利用对象关系映射(ORM)的优势。

示例代码

public interface UserMapper {User getUserById(Integer id);
}<select id="getUserById" resultType="com.example.model.User">SELECT * FROM users WHERE id = #{id}
</select>
2. Map 类型

当结果集中的字段与实体类不完全匹配,或者需要处理复杂的结构(如嵌套查询结果)时,可以选择将结果集映射为 Map。这种方式虽然较为灵活,但不如实体类直观。

示例代码

public interface UserMapper {Map<String, Object> getUserById(Integer id);
}<select id="getUserById" resultType="java.util.Map">SELECT id, name, email FROM users WHERE id = #{id}
</select>
3. 自定义结果类型

有时需要返回自定义的结果类型,这时可以使用 resultMap 来定义复杂的映射逻辑。这种方式适用于需要组合多个表数据的情况。

示例代码

<resultMap id="UserResultMap" type="com.example.model.User"><id property="id" column="id"/><result property="name" column="name"/><result property="email" column="email"/>
</resultMap><select id="getUserById" resultMap="UserResultMap">SELECT id, name, email FROM users WHERE id = #{id}
</select>
4. List 集合

当查询结果包含多行数据时,可以使用 List 来接收结果集。这种方式适用于需要处理多条记录的情况。

示例代码

public interface UserMapper {List<User> getAllUsers();
}<select id="getAllUsers" resultType="com.example.model.User">SELECT * FROM users
</select>
5. List<Map<String, Object>>

当查询结果包含多行数据且结果集与实体类不匹配时,可以使用 List<Map<String, Object>> 来接收结果集。这种方式适用于需要灵活处理多条记录的情况。

示例代码

public interface UserMapper {List<Map<String, Object>> getAllUsers();
}<select id="getAllUsers" resultType="java.util.Map">SELECT id, name, email FROM users
</select>
6. 多参数接收

如果查询参数或结果包含了多个独立的参数,可以使用 @Param 注解来标记参数。这种方式适用于需要传递多个参数的情况。

示例代码

public interface UserMapper {List<User> getUsersByNameAndAge(@Param("name") String name, @Param("age") int age);
}<select id="getUsersByNameAndAge" resultType="com.example.model.User">SELECT * FROM users WHERE name = #{name} AND age = #{age}
</select>
7. 自定义对象

可以创建一个自定义对象来接收查询结果,特别是在结果集中包含了一些额外的信息或需要组合不同表的数据时。

示例代码

public class UserWithDetails {private Integer id;private String name;private String department;// getters and setters
}public interface UserMapper {List<UserWithDetails> getUsersWithDepartment();
}<select id="getUsersWithDepartment" resultType="com.example.model.UserWithDetails">SELECT u.id, u.name, d.name AS department FROM users u JOIN departments d ON u.department_id = d.id
</select>
8. 动态结果类型

在某些情况下,可能需要根据运行时的情况动态决定结果类型。这时可以使用 Object 类型来接收结果,然后在应用层进行类型转换或处理。

复杂情况

1. 多表关联查询

当查询涉及到多个表的联接,并且需要将多个表的数据合并到一个对象或多个对象中时,可以使用 resultMap<association><collection> 标签来定义复杂的映射关系。

示例代码
<resultMap id="ComplexUserResultMap" type="com.example.model.ComplexUser"><id property="userId" column="user_id"/><result property="name" column="user_name"/><result property="email" column="user_email"/><association property="department" javaType="com.example.model.Department"><id property="departmentId" column="department_id"/><result property="name" column="department_name"/></association><collection property="orders" ofType="com.example.model.Order"><id property="orderId" column="order_id"/><result property="orderDate" column="order_date"/></collection>
</resultMap><select id="getComplexUser" resultMap="ComplexUserResultMap">SELECT u.user_id, u.user_name, u.user_email,d.department_id, d.department_name,o.order_id, o.order_dateFROM users uJOIN departments d ON u.department_id = d.department_idLEFT JOIN orders o ON u.user_id = o.user_idWHERE u.user_id = #{userId}
</select>
2. 分页查询

在需要处理大量数据并进行分页显示时,可以利用 MyBatis 的 <if> 标签动态构建 SQL 语句来实现分页功能。

示例代码
public interface UserMapper {List<User> getUsersWithPagination(@Param("offset") int offset, @Param("limit") int limit);
}<select id="getUsersWithPagination" resultType="com.example.model.User">SELECT * FROM usersLIMIT #{offset}, #{limit}
</select>
3. 动态 SQL

在 SQL 语句需要根据传入的参数动态改变的情况下,可以使用 <if><choose><when><otherwise><foreach> 等标签来构建动态 SQL 语句。

示例代码
<select id="searchUsers" resultType="com.example.model.User">SELECT * FROM users<where><if test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="age != null">AND age = #{age}</if></where>
</select>
4. 批量更新/插入

当需要批量更新或插入数据时,可以使用 <foreach> 标签来处理列表数据。

示例代码
<update id="batchUpdateStatus">UPDATE users SET status = #{status} WHERE user_id IN<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">#{item}</foreach>
</update>
5. 存储过程

当需要执行复杂的数据库操作,如事务处理或批处理等,可以使用存储过程。MyBatis 支持调用存储过程并将结果映射到 Java 对象。

示例代码
<select id="callStoredProc" statementType="CALLABLE" resultType="com.example.model.User">{ CALL get_user_data(#{userId}) }
</select>
6. 嵌套查询

在某些情况下,需要在一个查询中嵌套另一个查询来获取数据。可以使用 <select> 子标签在 <resultMap> 中定义嵌套查询。

示例代码
<resultMap id="UserWithNestedQueryResultMap" type="com.example.model.User"><id property="userId" column="user_id"/><result property="name" column="user_name"/><association property="department" javaType="com.example.model.Department" select="selectDepartmentById"/>
</resultMap><select id="selectDepartmentById" resultType="com.example.model.Department">SELECT * FROM departments WHERE department_id = #{userId}
</select><select id="getUserWithNestedQuery" resultMap="UserWithNestedQueryResultMap">SELECT u.user_id, u.user_name FROM users u WHERE u.user_id = #{userId}
</select>

###3 7. 自定义类型处理器

当需要处理自定义的数据类型时,可以编写自定义类型处理器来处理特定类型的序列化和反序列化。

示例代码
public class CustomTypeHandler extends BaseTypeHandler<Date> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {ps.setTimestamp(i, new Timestamp(parameter.getTime()));}@Overridepublic Date getNullableResult(ResultSet rs, String columnName) throws SQLException {return new Date(rs.getTimestamp(columnName).getTime());}@Overridepublic Date getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return new Date(cs.getTimestamp(columnIndex).getTime());}
}
8. 事务管理

在处理涉及多个数据库操作的事务时,可以使用 MyBatis 的事务管理功能来确保数据的一致性。

示例代码
@Transactional
public class UserServiceImpl implements UserService {private final UserMapper userMapper;public UserServiceImpl(UserMapper userMapper) {this.userMapper = userMapper;}@Overridepublic void createUser(User user) {userMapper.insertUser(user);// 其他操作...}
}

http://www.mrgr.cn/news/47272.html

相关文章:

  • js代理模式
  • Leetcode 72. 编辑距离 动态规划
  • nvim 打造成可用的IDE(2)
  • ubuntu22.04 gcc,g++从10.5切换到低版本9.5
  • Python的循环
  • CI/CD 流水线
  • 指针揭秘:掌握 Go 语言的内存魔法,让你的编程能力跃升到新高度!
  • 创新设计大师项骅:用卓越才华打造医疗科技新未来
  • 2024小红书高增长赛道洞察报告
  • 前端在vue项目静态文件夹下引入非默认字体并使用
  • 【windows Server 2012】把我的电脑放在桌面
  • (接口测试)day01接口测试理论 http理论 接口测试流程 接口文档解析
  • Printjs 打印表格的时候无法展示样式
  • NodeJs环境安装Vue 认证失效处理
  • LangChain使用Parser控制输出
  • Xinstall品牌揭秘:如何成为App拉新的行业翘楚?
  • c到c++衔接速成
  • 权威认证!宝兰德中间件统一管理平台通过云原生平台中间件管理能力评估
  • RPA技术的定义与原理
  • 深入浅出理解TCP三次握手与四次挥手
  • 5款人声分离免费软件分享,从入门到精通,伴奏提取分分钟拿捏!
  • 新手必备!百度思维导图在内四款必备工具分享
  • 代码随想录 (三)—— 哈希表部分刷题
  • QDockWidget Class
  • 银发产业资讯丨蚂蚁集团、金城药业、百联集团、京东健康布局业务
  • 如何估算业务需要多少短效代理IP的量?