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

MyBatis注解与XML使用对比

1. MyBatis 注解方式

基本 CRUD 注解

java

@Mapper
public interface UserMapper {// 查询@Select("SELECT * FROM users WHERE id = #{id}")User findById(Long id);// 插入@Insert("INSERT INTO users(name, email, age) VALUES(#{name}, #{email}, #{age})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);// 更新@Update("UPDATE users SET name=#{name}, email=#{email}, age=#{age} WHERE id=#{id}")int update(User user);// 删除@Delete("DELETE FROM users WHERE id = #{id}")int deleteById(Long id);
}

结果映射注解

java

@Mapper
public interface UserMapper {@Results({@Result(property = "id", column = "id"),@Result(property = "userName", column = "username"),@Result(property = "email", column = "email"),@Result(property = "createTime", column = "create_time")})@Select("SELECT * FROM users WHERE id = #{id}")User findUserWithMapping(Long id);// 一对一关联查询@Results({@Result(property = "id", column = "id"),@Result(property = "userName", column = "username"),@Result(property = "profile", column = "user_id", one = @One(select = "findProfileByUserId"))})@Select("SELECT * FROM users WHERE id = #{id}")User findUserWithProfile(Long id);@Select("SELECT * FROM user_profile WHERE user_id = #{userId}")UserProfile findProfileByUserId(Long userId);
}

动态 SQL 注解

java

@Mapper
public interface UserMapper {// 使用脚本实现动态 SQL@Select("<script>" +"SELECT * FROM users " +"WHERE 1=1 " +"<if test='name != null'> AND name LIKE CONCAT('%', #{name}, '%')</if>" +"<if test='email != null'> AND email = #{email}</if>" +"<if test='minAge != null'> AND age &gt;= #{minAge}</if>" +"<if test='maxAge != null'> AND age &lt;= #{maxAge}</if>" +"</script>")List<User> findUsersByCondition(@Param("name") String name,@Param("email") String email,@Param("minAge") Integer minAge,@Param("maxAge") Integer maxAge);// 批量插入@Insert("<script>" +"INSERT INTO users(name, email, age) VALUES " +"<foreach collection='users' item='user' separator=','>" +"(#{user.name}, #{user.email}, #{user.age})" +"</foreach>" +"</script>")int batchInsert(@Param("users") List<User> users);
}

2. MyBatis XML 方式

Mapper 接口

java

@Mapper
public interface UserMapper {User findById(Long id);List<User> findByCondition(UserQuery query);int insert(User user);int update(User user);int deleteById(Long id);int batchInsert(List<User> users);
}

