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} 就用来传入表名。

  • 相关阅读:
    #define、const、typedef的区别
    《软件调试的艺术》学习笔记——GDB使用技巧摘要
    作为员工与老板的竞争力区别
    部分经典IT书籍
    对找工作功不可没——评《深入理解计算机系统》
    前端UI框架小汇总
    Visual Studio 2017 序列号 Key 激活码 VS2017 注册码
    Wampserver 2.5 多站点配置方法
    ThinkPHP3.1快速入门(9)变量输出
    ThinkPHP3.1快速入门(8)视图
  • 原文地址:https://www.cnblogs.com/goloving/p/14847446.html
Copyright © 2011-2022 走看看