学习MyBatis必知必会(7)~注解开发、动态SQL

简介: 学习MyBatis必知必会(7)~注解开发、动态SQL

一、MyBatis的注解开发

  • 开发中推荐是使用xml文件配置

1、配置映射关系【使用注解的方式】:

<!-- 全局的配置文件 --> 
<configuration>
   <!-- 2、关联映射文件/ 关联Mapper接口  --> 
  <mappers>
    <!--  <mapper resource="com/shan/hello/mapper/UserMapper.xml"/>-->
    <mapper class="com.shan.hello.mapper.UserMapper"/>
  </mappers>
  </configuration>

2、通过注解,把sql和映射写到Mapper接口:

public interface UserMapper {
  @Insert("insert into t_user (name, salary) values (#{name}, #{salary});")
  @Options(useGeneratedKeys = true,keyProperty = "id")
  void save(User user);
  @Delete("delete from t_user where id = #{id};")
  void delete(Long id);
  @Update("update t_user set name = #{name}, salary = #{salary} where id = #{id};")
  void update(User user);
//  void update(User user, Long id);//错误:myBatis默认只能传递一个参数
  @Select("select id u_id, name as u_name, salary u_salary from t_user where id = #{id}")
  @Results(id="BaseResultMap", value= {
      @Result(column = "u_id",property = "id"),
      @Result(column = "u_name",property = "name"),
      @Result(column = "u_salary",property = "salary")
  })
  User get(Long id);
  @Select("select id u_id, name as u_name, salary u_salary from t_user")
  @ResultMap("BaseResultMap")
  List<User> getListAll();
}

3、测试(这里以测试查询为例):

/* 测试查询 */
  @Test
  public void testGet() throws IOException {
    SqlSession session = MyBatisUtil.getSession();
    UserMapper userMapper = session.getMapper(UserMapper.class);
    User user = userMapper.get(2L);
    System.out.println(user);
    //5、关闭资源
    session.close();
  }


二、动态SQL 【类似JSTL(java标准标签库)语法】

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach
  • 其他(bind,sql,include)

1、if 举例:

<!-- 映射文件 -->
  <select id="select" resultType="Employee">
    select * from employee 
    <if test="minSalary != null">
      where salary >= #{minSalary}
    </if>
  </select>
  • 细节:在xml中 小于符合不能直接输入 < , 会被当做标签的开始标志,需要使用转义符号 &lt;
  • 防止第一个查询条件是null,加上 where 1=1,然后其他查询条件接着and 写。


2、choose (when, otherwise) 举例:

<!-- 映射文件 -->
 <select id="select" resultType="Employee">
      select * from employee where 1=1
    <if test="minSalary != null">
      and salary >= #{minSalary}
    </if>
    <choose>
      <when test="deptId > 0">and deptId = #{deptId}</when>
      <otherwise>and deptId is not null</otherwise>
    </choose>
  </select>


3-1、trim (where, set)- where 举例:

  • 解决sql拼接查询条件时第一个条件为null,而加上 where 1=1,导致不能进行索引查询,影响性能。
  • where 元素:判断查询条件是否有where关键字,若没有,则第一个查询条件之前要插入 where
    若发现查询条件是以and/or开头,则会把第一个查询条件前的and/or 替换成 where
<!-- 映射文件 -->
  <select id="select" resultType="Employee">
      select * from employee 
  <where>
     <if test="minSalary != null">
          and salary >= #{minSalary}
        </if>
      <if test="maxSalary != null">
        and salary &lt;= #{maxSalary}
      </if>
      <choose>
        <when test="deptId > 0">and deptId = #{deptId}</when>
        <otherwise>and deptId is not null</otherwise>
        </choose>
  </where>
  </select>

3-2、trim (where, set)-set 举例:

  • 和where 类似,动态去掉最后一个逗号
<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

3-3、trim (where, set)-trim :

<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
  <!--trim 包含的动态 SQL-->
</trim>

prefix – 在这个字符串之前插入 prefix 属性值。

prefixOverrides – 并且字符串的内容以 prefixOverrides 中的内容开头(可以包含管道符号),那么使用 prefix 属性值替换内容的开头。

suffix – 在这个字符串之后插入 suffix 属性值。

