[慕课电商项目] 01.对 mybatis 逆向工程生成的 xml 的改进

一、insert 语句的总结

1. 插入的时候,如果插入了自增的id

  • id值如果在该表中不存在,并且其他字段没有错误的话,mysql 会插入该行数据。
    • 如果插入的 id 的值大于表自增的值,那么表自增的值就更新到这个id值。例如,表的自增主键在被手动插入后的最大的 id 值为100,那么下一个自动插入的 id 就递增到了101。
  • id值在该表中已经存在了,那么就会报异常org.springframework.dao.DuplicateKeyException

2. 对返回值的处理

  我们应该事先初始化一个值为0的 int 变量,然后对执行 insert 的方法进行 try-catch 异常捕获,根据是否捕获到异常来决定接下来怎么做。

3. 代码演示:

    @Test
    public void insertSelectiveWithoutTime() throws Exception {
        //RandomUser.getNormalUser() 没有设置createTime, updateTime 
        //它们都为null
        User user = RandomUser.getNormalUser();

        //故意设置一个重复的 自增id,那么会捕获到异常,count 将为 0
        //user.setId(90);
        System.out.println(user);

        int count = 0;
        try {
            count = userMapper.insertSelectiveWithoutTime(user);
        }catch (Exception e) {
            System.out.println("出现了异常: " + e);
        }

        System.out.println("count: " + count);
    }

二、对 mybatis 逆向工程生成的 xml 的改进

1.问题缘由:

   电商项目中数据库的每一张表都包含创建时间和更新时间字段,为什么所有的表都需要这两个字段呢?
  • 好处:不仅可以简单的记录下操作时间,而且这两个字段也可以用于以后数据分析中。
  • 必要性:
    • 创建时间:大部分数据在创建了之后就不会更新了。
    • 更新时间:如果数据需要大量的更新,那么我们也不可能记录每一次的更新时间,最好的方式是记录最后一次的更新时间。

2.思考点:

(1)创建时间和更新时间的值有必要交给 java 代码来做吗?
(2)让数据库去做这个是不是更适合,更方便些?

3.对 mybatis 逆向工程生成的映射文件的改进

(1) 分析

   我们只需要修改 xml 中的 insert 和 update 语句即可。insert 语句插入的是一条全新的记录,我们要让数据库给出更新时间,创建时间的值。而对于 update 语句,我们只管最后的更新时间即可,创建时间已经在 insert 的时候插入到数据库中了。所以,数据库要给出更新时间的值,还要删掉原来 update 语句中的 create_time 的相关片段。在这里使用 mysql 的 now() 来生成时间。

   注意: 在 mybatis 生成的 xml 中有一种 Selective 的实现。我们在 service 代码中也经常会调用它。这里的 insert 语句会包含(列名1,列名2,... ,列名n)values (值1,值2,... ,值n)。它根据传来的 pojo 的属性值是否为 null 来决定是否要更改数据库对应的那一列。

/* 列中包含的字段:(列名1,列名2,... ,列名n) */
<trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      ...
</trim>
/* values 中包含的字段:values (值1,值2,... ,值n) */
<trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
       ...
</trim>

   我们要想,每次 insert 都一定要插入创建时间和更新时间的,而不是根据传来的 pojo 的 createTime ,updateTime 的值是否为null 来决定插入。所以,我们要在 Selective 类型的实现中,不让这两个属性 Selective ,而是直接确定好。
   (createTime 和 updateTime 内心OS:这是不是有一种钦定的感觉?)

(2) 具体代码

(注意对应的列与值的位置,在更改的时候很容易搞混)

  1. 复杂的 insert

insert:

<insert id="insertWithoutTime" parameterType="top.kongk.mmall.pojo.User">
    insert into mmall_user (id, username, password,email, phone, question, answer, role,
      create_time, update_time)
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},
      #{phone,jdbcType=VARCHAR}, #{question,jdbcType=VARCHAR}, #{answer,jdbcType=VARCHAR}, #{role,jdbcType=INTEGER},
      now(), now())
  /*这两个 now() 对应 create_time 和 update_time*/
  </insert>

insertSelective :

<insert id="insertSelectiveWithoutTime" parameterType="top.kongk.mmall.pojo.User" >
    insert into mmall_user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="email != null" >
        email,
      </if>
      <if test="phone != null" >
        phone,
      </if>
      <if test="question != null" >
        question,
      </if>
      <if test="answer != null" >
        answer,
      </if>
      <if test="role != null" >
        role,
      </if>
        /*被钦定的 createTime 和 updateTime 的列名*/
        create_time, update_time,
    </trim>

    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        #{email,jdbcType=VARCHAR},
      </if>
      <if test="phone != null" >
        #{phone,jdbcType=VARCHAR},
      </if>
      <if test="question != null" >
        #{question,jdbcType=VARCHAR},
      </if>
      <if test="answer != null" >
        #{answer,jdbcType=VARCHAR},
      </if>
      <if test="role != null" >
        #{role,jdbcType=INTEGER},
      </if>
        /*被钦定的 createTime 和 updateTime 的值*/
        now(), now(),
    </trim>
  </insert>

2.简单的 update

updateByPrimaryKey :

<update id="updateByPrimaryKey" parameterType="top.kongk.mmall.pojo.User" >
    update mmall_user
    set username = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      email = #{email,jdbcType=VARCHAR},
      phone = #{phone,jdbcType=VARCHAR},
      question = #{question,jdbcType=VARCHAR},
      answer = #{answer,jdbcType=VARCHAR},
      role = #{role,jdbcType=INTEGER},
      /*被注释的 create_time = */
      update_time = now()
    where id = #{id,jdbcType=INTEGER}
  </update>

updateByPrimaryKeySelective :

<update id="updateByPrimaryKeySelective" parameterType="top.kongk.mmall.pojo.User" >
    update mmall_user
    <set >
      <if test="username != null" >
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="email != null" >
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="phone != null" >
        phone = #{phone,jdbcType=VARCHAR},
      </if>
      <if test="question != null" >
        question = #{question,jdbcType=VARCHAR},
      </if>
      <if test="answer != null" >
        answer = #{answer,jdbcType=VARCHAR},
      </if>
      <if test="role != null" >
        role = #{role,jdbcType=INTEGER},
      </if>
      <!-- 被注释掉的 createTime 
        <if test="createTime != null" >
          create_time = #{createTime,jdbcType=TIMESTAMP},
        </if>
      -->
      <if test="updateTime != null" >
        update_time = now(),
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容