zoukankan      html  css  js  c++  java
  • 时间格式字段处理(localtimestamp)、报错:operator does not exist: integer == integer、打开本地sql执行显示、MyBatis中${}和#{}使用场景及区别

    一、localtimestamp - 时间格式字段处理

    // sql
    created_time timestamp(0) default LOCALTIMESTAMP not null
    
    // java
    localtimestamp

      default LOCALTIMESTAMP,可以设置默认时间是插入数据的时间

      我最初设置了上述这样,然后这样插入值:

    <insert id="insert" parameterType="Market">
            insert into cs_market_service(id,
              ...
              created_by,
          created_time
              ...)
            values (nextval('seq_cs_common'),
              ...
              #{createdBy},
              #{createdTime},
          ...)
            <selectKey order="AFTER" keyProperty="id" resultType="Integer">
              SELECT currval('seq_cs_common')
            </selectKey>
        </insert>

      然后一直报错:createdTime不允许为null,但是传入了 null 值,因为我这个 java 里没有传这个值。有2种方式可以解决。

    1、localtimestamp —— 将上面的 #{createdTime} 改为 下面的localtimestamp即可

    <insert id="insert" parameterType="Market">
            insert into cs_market_service(id,
              ...
              created_by,
          created_time
              ...)
            values (nextval('seq_cs_common'),
              ...
              #{createdBy},
              localtimestamp,
          ...)
            <selectKey order="AFTER" keyProperty="id" resultType="Integer">
              SELECT currval('seq_cs_common')
            </selectKey>
        </insert>

    2、第2种方案:取消数据库的 not null 限制

      利用数据库的 default LOCALTIMESTAMP,可以设置默认时间是插入数据的时间。

      然后将上面的 created_time 的设置删掉即可,让数据库去默认填值就行了。推荐这种方式。

    二、报错:operator does not exist: integer == integer

      今天在 Mybatis 里执行时,控制台报错:operator does not exist: integer == integer,起初不知道什么原因,还以为是传值问题。

      后来才发现原来是写法写错了,在 Mybatis 里写了 

    // 错误写法
    ms.status == 0
    
    // 正确写法
    ms.status = 0

      这是代码里的 == 搞习惯了,马虎导致。

    三、如何打开本地 sql 执行的显示

      在本地执行时,有时候 sql 报错,如果不打开调试的话,看不到具体 sql 长啥样,不太好调试,那么如何才能打开调试呢?这样在配置文件加入该 Dao 层的调试即可。

    logging.level.com.enmox.emcs.market.dao: debug

    四、MyBatis 中 ${}和 #{}千万不要乱用

      Mybatis 的Mapper.xml语句中parameterType向SQL语句传参有两种方式:#{}和${}

    1、#{} 是预编译处理

      MyBatis在处理 #{ } 时,它会将sql中的 #{ } 替换为 ?,然后调用 PreparedStatement 的 set 方法来赋值,传入字符串后,会在值两边加上单引号。

      如上面的值 “4,44,514”就会变成“ ‘4,44,514’ ”;

    2、${} 是字符串替换

      在处理字符串替换时,它会将 sql 中的 {} 替换为变量的值,传入的值不会加两边的单引号。

    3、注意:使用${ }会导致sql注入,不利于系统的安全性

      SQL注入:就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。常见的有匿名登录(在登录框输入恶意的字符串)、借助异常获取数据库信息等

      我们经常使用的是 #{},一般解说是因为这种方式可以防止SQL注入,简单的说 #{} 这种方式SQL语句是经过预编译的,它是把 #{} 中间的参数转义成字符串,举个例子:

    select * from student where student_name = #{name}
    
    -- 预编译后,会动态解析成一个参数标记符?:
    select * from student where student_name = ?
    
    -- 而使用${}在动态解析时候,会传入参数字符串
    select * from student where student_name = 'lyrics'

      总结:

      #{} 是编译好 sql 语句再取值

      ${} 是取值后再去编译 SQL 语句

    4、具体用例

    --#{}方式能够很大程度防止sql注入。
    -- $方式无法防止Sql注入。
    -- $方式一般用于传入数据库对象,例如传入表名。
    -- 一般能用#的就别用$。
      举个activiti工作流的例子:
    select * from ${prefix} ACT_HI_PROCINST where PROC_INST_ID_ = #{processInstanceId}

      上面的 ${prefix} 就用来传入表名。

  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/goloving/p/14847446.html
Copyright © 2011-2022 走看看