精华内容
下载资源
问答
  • 简述一下动态sql执行原理? 1.动态SQL的概念 ​ 动态sql是指在进行sql操作的时候,传入的参数对象或者参数值,根据匹配的条件,有可能需要动态的去判断是否为空,循环,拼接等情况; 2.动态Sql的标签大致有以下几...

    1.Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理?

    1.动态SQL的概念

    ​ 动态sql是指在进行sql操作的时候,传入的参数对象或者参数值,根据匹配的条件,有可能需要动态的去判断是否为空,循环,拼接等情况;

    2.动态Sql的标签大致有以下几种
    if 和 where 标签和include标签

    ​ if标签中可以判断传入的值是否符合某种规则,比如是否不为空;

    ​ where标签可以用来做动态拼接查询条件,当和if标签配合的时候,不用显示的声明类似where 1=1这种无用的条件,来达到匹配的时候and会多余的情况;

    ​ include可以把大量重复的代码整理起来,当使用的时候直接include即可,减少重复代码的编写

    <!--动态Sql : where / if-->
    <select id="findUserById"  resultType="com.lagou.pojo.User">
      select <include refid="userInfo"/> from user
      <where>
        <if test="id != null and id != 0">
          AND id = #{id}
        </if>
        <if test="name != null and name != ''">
          AND name = #{name}
        </if>
      </where>
    </select>
    
    choose、when、otherwise 标签

    ​ 类似于 Java 中的 switch、case、default。只有一个条件生效,也就是只执行满足的条件 when,没有满足的条件就执行 otherwise,表示默认条件

    <!--动态Sql: choose、when、otherwise 标签-->
    <select id="findUserById" resultType="com.lagou.pojo.User">
      select * from user
      <where>
        <choose>
          <when test="name != null and name != ''">
            AND name = #{name}
          </when>
          <otherwise>
            AND id = #{id}
          </otherwise>
        </choose>
      </where>
    </select>
    

    foreach 标签

    ​ foreach标签可以把传入的集合对象进行遍历,然后把每一项的内容作为参数传到sql语句中,里面涉及到 item(具体的每一个对象), index(序号), open(开始符), close(结束符), separator(分隔符)

    <!--动态Sql: foreach标签, 批量插入-->
    <insert id="insertBatch" useGeneratedKeys="true" keyProperty="id">
      insert into user (id, name)
      values
      <foreach collection="list" item="user" separator="," >
        (#{user.id}, #{user.name})
      </foreach>
    </insert>
    
    <!--动态Sql: foreach标签, in查询-->
    <select id="dynamicSqlSelectList" resultType="com.lagou.pojo.User">
      SELECT * from user WHERE id in
      <foreach collection="list" item="id" open="(" close=")" separator="," >
        #{id}
      </foreach>
    </select>
    

    map参数

    ​ < map> 标签需要结合MyBatis的参数注解 @Param()来使用,需要告诉Mybatis配置文件中的collection="map"里的map是一个参数

    <!--动态Sql: foreach标签, map参数查询-->
    <select id="findByMap" resultType="com.lagou.pojo.User">
      select * from user WHERE
      <foreach collection="map" index="key" item="value"  separator="=">
        ${key} = #{value}
      </foreach>
    </select>
    

    set标签

    ​ 适用于更新中,当匹配某个条件后,才会对该字段进行更新操作

    <!--动态Sql: set 标签-->
    <update id="updateSet" parameterType="com.lagou.pojo.User">
      update user
      <set>
        <if test="name != null and name != ''">
          name = #{name},
        </if>
      </set>
      where id = #{id}
    </update>
    
    trim标签

    是一个格式化标签,主要有4个参数:

    prefix(前缀)

    prefixOverrides(去掉第一个标记)

    suffix(后缀)

    suffixOverrides(去掉最后一个标记)

    <!--动态Sql: trim 标签-->
    <select id="findUser" resultType="com.lagou.pojo.User">
      select * from user
      <trim prefix="where" suffix="order by id" prefixOverrides="and | or" suffixOverrides=",">
        <if test="name != null and name != ''">
          AND name = #{name}
        </if>
        <if test="id != null">
          AND id = #{id}
        </if>
      </trim>
    </select>
    
    3.动态sql的执行原理
    • 首先在解析xml配置文件的时候,会有一个SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass) 的操作
    • createSqlSource底层使用了XMLScriptBuilder来对xml中的标签进行解析
    • XMLScriptBuilder调用了parseScriptNode()的方法,
    • 在parseScriptNode()的方法中有一个parseDynamicTags()方法,会对nodeHandlers里的标签根据不同的handler来处理不同的标签
    • 然后把DynamicContext结果放回SqlSource中
    • DynamicSqlSource获取BoundSql
    • 在Executor执行的时候,调用DynamicSqlSource的解析方法,并返回解析好的BoundSql,和已经排好序,需要替换的参数
      在这里插入图片描述
      在这里插入图片描述

    ​ 简单的说:就是使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql

    展开全文
  • mybatis可以通过两种方式实现动态SQL,通过XML配置SQL,也可以使用注解的方式配置。两种不同的方式,执行的逻辑都不一样。 1. 通过XML配置实现动态SQL 构建SqlSessionFactory对象时,解析mapper.xml文件,...

    mybatis可以通过两种方式实现动态SQL,通过XML配置SQL,也可以使用注解的方式配置。两种不同的方式,执行的逻辑都不一样。

    1. 通过XML配置实现动态SQL

    构建SqlSessionFactory对象时,解析mapper.xml文件,XMLStatementBuilder.parseStatementNode()根据不同的SQL标签()生成对应的MappedStatement对象,存放在Configuration.mappedStatements集合中。
    然后遍历主标签里所有节点生成对应的SQL子节点对象(SqlNode)。XMLScriptBuilder.parseScriptNode()解析每个标签生成SqlNode对象。

      public SqlSource parseScriptNode() {
        List<SqlNode> contents = parseDynamicTags(context); //context 当前遍历到的sql标签
        MixedSqlNode rootSqlNode = new MixedSqlNode(contents);
        SqlSource sqlSource = null;
        if (isDynamic) {
          sqlSource = new DynamicSqlSource(configuration, rootSqlNode);
        } else {
          sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);
        }
        return sqlSource;
      }
    

    执行Executor.query()方法,根据keyStatementId获取到对应的MappedStatement对象,获取BoundSql对象时。遍历当前SqlSource.rootSqlNode对象。执行SqlNode.apply()方法。把动态sql拼接到DynamicContext.sqlBuilder字段中。

      @Override
      public BoundSql getBoundSql(Object parameterObject) {
        DynamicContext context = new DynamicContext(configuration, parameterObject);
        rootSqlNode.apply(context);
        SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
        Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
        SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
        BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
        for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
          boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
        }
        return boundSql;
      }
    

    使用sqlSourceParser.parse()方法替换sql中 ${}, #{} 为 ?,并且把大括号中的值存放在
    ParameterMappingTokenHandler.parameterMappings集合中。

      //SqlSourceParser.parse()
      public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {
        ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);
        GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
        String sql = parser.parse(originalSql);
        return new StaticSqlSource(configuration, sql, handler.getParameterMappings());
      }
      
      //TokenHandler.handleToken(content)
      @Override
      public String handleToken(String content) {
        parameterMappings.add(buildParameterMapping(content));
        return "?";
      }
    

    2. 通过注解实现动态SQL

    注解实现动态SQL不同的地方在于或许主标签的方式不一样。XML动态SQL可以直接解析等标签的节点。注解需要通过MapperAnnotationBuilder.getSqlSourceFromAnnotations(Method method, Class<?> parameterType, LanguageDriver languageDriver)方法获取SQL语句。然后在执行XMLScriptBuilder.parseScriptNode()解析每个标签生成SqlNode对象。

      private SqlSource getSqlSourceFromAnnotations(Method method, Class<?> parameterType, LanguageDriver languageDriver) {
        try {
          Class<? extends Annotation> sqlAnnotationType = getSqlAnnotationType(method);
          Class<? extends Annotation> sqlProviderAnnotationType = getSqlProviderAnnotationType(method);
          if (sqlAnnotationType != null) {
            if (sqlProviderAnnotationType != null) {
              throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName());
            }
            Annotation sqlAnnotation = method.getAnnotation(sqlAnnotationType);
            final String[] strings = (String[]) sqlAnnotation.getClass().getMethod("value").invoke(sqlAnnotation);
            return buildSqlSourceFromStrings(strings, parameterType, languageDriver);
          } else if (sqlProviderAnnotationType != null) {
            Annotation sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType);
            return new ProviderSqlSource(assistant.getConfiguration(), sqlProviderAnnotation, type, method);
          }
          return null;
        } catch (Exception e) {
          throw new BuilderException("Could not find value method on SQL annotation.  Cause: " + e, e);
        }
      }
    
    展开全文
  • a、Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成...c、其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。 ...

    a、Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。b、Mybatis 提 供 了 9 种 动 态 sql 标 签 : trim|where|set|foreach|if|choose|when|otherwise|bind。
    c、其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

    展开全文
  • Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql执行原理是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。 Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | ...

    Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。

    Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | choose
    | when | otherwise | bind。

    在这里插入图片描述

    展开全文
  • Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql执行原理 是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。 Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | ...
  • Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql执行原理 是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。 Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | ...
  • Mybatis 动态 SQL ,可以让我们在 XML 映射文件内,以 XML 标签的形 式编写动态 SQL ,完成逻辑判断和动态拼接 SQL 的功能。 Mybatis 提供了 9 种动态 SQL 标签:<if/>、<choose/>、<when/>...
  • Sql执行——通过调用SqlSource.getBoundSql得到动态处理过的Sql1. SqlNode.apply处理动态内容2. SqlSourceParser.parse替换#符号为? Demo:动态SQL <select id="countByMap" resultType="int"> select ...
  • Mp动态SQL原理

    2021-05-26 21:17:01
    动态拼接SQL:Java代码实现用户入库操作 userMapper.insert(user); sql拼接过程 insert into user(name,age,sex) values(name的值,age的值,); 上下对应 ,这是交给Mybatis执行即可。 String value = user....
  • 为什么要动态sql语句? 因为动态sql语句能够提供一些比较友好的机制 1、可以使得一些在编译过程中无法获得完整的sql语句,在程序执行阶段动态的获得。 2、支持动态组装 sql语句、动态参数 两种形式 动态sql...
  • 那么我们只声明一个接口,MyBatis是如何帮我们来实现SQL呢,对吗,我们的sql是定义在/resources/mapper/mybatis下。每个单独的xml文件都有一个id和接口里的方法一一对应。这里的对应关系就是mybatis框架帮我们做的...
  • MyBatis执行sql原理

    千次阅读 2016-08-27 11:16:05
    我们知道Mybatis是通过在配置文件中配置sql文,然后对应创建一个接口,通过调用接口的形式来执行sql的。但是接口并没有被实例化怎么就能被调用呢,知道动态代理的朋友肯定会想到是动态代理在背后操控这一切。动态...
  • mybatis作为一款持久层框架,最为主要的职责,当然是执行我们在mapper...(2)动态sql语句,包含了<if | foreach | choose | when | otherwise | where | set | trim>等可以动态拼接sql的标签 本篇博客将...
  • SQL注入原理

    2020-02-27 10:37:12
    当我们访问动态网页时,web服务器会向数据访问层发起SQL查询请求,如果极限验证通过就会执行SQL语句。这种情况下的SQL请求一般不会有问题,但实际情况是很多时候需要结合用户的输入数据动态构建SQL语句,如果用户...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 601
精华内容 240
关键字:

动态sql执行原理