时间格式字段处理(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} 就用来传入表名。

posted @   古兰精  阅读(775)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2020-06-03 实现粘性布局position:sticky
2018-06-03 IDEA是如何导入项目的,及启动导入项目遇到的问题:无法加载主类的一连串问题
2018-06-03 创建springBoot项目及启动报错遇到的问题解决:Failed to configure a DataSource: 'url' attribute is not specified and no embedd
点击右上角即可分享
微信分享提示