sql 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="status" column="status"/>
    <result property="createTime" column="create_time"/>
  </resultMap>

  <!-- 公共字段:SELECT 字段列表 -->
  <sql id="columns">
    id, username, email, age, status, create_time
  </sql>

  <!-- 公共字段:INSERT 列名 -->
  <sql id="insertColumns">
    username, email, age, status, create_time
  </sql>

  <!-- 公共字段:INSERT 值 -->
  <sql id="insertValues">
    #{username, jdbcType=VARCHAR},
    #{email, jdbcType=VARCHAR},
    #{age, jdbcType=INTEGER},
    #{status, jdbcType=TINYINT},
    #{createTime, jdbcType=TIMESTAMP}
  </sql>

  <!-- 公共字段:UPDATE set 片段 -->
  <sql id="updateSet">
    <set>
      <if test="username != null">
        username = #{username, jdbcType=VARCHAR},
      </if>
      <if test="email != null">
        email = #{email, jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        age = #{age, jdbcType=INTEGER},
      </if>
      <if test="status != null">
        status = #{status, jdbcType=TINYINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime, jdbcType=TIMESTAMP},
      </if>
    </set>
  </sql>

  <!-- 公共条件:WHERE 动态条件(含防转义) -->
  <sql id="whereCondition">
    <where>
      <!-- 使用 &lt; 和 &gt; 转义简单比较 -->
      <if test="status != null">
        AND status = #{status, jdbcType=TINYINT}
      </if>

      <if test="username != null and username != ''">
        AND username LIKE CONCAT('%', #{username, jdbcType=VARCHAR}, '%')
      </if>

      <if test="email != null and email != ''">
        AND email = #{email, jdbcType=VARCHAR}
      </if>

      <!-- 使用 &gt;= 和 &lt;= 转义 -->
      <if test="age != null">
        AND age &gt;= #{age, jdbcType=INTEGER}
      </if>

      <!-- 使用 CDATA 包裹复杂时间范围条件 -->
      <if test="startTime != null or endTime != null">
        AND <![CDATA[
          create_time >= #{startTime, jdbcType=TIMESTAMP}
          AND create_time <= #{endTime, jdbcType=TIMESTAMP}
        ]]>
      </if>

      <!-- 使用 OGNL 逻辑判断 + 转义 -->
      <if test="score != null and score gt 90">
        AND score &gt; 90
      </if>
      <if test="score != null and score le 60">
        AND score &lt;= 60
      </if>
    </where>
  </sql>

  <!-- 公共分页 -->
  <sql id="limitClause">
    <if test="offset != null and limit != null">
      LIMIT #{offset, jdbcType=INTEGER}, #{limit, jdbcType=INTEGER}
    </if>
  </sql>

  <!-- 查询所有用户 -->
  <select id="selectAll" resultMap="UserResultMap">
    SELECT
      <include refid="columns"/>
    FROM user
    WHERE status = #{value, jdbcType=TINYINT}
    ORDER BY id DESC
  </select>

  <!-- 根据 ID 查询 -->
  <select id="selectById" parameterType="java.lang.Long" resultMap="UserResultMap">
    SELECT
      <include refid="columns"/>
    FROM user
    WHERE id = #{id, jdbcType=BIGINT}
  </select>

  <!-- 条件查询 -->
  <select id="selectByCondition" parameterType="java.util.Map" resultMap="UserResultMap">
    SELECT
      <include refid="columns"/>
    FROM user
    <include refid="whereCondition"/>
    ORDER BY create_time DESC
    <include refid="limitClause"/>
  </select>

  <!-- 查询总数 -->
  <select id="countByCondition" parameterType="java.util.Map" resultType="int">
    SELECT COUNT(*)
    FROM user
    <include refid="whereCondition"/>
  </select>

  <!-- 插入用户 -->
  <insert id="insertUser" parameterType="com.example.entity.User">
    INSERT INTO user (
      <include refid="insertColumns"/>
    ) VALUES (
      <include refid="insertValues"/>
    )
  </insert>

  <!-- 更新用户 -->
  <update id="updateUser" parameterType="com.example.entity.User">
    UPDATE user
    <include refid="updateSet"/>
    WHERE id = #{id, jdbcType=BIGINT}
  </update>

  <!-- 删除用户 -->
  <delete id="deleteUserById" parameterType="java.lang.Long">
    DELETE FROM user
    WHERE id = #{id, jdbcType=BIGINT}
  </delete>

</mapper>

<resultMap> 有嵌套对象

java 复制代码
public class User {
    private Long id;
    private String username;
    private Address address; // 嵌套对象
    // getter 和 setter
}

public class Address {
    private String street;
    private String city;
    private String zipCode;
    // getter 和 setter
}
XML 复制代码
<resultMap id="UserWithAddressResultMap" type="com.example.entity.User">
  <id property="id" column="id"/>
  <result property="username" column="username"/>

  <!-- 嵌套对象:来自 addresses 表 -->
  <association property="address" javaType="com.example.entity.Address">
    <id property="id" column="address_id"/>        <!-- address 的主键 -->
    <result property="street" column="street"/>
    <result property="city" column="city"/>
    <result property="zipCode" column="zip_code"/>
  </association>
</resultMap>

<select id="selectUserWithAddress" resultMap="UserWithAddressResultMap">
  SELECT 
    u.id,
    u.username,
    u.address_id,
    a.street,
    a.city,
    a.zip_code
  FROM users u
  LEFT JOIN addresses a ON u.address_id = a.id
  WHERE u.id = #{id}
</select>

不用写<resultMap id="UserResultMap" type="com.example.entity.User">

XML 复制代码
<select id="selectUser" resultType="com.example.entity.User">
  SELECT
    id,
    username,
    email,
    age,
    status,
    create_time AS createTime
  FROM users
</select>

循环sql

XML 复制代码
<select id="selectUsersByIds" resultType="com.example.entity.User">
  SELECT id, username, email, create_time AS createTime
  FROM users
  WHERE id IN
  <foreach item="id" index="index" collection="list" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>
XML 复制代码
<insert id="batchInsert">
  INSERT INTO users (username, email, create_time)
  VALUES
  <foreach collection="list" item="user" separator=",">
    (#{user.username}, #{user.email}, #{user.createTime})
  </foreach>
</insert>

<if>:条件判断

XML 复制代码
<select id="selectUsers" resultType="User">
  SELECT id, username, email, create_time AS createTime
  FROM users
  WHERE 1=1
  <if test="username != null and username != ''">
    AND username LIKE CONCAT('%', #{username}, '%')
  </if>
  <if test="email != null and email != ''">
    AND email = #{email}
  </if>
  <if test="age != null">
    AND age >= #{age}
  </if>
</select>

<where>:智能 WHERE(自动处理 AND/OR

XML 复制代码
<select id="selectUsers" resultType="User">
  SELECT id, username, email, create_time AS createTime
  FROM users
  <where>
    <if test="username != null and username != ''">
      AND username LIKE CONCAT('%', #{username}, '%')
    </if>
    <if test="status == 1">
      AND status = 1
    </if>
    <if test="minAge != null">
      AND age >= #{minAge}
    </if>
  </where>
</select>

<set>:用于 UPDATE,自动处理逗号 (自动去掉最后一个逗号)

XML 复制代码
<update id="updateUser">
  UPDATE users
  <set>
    <if test="username != null">username = #{username},</if>
    <if test="email != null">email = #{email},</if>
    <if test="age != null">age = #{age},</if>
    <if test="status != null">status = #{status}</if>
  </set>
  WHERE id = #{id}
</update>

<choose><when><otherwise>:类似 Java 的 switch

XML 复制代码
<select id="selectUsersByCondition" resultType="User">
  SELECT id, username, email, status
  FROM users
  <where>
    <choose>
      <when test="type == 'admin'">
        AND status = 1 AND username LIKE 'admin%'
      </when>
      <when test="type == 'active'">
        AND status = 1
      </when>
      <otherwise>
        AND status IN (0, 1)
      </otherwise>
    </choose>
  </where>
</select>

补充:mybatis-plus 配置

spring:

datasource:

url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC

username: root

password: root

driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:

mapper-locations: classpath*:mapper/*.xml

type-aliases-package: com.example.entity

configuration:

map-underscore-to-camel-case: true

log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印 SQL

相关推荐
bing_1584 小时前
Spring Boot mybatis-plus 多数据源配置
spring boot·后端·mybatis
hqxstudying2 天前
mybatis过渡到mybatis-plus过程中需要注意的地方
java·tomcat·mybatis
ss2732 天前
手写MyBatis第32弹-设计模式实战:Builder模式在MyBatis框架中的精妙应用
设计模式·mybatis·建造者模式
hqxstudying2 天前
MyBatis 和 MyBatis-Plus对比
java·数据库·mysql·mybatis
ss2732 天前
手写MyBatis第31弹-用工厂模式重构MyBatis的SqlSession创建过程
spring boot·后端·mybatis
毅航3 天前
从原理到实践,讲透 MyBatis 内部池化思想的核心逻辑
后端·面试·mybatis
寒士obj4 天前
MyBatis-Plus基础篇详解
java·mybatis
陈三一4 天前
MyBatis OGNL 表达式避坑指南
后端·mybatis
funfan05175 天前
在IDEA中DEBUG调试时查看MyBatis-Plus动态生成的SQL语句
sql·intellij-idea·mybatis