XML 映射文件

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.mapper.UserMapper"><!-- 结果映射 --><resultMap id="UserResultMap" type="com.example.entity.User"><id property="id" column="id" /><result property="userName" column="username" /><result property="email" column="email" /><result property="age" column="age" /><result property="createTime" column="create_time" /><result property="updateTime" column="update_time" /></resultMap><!-- 基础查询 --><select id="findById" parameterType="Long" resultMap="UserResultMap">SELECT * FROM users WHERE id = #{id}</select><!-- 动态 SQL 查询 --><select id="findByCondition" parameterType="UserQuery" resultMap="UserResultMap">SELECT * FROM users<where><if test="userName != null and userName != ''">AND username LIKE CONCAT('%', #{userName}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="minAge != null">AND age &gt;= #{minAge}</if><if test="maxAge != null">AND age &lt;= #{maxAge}</if><if test="createTimeStart != null">AND create_time &gt;= #{createTimeStart}</if><if test="createTimeEnd != null">AND create_time &lt;= #{createTimeEnd}</if></where>ORDER BY create_time DESC</select><!-- 插入 --><insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">INSERT INTO users (username, email, age, create_time)VALUES (#{userName}, #{email}, #{age}, NOW())</insert><!-- 批量插入 --><insert id="batchInsert" parameterType="java.util.List">INSERT INTO users (username, email, age, create_time)VALUES<foreach collection="list" item="user" separator=",">(#{user.userName}, #{user.email}, #{user.age}, NOW())</foreach></insert><!-- 更新 --><update id="update" parameterType="User">UPDATE users<set><if test="userName != null">username = #{userName},</if><if test="email != null">email = #{email},</if><if test="age != null">age = #{age},</if>update_time = NOW()</set>WHERE id = #{id}</update><!-- 删除 --><delete id="deleteById" parameterType="Long">DELETE FROM users WHERE id = #{id}</delete></mapper>

复杂关联查询 XML

xml

<!-- 一对一关联 -->
<resultMap id="UserWithProfileResultMap" type="User" extends="UserResultMap"><association property="profile" javaType="UserProfile"><id property="id" column="profile_id" /><result property="realName" column="real_name" /><result property="phone" column="phone" /><result property="address" column="address" /></association>
</resultMap><select id="findUserWithProfile" parameterType="Long" resultMap="UserWithProfileResultMap">SELECT u.*, p.id as profile_id, p.real_name, p.phone, p.addressFROM users uLEFT JOIN user_profile p ON u.id = p.user_idWHERE u.id = #{id}
</select><!-- 一对多关联 -->
<resultMap id="UserWithOrdersResultMap" type="User" extends="UserResultMap"><collection property="orders" ofType="Order"><id property="id" column="order_id" /><result property="orderNo" column="order_no" /><result property="amount" column="amount" /><result property="createTime" column="order_create_time" /></collection>
</resultMap><select id="findUserWithOrders" parameterType="Long" resultMap="UserWithOrdersResultMap">SELECT u.*,o.id as order_id,o.order_no,o.amount,o.create_time as order_create_timeFROM users uLEFT JOIN orders o ON u.id = o.user_idWHERE u.id = #{id}
</select>

3. 注解 vs XML 对比

注解方式的优缺点

优点:

  • 代码简洁,SQL 与 Java 代码在一起

  • 无需额外的 XML 文件

  • 类型安全,编译时检查

  • 重构友好

缺点:

  • 复杂 SQL 可读性差

  • 动态 SQL 编写麻烦

  • 不支持所有 MyBatis 特性

  • 字符串形式,无语法高亮和提示

XML 方式的优缺点

优点:

  • 复杂 SQL 可读性好

  • 强大的动态 SQL 支持

  • 完整的 MyBatis 特性支持

  • 良好的 IDE 支持(语法高亮、提示)

  • SQL 与 Java 代码分离

缺点:

  • 需要维护额外的 XML 文件

  • 配置相对繁琐

  • 类型不安全,运行时错误

4. 实际应用建议

推荐使用注解的场景

java

// 简单的 CRUD 操作
@Mapper
public interface SimpleUserMapper {@Select("SELECT COUNT(*) FROM users WHERE status = #{status}")long countByStatus(@Param("status") Integer status);@Select("SELECT * FROM users WHERE email = #{email}")User findByEmail(String email);@Update("UPDATE users SET last_login_time = NOW() WHERE id = #{id}")int updateLastLoginTime(Long id);
}

推荐使用 XML 的场景

xml

<!-- 复杂的统计查询 -->
<select id="findUserStatistics" resultType="UserStatistics">SELECT COUNT(*) as totalUsers,COUNT(CASE WHEN age &lt; 18 THEN 1 END) as minorCount,COUNT(CASE WHEN age BETWEEN 18 AND 60 THEN 1 END) as adultCount,COUNT(CASE WHEN age &gt; 60 THEN 1 END) as seniorCount,AVG(age) as averageAge,MAX(create_time) as latestCreateTimeFROM usersWHERE status = 1
</select><!-- 复杂的分页查询 -->
<select id="findUsersWithPagination" parameterType="UserQuery" resultMap="UserResultMap">SELECT * FROM users<where><include refid="userQueryConditions"/></where>ORDER BY <choose><when test="sortField == 'name'">username</when><when test="sortField == 'email'">email</when><when test="sortField == 'createTime'">create_time</when><otherwise>id</otherwise></choose><if test="sortOrder != null and sortOrder == 'desc'">DESC</if>LIMIT #{offset}, #{pageSize}
</select><!-- 可重用的 SQL 片段 -->
<sql id="userQueryConditions"><if test="userName != null and userName != ''">AND username LIKE CONCAT('%', #{userName}, '%')</if><if test="status != null">AND status = #{status}</if>
</sql>

5. 混合使用方式

在实际项目中,可以混合使用注解和 XML:

java

@Mapper
public interface UserMapper {// 简单查询使用注解@Select("SELECT * FROM users WHERE id = #{id}")User findById(Long id);@Select("SELECT * FROM users WHERE email = #{email}")User findByEmail(String email);// 复杂查询使用 XMLList<User> findByComplexCondition(UserQuery query);List<UserStatistics> findUserStatistics();int batchUpdate(List<User> users);
}

6. 配置说明

application.yml 配置

yaml

mybatis:# XML 映射文件位置mapper-locations: classpath:mapper/*.xml# 实体类包路径type-aliases-package: com.example.entity# 开启驼峰命名转换configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl

依赖配置

xml

<dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId>
https://rd.xjyl.gov.cn/upload/1981730209542930432.html
https://rd.xjyl.gov.cn/upload/1981730209110917120.html
https://rd.xjyl.gov.cn/upload/1981730209496793088.html
https://rd.xjyl.gov.cn/upload/1981730209555513344.html
https://rd.xjyl.gov.cn/upload/1981730209865891840.html
https://rd.xjyl.gov.cn/upload/1981730209983332352.html
https://rd.xjyl.gov.cn/upload/1981730210176270336.html
https://rd.xjyl.gov.cn/upload/1981730208825704448.html
https://rd.xjyl.gov.cn/upload/1981730209136082944.html
https://rd.xjyl.gov.cn/upload/1981730210339848192.html
https://rd.xjyl.gov.cn/upload/1981730210306293760.html
https://rd.xjyl.gov.cn/upload/1981730210868330496.html
https://rd.xjyl.gov.cn/upload/1981730210302099456.html
https://rd.xjyl.gov.cn/upload/1981730210809610240.html
https://rd.xjyl.gov.cn/upload/1981730210968993792.html
https://rd.xjyl.gov.cn/upload/1981730211027714048.html
https://rd.xjyl.gov.cn/upload/1981730211388424192.html
https://rd.xjyl.gov.cn/upload/1981730211199680512.html
https://rd.xjyl.gov.cn/upload/1981730211677831168.html
https://rd.xjyl.gov.cn/upload/1981730211791077376.html
https://rd.xjyl.gov.cn/upload/1981730211610722304.html
https://rd.xjyl.gov.cn/upload/1981730211493281792.html
https://rd.xjyl.gov.cn/upload/1981730211518447616.html
https://rd.xjyl.gov.cn/upload/1981730212155981824.html
https://rd.xjyl.gov.cn/upload/1981730211673636864.html
https://rd.xjyl.gov.cn/upload/1981730210721529856.html
https://rd.xjyl.gov.cn/upload/1981730212168564736.html
https://rd.xjyl.gov.cn/upload/1981730212214702080.html
https://rd.xjyl.gov.cn/upload/1981730212713824256.html<version>2.3.1</version></dependency>
</dependencies>

总结

  • 简单场景:推荐使用注解,代码简洁明了

  • 复杂场景:推荐使用 XML,可读性和维护性更好

  • 混合使用:根据实际情况选择最合适的方式

  • 团队规范:统一团队的开发规范,保持一致性

根据项目复杂度和团队习惯,合理选择注解和 XML 的使用比例,可以达到最佳的开发效率和代码质量。

http://www.dtcms.com/a/528966.html

相关文章:

  • Connector
  • 招标网免费查看什么是优化师
  • 商城网站开发哪家好室内装饰设计费收费标准
  • 自动驾驶中的传感器技术70——Navigation(7)
  • 个人接装修活怎样给网站做seo优化
  • php做购物网站wordpress 3.4.2
  • 阮一峰《TypeScript 教程》学习笔记——namespace
  • WEB前端技术基础(第三章:css-网页美化的衣装-上)
  • 大学生网站开发项目计划书范文南宁营销型网站设计
  • C++ 游戏开发示例:简单的贪吃蛇游戏
  • 东莞小学网站建设培训学校网站建设要点
  • 网络安全编程——TCP客户端以及服务端Python实现
  • 基于多尺度特征融合的自注意力度量学习的小样本故障诊断
  • UVa 1227 The Longest Constant Gene
  • datasophon1.2.1 二开
  • 建大网站首页华为商城网站建设
  • 运放的虚短和虚断
  • 建设网站公司兴田德润在哪里谷歌seo外链
  • 是“浴盆曲线”失灵,还是HDD变好了?
  • Tuesday JS,一款可视化小说编辑器
  • 景区旅游网站平台建设方案销售案例网站
  • 【小白笔记】input() 和 print() 这两个函数
  • 营销型网站哪家做的好东莞app
  • 部署PHP8.4(KylinV10SP3、Ubuntu2204、Rocky9.3)
  • 一套配置 双重体验:孪易 IOC 化解 端/流双渲染应用难题
  • jQuery Mobile 实例
  • 免费行情软件网站mnw做教育网站
  • WordPress网站hym地图凯里做网站
  • 东莞做网站优化哪家好网站识别手机电脑代码
  • Java---String类