MyBatis参数处理和查询语句专题


一、MyBatis参数处理

1.单个简单类型参数

  • 简单类型包括:
    • byte short int long float double char
    • Byte Short Integer Long Float Double Character
    • java.lang.String
    • java.util.Date
    • java.sql.Date
  • 通过测试得知,简单类型对于 mybatis 来说都是可以⾃动类型识别的:
    • 也就是说对于 mybatis 来说,它是可以⾃动推断出 ps.setXxxx() ⽅法的。ps.setString() 还是 ps.setInt()。它可以⾃动推断。
    • 其实SQL映射⽂件中的配置⽐较完整的写法是:
      <select id="selectByName" resultType="student" parameterType="java.lang.String">
      	select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR}
      </select>
      
  • 其中 sql 语句中的 javaType,jdbcType,以及 select 标签中的 parameterType 属性,都是⽤来帮助 mybatis 进⾏类型确定的。不过这些配置多数是可以省略的。因为 mybatis 它有强⼤的⾃动类型推断机制。
    • javaType:可以省略
    • jdbcType:可以省略
    • parameterType:可以省略
    • 如果参数只有⼀个的话,#{} ⾥⾯的内容就随便写了。对于 ${} 来说,注意加单引号。
  • Mybatis 内置的一些别名:参考官方手册 ===> https://mybatis.net.cn/configuration.html#typeAliases

在这里插入图片描述
在这里插入图片描述

2.单个Map参数

  • 这种⽅式是⼿动封装 Map 集合,将每个条件以 key 和 value 的形式存放到集合中。然后在使⽤的时候通过 #{map集合的key} 来取值。

3.单个实体类参数

  • 这⾥需要注意的是:#{} ⾥⾯写的是属性名字。这个属性名其本质上是:set/get ⽅法名去掉 set/get 之后的名字。

4.多参数

<select id="selectByNameAndSex" resultType="student">
	<!--select * from t_student where name = #{name} and sex = #{sex}-->
	<!--select * from t_student where name = #{arg0} and sex = #{arg1}-->
	<!--select * from t_student where name = #{param1} and sex = #{param2}-->
	select * from t_student where name = #{arg0} and sex = #{param2}
</select>
  • arg0 是第⼀个参数、param1是第⼀个参数、arg1 是第⼆个参数、param2是第⼆个参数
  • 实现原理:实际上在mybatis底层会创建⼀个map集合,以arg0/param1为key,以⽅法上的参数为value,例如以下代码:
    Map<String,Object> map = new HashMap<>();
    map.put("arg0", name);
    map.put("arg1", sex);
    map.put("param1", name);
    map.put("param2", sex);
    // 所以可以这样取值:#{arg0} #{arg1} #{param1} #{param2}
    // 其本质就是#{map集合的key}
    
  • 注意:使⽤ mybatis3.4.2 之前的版本时:要⽤#{0}和#{1}这种形式。

5.@Param注解(命名参数)

  • 可以不⽤ arg0 arg1 param1 param2,这个 map 集合的 key 我们可以使⽤ @Param 注解自定义。这样可以增强可读性。
  • 核⼼:@Param(“这⾥填写的其实就是map集合的key”)。
  • 现在如果不使用@Param注解,map中的key是形式参数名。(原来的arg0 arg1 param1 param2方式也仍然保留着的。)
<!-- ArticleMapper.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.gdb.mybatis.param.mapper.ArticleMapper">

    <select id="selectForUserIdAndTitle" resultType="Article">
        select * from article where user_id = #{userId} and title = #{title}
    </select>
</mapper>
//ArticleMapper接口 
package com.gdb.mybatis.param.mapper;

import com.gdb.mybatis.param.pojo.Article;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface ArticleMapper {
    List<Article> selectForUserIdAndTitle(@Param("userId") Integer userId, @Param("title") String title);
}
//测试代码
package com.gdb.mybatis.param.test;

import com.gdb.mybatis.param.mapper.ArticleMapper;
import com.gdb.mybatis.param.pojo.Article;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.util.List;

public class TestParam {
    @Test
    public void testParamAnnotation() throws Exception{
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        List<Article> articles = mapper.selectForUserIdAndTitle(9874, "JavaWeb");
        System.out.println(articles);
        sqlSession.close();
    }
}

在这里插入图片描述

  • 这里可以看到有部分属性为 null,这个问题可以看第二部分 MyBatis查询语句专题。

