Mybatis 系列 5:OGNL 表达式

回顾一下,我们之前在 Mybatis 的 mapper.xml 映射文件里写 SQL 查询单个学生记录的时候是这样写的:

<select id="get" parameterType="java.lang.Long" resultType="Student">
    select id, name, sex from t_student where id = #{id}
</select>

其中传进来的参数 #{id} 就是使用的 OGNL 表达式。

Mybatis 官方文档中「XML 映射文件」模块里边,有解析到:

说当我们使用 #{id} 类型参数符号的时候,其实就是告诉 Mybatis 创建一个预处理语句参数,通过 JDBC,这样的一个参数在 SQL 中会由一个 “?” 来标识,并传递到一个新的预处理语句中。
(点击图片放大)
也就是说当我们使用 #{XX} OGNL 表达式的时候, 它会先帮我们生成一条带占位符的 SQL 语句,然后在底层帮我们设置这个参数:ps.setInt(1, id);

那,OGNL 是什么呢?

OGNL 是 Object-Graph Navigation Language 的缩写,对象-图行导航语言,语法为:#{ }。

是不是有点懵,不知道这是个啥?

OGNL 作用是在对象和视图之间做数据的交互,可以存取对象的属性和调用对象的方法,通过表达式可以迭代出整个对象的结构图。

举个栗子:

有一个学生对象 student,属性分别有 id = 10,name = ‘学生1’ 和 课程对象 course,其中 course 对象中属性有:分数 score = 88,排名 rank = 5。

对象关系树结构如下:

student
    id:10
    name:学生1
    course:
        score:88
        rank:5

当上下文(环境)中的对象为 student 的时候,也就是在 Mybatis 中查询时传入的参数对象为 student 的时候:

通过 OGNL 表达式直接获取上下文中对象的属性值,比如:

#{id} —> 10,相对于当前上下文对象.getId(),即 student.getId() 。

#{name} —> 学生1。

#{course.score} —> 88,相当于 student.getCourse().getScore()。

所以,通过 OGNL 表达式,可以迭代出整个对象的结构图。

回到前面说的查询单个学生信息的 SQL:

<select id="get" parameterType="java.lang.Long" resultType="Student">
    select id, name, sex from t_student where id = #{id}
</select>

如果通过 namespace + id 的方式来查询的话,如:

Student student = sqlSession.selectOne("com.mxz.mybatis.mapper.StudentMapper.get", 1L);

可以看到,当前上下文的对象并没有 id 这个属性,传入的参数为 1L(简单类型),但是运行结果是正确的。

于是,

如果当前上下文对象是简单类型对象(基本类型+String),#{X} 表达式直接取出参数值,而和花括号中的名称没有任何关系,即 X 可为任意内容,因为 Mybatis 可以自动判断出来。

如果当前上下文对象是 JavaBean 对象,通过 #{X} 表达式来获取值,X 为属性名称。

如果当前上下文对象是 Map 对象,通过 #{key} 来获取值。

也就是说,

当我们查询单个学生信息,传入的参数为 1L 的时候(简单类型),映射文件中对应 SQL 的 OGNL 表达式不管是写成 #{id},还是 #{ooxx},查询结果是一样的。

而如果我们传入的是一个 student 对象的话,如:

Student key = new Student();
key.setId(1L);
Student student = sqlSession.selectOne("com.mxz.mybatis.mapper.StudentMapper.get"key);

那么我们要取到 id 的值的话,就必须写成 #{id},否则乱写则会报错。

tips:查看官方文档是学习一门新语言最有效的方法。

系列预告:Mybatis 系列 6:MybatisUtil 提取,作用域(scope)和生命周期。

欢迎关注公众号「阿泽学长」

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值