• 学习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>
    

  • 相关阅读:
    线程 定时任务 实现思路
    Days Floating In ShenZhen(1)
    由于未能找到具有自动生成的控件来引发回发事件,导致发生错误
    在ASP.NET中使用AJAX.NET (转译自MSDN)(二)
    Every Time I Wake up I want sleep more
    漂泊在深圳的日子2
    512今日历程
    流金岁月
    对自己的思考
    关于绑定自动生成的下拉式菜单的错误
  • 原文地址:https://www.cnblogs.com/shan333/p/15864333.html
Copyright © 2020-2023  润新知