二、MyBatis查询语句专题

1.结果映射

(1)as 给列起别名

    <select id="selectArticleForId" resultType="Article">
        select id,
               user_id     as userId,
               title,
               summary,
               read_count  as readCount,
               create_time as createTime,
               update_time as updateTime
        from article
        where id = #{id};
    </select>

(2)使⽤resultMap进⾏结果映射

<!--
 resultMap:
 id:这个结果映射的标识,作为select标签的resultMap属性的值。
 type:结果集要映射的类。可以使⽤别名。
-->
<resultMap id="ArticleResultMap" type="Article">
	<!--对象的唯⼀标识,官⽅解释是:为了提⾼mybatis的性能。建议写上。-->
	<id property="id" column="id"/>
	<result property="userId" column="user_id"/>
	<!--当属性名和数据库列名⼀致时,可以省略。但建议都写上。-->
	<!--javaType⽤来指定属性类型。jdbcType⽤来指定列类型。⼀般可以省略。-->
	<result property="title" column="title" javaType="string" jdbcType="VARCHAR"/>
	<result property="summary" column="summary"/>
	<result property="readCount" column="read_count"/>
	<result property="createTime" column="create_time"/>
	<result property="updateTime" column="update_time"/>
</resultMap>
<!--resultMap属性的值必须和resultMap标签中id属性值⼀致。-->
<select id="selectAllByResultMap" resultMap="ArticleResultMap">
	select * from article
</select>

(3)是否开启驼峰命名⾃动映射(配置settings)

  • 使⽤这种⽅式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
  • Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。
  • SQL命名规范:全部⼩写,单词之间采⽤下划线分割。
<!--放在properties标签后⾯-->
<settings>
	<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

2.返回实体类

  • 查询结果是⼀条的话可以使⽤List集合接收。

  • 启用驼峰命名方式,完成数据库表字段到Java类属性的映射。

    <select id="SelectArticleForIdRetPojo" resultType="Article">
        select * from article where id = #{id}
    </select>
    
  • ArticleMapper.java

    • 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
    Article SelectArticleForIdRetPojo(Integer id);
    
  • 测试程序

    @Test
    public void SelectArticleForIdRetPojo() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        Article article = mapper.SelectArticleForIdRetPojo(1);
        System.out.println(article);
        sqlSession.close();
    }
    

3.返回List

  • 当查询的记录条数是多条的时候,必须使⽤集合接收。如果使⽤单个实体类接收会出现异常。

4.返回Map

  • 当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收。字段名做key,字段值做value。
  • 查询如果可以保证只有⼀条数据,则返回⼀个Map集合即可。(如果返回结果不是一条记录,使用一个 Map 集合来接收会出现异常。)

5.返回List

  • 查询结果条数⼤于等于1条数据,则可以返回⼀个存储 Map 集合的 List 集合 List<Map>。

  • ArticleMapper.xml

    <select id="selectAllRetListMap" resultType="map">
        select * from article
    </select>
    
  • ArticleMapper.java

    • 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
    List<Map<String,Object>> selectAllRetListMap();
    
  • 测试程序

    @Test
    public void selectAllRetListMap() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        List<Map<String, Object>> list = mapper.selectAllRetListMap();
        System.out.println(list);
        sqlSession.close();
    }
    

6. 返回Map<String,Map>

  • 拿 Article 的 id 做 key,以后取出对应的 Map 集合时更⽅便。

  • ArticleMapper.xml

    <select id="selectAllArticleRetBigMap" resultType="map">
        select * from article
    </select>
    
  • ArticleMapper.java

    • 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
    @MapKey("id")
    Map<String, Map<String, String>> selectAllArticleRetBigMap();
    
  • 测试程序

    @Test
    public void selectAllArticleRetBigMap() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        Map<String, Map<String, String>> stringMapMap = mapper.selectAllArticleRetBigMap();
        System.out.println(stringMapMap);
        sqlSession.close();
    }
    

7.返回总记录条数

  • ArticleMapper.xml

    <select id="selectForRowCount" resultType="_int">
        select count(*) from article;
    </select>
    
  • ArticleMapper.java

    public interface ArticleMapper {
        int selectForRowCount();
    }
    
  • 测试程序

    @Test
    public void testQueryAllRow() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        int count = mapper.selectForRowCount();
        System.out.println("count = " + count);
        sqlSession.close();
    }
    
  • 结果展示
    在这里插入图片描述


  • 33
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝945

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值