zl程序教程

您现在的位置是:首页 >  Java

当前栏目

ognl表达式-Mybatis 系列 5:OGNL 表达式

2023-02-18 16:41:09 时间

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

        select id, name, sex from t_student where id = #{id}

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

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

  说当我们使用 #{id} 类型参数符号的时候,其实就是告诉 创建一个预处理语句参数,通过 JDBC,这样的一个参数在 SQL 中会由一个 "?" 来标识,并传递到一个新的预处理语句中。

  也就是说当我们使用 #{XX} OGNL 表达式的时候, 它会先帮我们生成一条带占位符的 SQL 语句,然后在底层帮我们设置这个参数:ps.setInt(1, id);

  那,OGNL 是什么呢?

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

  是不是有点懵ognl表达式,不知道这是个啥?

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

  举个栗子:

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

  对象关系树结构如下:

  id:10

  name:学生1

  course:

  score:88

  rank:5

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

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

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

  #{name} —> 学生1。

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

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

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

        select id, name, sex from t_student where id = #{id}

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

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

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

  于是,

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

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

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

  也就是说,

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

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

   Student key = new Student();

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

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

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

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

本文共 707 个字数,平均阅读时长 ≈ 2分钟