IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 映射接口的参数与返回值 -> 正文阅读

[Java知识库]映射接口的参数与返回值

一、映射接口的参数与映射文件的取值

参数可以是简单的数据类型,JavaBean、Map、List、Array。

?

参数名称解析规则:

ParamNameResolver 是一个参数名解析器,用来按顺序列出方法中的虚参,并对实参进行名称标注。

ParamNameResolver 类主要的方法有两个:构造方法 ParamNameResolver 和getNamedParams方法。

构造方法 ParamNameResolver能够将目标方法的参数名称依次列举出来。在列举的过程中,如果某个参数存在@Param注解,则会用注解的 value值替换参数名。

同时会为每个参数名对应一个param1,param2 …,并将实参值赋值给param1,param2 …。

MyBatis在3.4.2版本之前,传递参数支持使用#{0} - #{n};在3.4.2及之后版本,没有使用@param注解的情况下,传递参数需要使用#{arg0}-#{argn}或者#{param1}-#{paramn},按照顺序拿

(因此你可以通过参数名称 | @param的value值 | paramx来取到值)

?

1、简单类型

接口定义:

Customers selectById(Integer id);

?
在映射文件中支持以下几种方式取值:

1.1 #{value}取值

特殊的在只有单参数时,可以通过#{value}直接取值:

<select id="selectById" resultType="customers">
       select * from customers where id = #{value};
</select>

?

1.2 通过变量名取值

无论是单参数还是多参数都可以,前提是你没有使用@Param注解

<select id="selectById" resultType="customers">
       select * from customers where id = #{id};
</select>

?

1.3 使用@Param注解

无论是单参数还是多参数都可以,在此时你无法通过变量名取到值

Customers selectById(@Param("customerId") Integer id);
<select id="selectById" resultType="customers">
       select * from customers where id = #{customerId};
</select>

?

1.4 使用paramx|argx

<select id="selectById" resultType="customers">
       select * from customers where id = #{param1}; 
</select>

?

2、JavaBean

对于JavaBean我们需要取到其属性值,此时就需要用到OGNL表达式了。

OGNL表达式:

它是 apache 提供的一种表达式语言,全称是: Object Graphic Navigation Language 对象图导航语言 。

它是按照一定的语法格式来获取数据的。 语法格式就是使用 #{对象.对象}的方式。

#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。

如果对象里面再包含对象,则可以使用#{xxx.xxx.xx}取值

但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user. 而直接写 username。

?
接口:

public class Customers {
    private Integer id;
    private String name;
    private String email;
    private String birth;
}

----------------
    
List<Customers> selectByQuery(Customers customers);

?

2.1 #{value}取值

