在项目中使用mybatis做为持久层框架,mysql数据库。项目上线前,DBA要求我们将每张数据库表中的字段都设置默认值和not null。之前项目中有一些insert语句是将表中所有字段都列出来,然后把它做为一个通用的插入语句来使用。举个简单的例子:假如一张数据库表blog中有如下几个字段:id,title,content,author,除id外,每个字段都设置了默认值Empty String(空字符串),写的一个insert语句是这样的:

  1. <insert id="addOneBlog" parameterType="main.Blog">
  2. insert into blog(title,author,content)
  3. values(#{title},#{author},#{content})
  4. </insert>

原以为有这么一个insert语句就万事大吉了,我们以为,以后做插入操作的时候,无论有多少个字段,都使用这一个insert语句,如果字段没有值,就会被赋值为mysql字段的默认值。。。

但事实证明,根本不是这样的。

当我们只给title字段赋值,然后执行一个insert语句时,mybatis马上报出这样的异常:

  1. Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'content' cannot be null

显然,所有字段规定了not null,看来按照这种insert的方法,未赋值的字段并没有赋值为mysql的默认值。

那么如果把数据库字段的not null限制去掉呢?

再次执行刚才的insert操作,这次没有抛出异常,但查看数据库后,我们发现,新插入的表记录中,没有赋值的字段仍然不是mysql的默认值,而是null值。

所以,按照上面所谓的通用insert语句,是无法让未赋值字段的值变为mysql默认值的。这种insert语句无法做到通用。具体解决方案

上一篇简单介绍了一个mysql的问题:字段默认值在使用全字段insert的时候,可能并不会生效。在使用mybatis时,虽然需要自己写sql,但相比原始jdbc的方式来说,有一个很好的优势——动态sql。针对前一篇文章提出的问题,mybatis的动态sql可以很好地解决这个问题。

1.问题分析

上一篇文章中描述的问题,是由于我们误将一个包含所有字段的insert语句做为通用的insert。那么显而易见,解决此问题的方法是,我们需要针对不同的业务需求,严格按照需要插入的字段来写不同的sql,不需要插入的字段,在insert语句中不能够出现。举例上一篇的blog表例子说明,假如我们有一个插入操作,只需要在插入时给author赋值,那么sql可以这么写:

  1. <insert id="addOneBlog" parameterType="main.Blog">
  2. insert into blog(author)
  3. values (#{author})
  4. </insert>

这个方法虽然奏效,但在实际项目开发中,为了开发效率的需要,我们仍然希望能够有一个通用的insert语句,供所有涉及单表插入操作的业务调用。刚才说过,mybatis有一个非常强大的特色功能:动态sql,使用动态sql即可解决此问题。

2.<sql>、<include>、<trim>标签简介

mybatis的动态sql功能包含了很多实用的标签:<sql>标签表示一个sql片段,使用此标签不仅可以重用很多sql代码,而且使sql语句更清晰;定义好<sql>标签后,在调用它的地方使用<include>标签,即可将定义好的sql片段拼接进来;<trim>标签可以在标签体内的sql片段首尾任意添加或覆盖字符。

3.问题解决

先上代码:

  1. <sql id="blogColumns">
  2. <trim suffixOverrides=",">
  3. <if test="title != null">title,</if>
  4. <if test="author != null">author,</if>
  5. <if test="content != null">content</if>
  6. </trim>
  7. </sql>
  8. <sql id="blogValues">
  9. <trim suffixOverrides=",">
  10. <if test="title != null">#{title},</if>
  11. <if test="author != null">#{author},</if>
  12. <if test="content != null">#{content}</if>
  13. </trim>
  14. </sql>
  15. <insert id="addOneBlog" parameterType="Blog">
  16. insert into blog(<include refid="blogColumns"/>)
  17. values (<include refid="blogValues"/>)
  18. </insert>

对于blog表,上面这段代码即可实现我们想要的insert重用,不管插入的字段有多少,我们都可以使用它来实现所有单表insert操作。上面代码中,先定义两个sql片段,分别代表insert语句中的字段列表和参数列表,并使用<trim>标签去除片段首尾可能出现的多余的“,”字符。最后写一个简单的insert,并将上面的sql片段拼接进来。

4.结尾

关于mybatis的动态sql,它有很多强大的,可高度重用sql的功能。大家如果对一些标签的作用不太清楚,请期待我后续的博文。作为一个半自动的持久层框架,我们虽然需要自己写sql语句,但mybatis的动态sql能够最大限度地减少我们的代码量,这也是在ORM横行的JavaEE世界里,mybatis能够独树一帜的原因。

 

mysql字段默认值不生效的问题解决(上)的更多相关文章

  1. MySQL字段默认值设置详解

    前言: 在 MySQL 中,我们可以为表字段设置默认值,在表中插入一条新记录时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值.关于默认值,有些知识还是需要了解的,本篇文章我们一起来学习下字 ...

  2. Mysql 修改字段默认值

    环境:MySQL 5.7.13 问题描述:建表的时候,users_info表的role_id字段没有默认值,后期发现注册的时候,需要提供给用户一个默认角色,也就是给role_id字段一个默认值. 当前 ...

  3. SQL Server2000导出数据时包含主键、字段默认值、描述等信息

    时经常用SQL Server2000自带的导出数据向导将数据从一台数据库服务器导出到另一台数据库服务器: 结果数据导出了,但表的主键.字段默认值.描述等信息却未能导出,一直没想出什么方法,今天又尝试了 ...

  4. SQL修改字段默认值、获取字段默认值

    一.SQL修改字段默认值 alter table 表名 drop constraint 约束名字 说明:删除表的字段的原有约束 alter table 表名 add constraint 约束名字 D ...

  5. Sqlserver添加加字段、删除字段、修改字段类型、修改字段名、修改字段默认值

    参考:https://www.cnblogs.com/pangpanghuan/p/6432331.html 初始化表: --.添加字段 --1.1.为null alter table DataTab ...

  6. Odoo14 设置Binary字段默认值

    1 # Odoo 中的附件也就是Binary字段都是经过特殊处理的 2 # 首先是上传的时候会进行base64编码后再上传到服务器 3 # 服务器进行压缩存放在odoo文件仓库中 4 # 每个odoo ...

  7. 关于Java读取mysql中date类型字段默认值'0000-00-00'的问题

    今天在做项目过程中,查询一个表中数据时总碰到这个问题:      java.sql.SQLException:Value '0000-00-00' can not be represented as ...

  8. mysql多个时间戳字段默认值问题

    项目使用mysql数据库,在设计表时某张表有多个字段设计的类型是timestamp 但没有给默认值,在执行sql时报 timestamp Invalid default value for 'xxx' ...

  9. mysql删除、修改字段默认值

    alter table表名alter column字段名drop default; (若本身存在默认值,则先删除) alter table 表名 alter column 字段名 set defaul ...

随机推荐

  1. 双重ScrollView,RecyclerView联动实例

    最近收到一个需求,如图,大家一看,不就是一个简单的表格吗,RecyclerView就搞定了 我一开始也是这么想的,但是当我继续听下去 需求是左边党支部栏目只能上下滑动,之后联动右边下方表格一起上下滑动 ...

  2. 『Python进阶』专题汇总

    基础知识 Python3内置函数 『Python』库安装 『流畅的Python』第1~4章_数据结构.编码 『Python』基础数据结构常见使用方法 『Python CoolBook』数据结构和算法_ ...

  3. [转]关于Megatops BinCalc RPN计算器的说明

    最近收到几个好心人发来的邮件,指出我的BinCalc存在低级BUG,即1+1算出来不等于2--鉴于存在这种误解的人之多,俺不得不爬出来澄清一下--我的Megatops BinCalc当中的计算器是RP ...

  4. 983. Minimum Cost For Tickets

    网址:https://leetcode.com/problems/minimum-cost-for-tickets/ 参考:https://leetcode.com/problems/minimum- ...

  5. Varnish http缓存服务器

    http://blog.51cto.com/hexiaoshuai/1909183 https://jefferywang.gitbooks.io/varnish_4_1_doc_zh/content ...

  6. IPFS扫盲

    第二届深圳区块链技术与应用大会暨展览会,深圳区块链存储与IPFS技术应用大会暨展览会于2019年4月9日在深圳会展中心6号馆举行.那么这个IPFS是什么?和区块链有什么关系?有什么用?又怎么用呢?接下 ...

  7. Introduction and use of Cookie and Session(Cookie&Session的介绍和使用)

    一.Cookie 1.什么是Cookie? Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据. 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来 ...

  8. 【cogs247】售票系统【线段树】

    售票系统 输入文件:railway.in 输出文件:railway.out 时间限制:1 s 内存限制:128 MB [问题描述] 某次列车途经C个城市,城市编号依次为1到C,列车上共有S个座位,铁路 ...

  9. MVP技术沙龙上海站-SQL BI

    5月,微软爱好者们齐聚一起,在上海港汇中心,参加<MVP技术沙龙上海站-SQL BI>系列讲座,下面是现场图片.  

  10. MySQL—增删改查,分组,连表,limit,union,alter,排序,去重

    MySQL增删改查 在表格的增删改查中,查的内容是最多的,包括group by ,join,limit,union,alter,排序都是服务于查的 #sql语句数据行操作补充 #增加: #insert ...