@forjinjie (金 傑)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

MyBatis Generator で一部カラムに対してデフォルト値を設定できますか。

解決したいこと

MyBatis Generator(MBG)を利用してMapper と Entityを自動生成しています。
実際に作成されるMapper.xml の一部カラムにデフォルト値を設定したいです。

環境情報

Java 1.8
MyBatis 3
MySQL

テーブル定義

CREATE TABLE `emp` (
  `EMP_ID` varchar(8) NOT NULL,
  `ENAME` varchar(20) NOT NULL,
  `JOB_ID` varchar(3) NOT NULL,
  `MGR` varchar(8) DEFAULT NULL,
  `HIRED_DATE` date NOT NULL,
  `SAL` int(11) NOT NULL,
  `DEPT_ID` varchar(4) NOT NULL,
  `DEL_FLG` varchar(1) NOT NULL,
  `CREATED_AT` timestamp NOT NULL DEFAULT current_timestamp(),
  `UPDATED_AT` timestamp NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`EMP_ID`)
)

実際MBGで作成された Mapper.xml(一部抜粋)

  <insert id="insert" parameterType="com.denny.t5.handson.domain.model.entity.Emp">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into emp (EMP_ID, ENAME, JOB_ID, 
      MGR, HIRED_DATE, SAL, DEPT_ID, 
      DEL_FLG, CREATED_AT, UPDATED_AT
      )
    values (#{empId,jdbcType=VARCHAR}, #{ename,jdbcType=VARCHAR}, #{jobId,jdbcType=VARCHAR}, 
      #{mgr,jdbcType=VARCHAR}, #{hiredDate,jdbcType=DATE}, #{sal,jdbcType=INTEGER}, #{deptId,jdbcType=VARCHAR}, 
      #{delFlg,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}
      )
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.denny.t5.handson.domain.model.entity.Emp">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    update emp
    <set>
      <if test="ename != null">
        ENAME = #{ename,jdbcType=VARCHAR},
      </if>
      <if test="jobId != null">
        JOB_ID = #{jobId,jdbcType=VARCHAR},
      </if>
      <if test="mgr != null">
        MGR = #{mgr,jdbcType=VARCHAR},
      </if>
      <if test="hiredDate != null">
        HIRED_DATE = #{hiredDate,jdbcType=DATE},
      </if>
      <if test="sal != null">
        SAL = #{sal,jdbcType=INTEGER},
      </if>
      <if test="deptId != null">
        DEPT_ID = #{deptId,jdbcType=VARCHAR},
      </if>
      <if test="delFlg != null">
        DEL_FLG = #{delFlg,jdbcType=VARCHAR},
      </if>
      <if test="createdAt != null">
        CREATED_AT = #{createdAt,jdbcType=TIMESTAMP},
      </if>
      <if test="updatedAt != null">
        UPDATED_AT = #{updatedAt,jdbcType=TIMESTAMP},
      </if>
    </set>
    where EMP_ID = #{empId,jdbcType=VARCHAR}
  </update>

やりたいこと

  • INSERT の時、「CREATED_AT」と「UPDATED_AT」は「CURRENT_TIMESTAMP」とする。
  • UPDATE の時、「UPDATED_AT」は「CURRENT_TIMESTAMP」とする。(「CREATED_AT」は更新しない)
  • 条件付きSQL(XXXSelective)の場合、「CREATED_AT」と「UPDATED_AT」には条件を付けない。

作成例)

  <insert id="insert" parameterType="com.denny.t5.handson.domain.model.entity.Emp">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into emp (EMP_ID, ENAME, JOB_ID, 
      MGR, HIRED_DATE, SAL, DEPT_ID, 
      DEL_FLG, CREATED_AT, UPDATED_AT
      )
    values (#{empId,jdbcType=VARCHAR}, #{ename,jdbcType=VARCHAR}, #{jobId,jdbcType=VARCHAR}, 
      #{mgr,jdbcType=VARCHAR}, #{hiredDate,jdbcType=DATE}, #{sal,jdbcType=INTEGER}, #{deptId,jdbcType=VARCHAR}, 
      #{delFlg,jdbcType=VARCHAR}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
      )
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.denny.t5.handson.domain.model.entity.Emp">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    update emp
    <set>
      <if test="ename != null">
        ENAME = #{ename,jdbcType=VARCHAR},
      </if>
      <if test="jobId != null">
        JOB_ID = #{jobId,jdbcType=VARCHAR},
      </if>
      <if test="mgr != null">
        MGR = #{mgr,jdbcType=VARCHAR},
      </if>
      <if test="hiredDate != null">
        HIRED_DATE = #{hiredDate,jdbcType=DATE},
      </if>
      <if test="sal != null">
        SAL = #{sal,jdbcType=INTEGER},
      </if>
      <if test="deptId != null">
        DEPT_ID = #{deptId,jdbcType=VARCHAR},
      </if>
      <if test="delFlg != null">
        DEL_FLG = #{delFlg,jdbcType=VARCHAR},
      </if>
      CREATED_AT = CREATED_AT,
      UPDATED_AT = CURRENT_TIMESTAMP
    </set>
    where EMP_ID = #{empId,jdbcType=VARCHAR}
  </update>

参考リンク

下記リンク先の他にもいろいろ調べてみましたが、上記の要望通りには行けませんでした。
どなたかご存じの方いらっしゃいますか。

MyBatis GeneratorでMapper&Entityを自動生成しよう!
MyBatis GeneratorXML Configuration File Reference

0 likes

1Answer

CREATED_AT に関しては要望と少し違いますが、columnOverride 要素の isGeneratedAlways をつけることで実現できるように思います。
(INSERT 時も UPDATE 時も、値を設定しない。そのため、テーブル定義で指定したデフォルト値が入る。SELECT の条件に付かなくなるかはわかりませんが)

UPDATED_AT については(CREATED_AT も上記の内容で対応できない場合には)、プラグインを作って対応するしかないのではないかと思います。

sqlMapInsertElementGenerated() などいくつかのメソッドで、設定する値を変更するロジックを入れることで UPDATED_AT に CURRENT_TIMESTAMP を入れることができると思います。
(ちょっと大変だと思います)

0Like

Your answer might help someone💌