和简单数据类型一样只有单参数时才可以使用,同时由于只有单参数因此可以省略value。(单个参数时,可不写value:#{value.name} 等价于 #{name})

<select id="selectByQuery" resultType="customers">
       select * from customers where name = #{name} and email = #{email}
</select>

?

2.2 变量名取值

和简单类型时一样的,范围也一样(单个参数时,可不写变量名:#{customers.name} 等价于 #{name})

<select id="selectByQuery" resultType="customers">
       select * from customers where name = #{name} and email = #{email}
</select>

?

2.4 使用@Param取值

和简单类型时一样的,范围也一样

List<Customers> selectByQuery(@Param("customer") Customers customers);
<select id="selectByQuery" resultType="customers">
       select * from customers where name = #{customer.name} and email = #{customer.email}
</select>

?

2.4 使用paramx|argx

和简单数据类型一样,范围也一样

<select id="selectByQuery" resultType="customers">
       select * from customers where name = #{param1.name} and email = #{param1.email}
</select>

?

3、Map

对于Map既可以使用foreach遍历使用,也可以不遍历使用

?

3.1 变量名、paramx|argx取值

3.1.1 单参数
List<Customers> selCustomersByMap(Map<String,String> map);

-------------
try(SqlSession sqlSession = factory.openSession()){
    ICustomersMapper mapper = sqlSession.getMapper(ICustomersMapper.class);
    HashMap<String, String> map = new HashMap<>();
    map.put("id","1");
    List<Customers> customers = mapper.selCustomersByMap(map);
    for(Customers e : customers)
        System.out.println(e);
}    

单参数情况下,它的取值方式类似于bean对象的取值,直接通过#{key值}来获取,但无法进行foreach遍历。
?
直接获取:

<select id="selCustomersByMap" resultType="com.bihai.pojo.Customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
    	id = #{id}
    </where>
</select>

?
foreach方式:

获取不到map,会报错,报错如下:

Caused by: org.apache.ibatis.builder.BuilderException: The expression ‘map’ evaluated to a null value.

?

3.1.2 多参数
List<Customers> selCustomerByMapAndId(Map<String,String> maps, String id);

----------------------
    
try(SqlSession sqlSession = factory.openSession()){
    ICustomersMapper mapper = sqlSession.getMapper(ICustomersMapper.class);
    HashMap<String, String> map = new HashMap<>();
    map.put("name","汪峰");
    List<Customers> customers = mapper.selCustomerByMapAndId(map,"1");
    for(Customers e : customers)
        System.out.println(e);
}    

对于多参数,无法通过#{id}、#{maps.xxx}获取;但可以通过paramx (从1开始)、argx (从0开始) 获取;对于map中的元素可以通过**#{paramx.key名称}**来获取。

?
直接使用:

<select id="selCustomerByMapAndId" resultType="customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
        id = #{param2}
        <if test="param1 != null">
            AND name = #{param1.name}
        </if>
    </where>
</select>

?
foreach方式:

<select id="selCustomerByMapAndId" resultType="customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
    	id = #{param2}
        <if test="param1 != null">
            <foreach open="AND " collection="param1" separator="AND " index="key" item="value">
            	#{key} = #{value}
        	</foreach>
        </if>
     </where>
</select>

?

3.2 @param取值

?

3.2.1 单、多参数

直接使用:

List<Customers> selCustomerByMapAndId(@Param("map") Map<String,String> maps, @Param("id") String id);
<select id="selCustomerByMapAndId" resultType="customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
        id = #{id}
        <if test="map != null">
            AND name = #{map.name}
        </if>
    </where>
</select>

?
foreach使用:

错误方式:通过#{key}获取到的key不对,带了''号,导致查不到数据;但上面通过paramx的方式遍历的key又是对的,无语了

<select id="selCustomerByMapAndId" resultType="customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
        <foreach open="AND " collection="map" separator="AND " index="key" item="value">
            #{key} = #{value}
        </foreach>
    </where>
</select>

?
正确方式:

<select id="selCustomerByMapAndId" resultType="customers">
    SELECT id, name, email,birth
    FROM `customers`
    <where>
        <foreach open="AND " collection="map" separator="AND " index="key" item="value">
            ${key} = #{value}
        </foreach>
    </where>
</select>

?

4、List与Array

对于List与Array用在foreach中,取值的方式可以通过变量名、paramx、@Param取值,并且单参数情况下可以通过list(仅仅针对List)、array(仅仅针对Array)取值。

?

4.1 变量名、@param、paramx取值

List<User> selectById(List<String> ids, String name);
<select id="selectById" parameterType="string" resultType="user">
    SELECT * FROM user WHERE
    <foreach collection="ids" item="e">
    	<if test = "e == '00001'">
        	id = #{e};
		</if>
    </foreach>
</select> 

?

4.2 通过list、array取值

<select id="selectById" parameterType="string" resultType="user">
    SELECT * FROM user WHERE
    <foreach collection="list" item="e">
    	<if test = "e == '00001'">
        	id = #{e};
		</if>
    </foreach>
</select> 

类似的Array也是一样的

?

二、接口的返回值

对于MyBatis支持的类型,可以在MapperMethod的execute方法中查看,如下:

/**
   * 执行映射接口中的方法
   * @param sqlSession sqlSession接口的实例,通过它可以进行数据库的操作
   * @param args 执行接口方法时传入的参数
   * @return 数据库操作结果
   */
  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    switch (command.getType()) { // 根据SQL语句类型,执行不同操作
      case INSERT: { // 如果是插入语句
        // 将参数顺序与实参对应好
        Object param = method.convertArgsToSqlCommandParam(args);
        // 执行操作并返回结果
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: { // 如果是更新语句
        // 将参数顺序与实参对应好
        Object param = method.convertArgsToSqlCommandParam(args);
        // 执行操作并返回结果
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: { // 如果是删除语句MappedStatement
        // 将参数顺序与实参对应好
        Object param = method.convertArgsToSqlCommandParam(args);
        // 执行操作并返回结果
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT: // 如果是查询语句
        if (method.returnsVoid() && method.hasResultHandler()) { // 方法返回值为void,且有结果处理器
          // 使用结果处理器执行查询
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) { // 多条结果查询
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) { // Map结果查询
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) { // 游标类型结果查询
          result = executeForCursor(sqlSession, args);
        } else { // 单条结果查询
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
          if (method.returnsOptional()
              && (result == null || !method.getReturnType().equals(result.getClass()))) {
            result = Optional.ofNullable(result);
          }
        }
        break;
      case FLUSH: // 清空缓存语句
        result = sqlSession.flushStatements();
        break;
      default: // 未知语句类型,抛出异常
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      // 查询结果为null,但返回类型为基本类型。因此返回变量无法接收查询结果,抛出异常。
      throw new BindingException("Mapper method '" + command.getName()
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-30 18:48:07  更:2022-01-30 18:49:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:57:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码