suffixOverrides –并且字符串的内容以 suffixOverrides 中的内容结尾(可以包含管道符号),那么使用 suffix 属性值替换内容的结尾。

  • 使用 where 等价于: 注意:此时 AND 后面有一个空格。
  • 使用 set 等价于:


4、foreach 举例1:

/* Mapper接口 */
void batchDelete(@Param("ids")List<Long> ids);
<!-- 映射文件 -->
 <!-- 
    foreach 元素: collection属性:表示要迭代的集合或数组【的类型,若是通过Parm注解,可以直接写上Map中的key,而不用填写类型】
            open属性:在集合迭代之前,要拼接的符号   close 属性:在集合迭代之后要拼接的符号
            separator属性:迭代的元素之间的分割符号
            item属性:每个被迭代的元素
            index属性:迭代的索引
   -->
  <delete id="batchDelete">
    delete from employee where id in
    <foreach collection="ids" open="(" close=")" separator="," item="id">
      #{id}
    </foreach>
  </delete>

■ foreach 举例2:

/* Mapper接口 */
void batchSave(@Param("emps")List<Employee>emps);
  <!-- 映射文件 -->
  <insert id="batchSave">
    insert into employee (name, sn, salary) values 
    <foreach collection="emps" separator="," item="e">
      (#{e.name}, #{e.sn}, #{e.salary})
    </foreach>
  </insert>


5、其他(bind,sql,include) 举例-高级分页查询:

■ sql,include 的例子:

<!-- 映射文件 -->
<mapper namespace="com.shan.hello.mapper.EmployeeMapper">
  <sql id="base_where">
    <where>
      <if test="keyword != null">
        <!--and name like #{%name%}; 要使用字符串函数concat进行拼接呀 -->
        <!-- and name like concat('%', #{name}, '%') or sn like concat('%', #{sn},'%'); qo查询对象,也没有属性name,sn呀 -->
        and (name like concat('%', #{keyword}, '%') or sn like concat('%', #{keyword}, '%'))
      </if>
      <if test="minSalary != null">
        and salary >= #{minSalary}
      </if>
      <if test="maxSalary != null">
        and salary &lt;= #{maxSalary}
      </if>
      <if test="deptId > 0">
        and deptId = #{deptId}
      </if>
    </where>
  </sql>
  <select id="queryForList" resultType="Employee">
    select id, name, sn, salary from employee
    <include refid="base_where"/>
  </select>
  <select id="queryForCount" resultType="int">
    select count(id) from employee
    <include refid="base_where"/>
  </select>
</mapper>

■ bind(跟concat一样是用于拼接字符串) 的例子:

<if test="keyword != null">
  <!--and name like #{%name%}; 要使用字符串函数concat进行拼接呀 -->
  <!-- and name like concat('%', #{name}, '%') or sn like concat('%', #{sn},'%'); qo查询对象,也没有属性name,sn呀 -->
  <!-- and (name like concat('%', #{keyword}, '%') or sn like concat('%', #{keyword}, '%')) -->
  <bind name="keywordLike" value="'%' + keyword + '%'"/>
      and (name like #{keywordLike} or sn like #{keywordLike})
</if>
目录
相关文章
|
8月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
6月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
551 5
|
8月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
8月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
8月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
230 0
|
10月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
445 2
|
10月前
|
缓存 NoSQL Java
Mybatis学习:Mybatis缓存配置
MyBatis缓存配置包括一级缓存(事务级)、二级缓存(应用级)和三级缓存(如Redis,跨JVM)。一级缓存自动启用,二级缓存需在`mybatis-config.xml`中开启并配置映射文件或注解。集成Redis缓存时,需添加依赖、配置Redis参数并在映射文件中指定缓存类型。适用于查询为主的场景,减少增删改操作,适合单表操作且表间关联较少的业务。
197 6
|
11月前
|
SQL Java 数据库连接
MyBatis-Plus高级用法:最优化持久层开发
MyBatis-Plus 通过简化常见的持久层开发任务,提高了开发效率和代码的可维护性。通过合理使用条件构造器、分页插件、逻辑删除和代码生成器等高级功能,可以进一步优化持久层开发,提升系统性能和稳定性。掌握这些高级用法和最佳实践,有助于开发者构建高效、稳定和可扩展的企业级应用。
648 13
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
12月前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象