[原創]Spring Boot + Mybatis 簡易使用指南(二)多參數方法支持 與 Joda DateTime類型支持


前言

今天在開發練習項目時遇到兩個mybatis使用問題

第一個問題是mapper方法參數問題,在參數大於一個時,mybatis不會自動識別參數命名

第二個問題是Pojo中使用Joda DateTime類型的字段,mybatis並不天然支持DateTime,這個問題想必有眾多開發者都遇到過

兩個問題均得到有效解決,在此進行總結記錄


Mapper中針對多參數的方法正確聲明方式

UserMapper interface中包含如下方法定義,用於刪除用戶權限

// 錯誤定義,此為演示
void deleteAuthority(String username, Authority authority);

對應UserMapper.xml中內容如下

<delete id="deleteAuthority">
	DELETE FROM authorities WHERE username = #{username} AND authority = #{authority};
</delete>

執行時出錯,提示無法找到username與authority參數

修復方式,在方法聲明中,參數增加@Param注解,如下

void deleteAuthority(@Param("username") String username, @Param("authority") Authority authority);

支持Joda DateTime

例如 Pojo/Model 類型定義如,ctime表示用戶創建時間,使用joda DateTime類型

public class User {
    private String username;
    private String password;
    private DateTime ctime;
    private List<UserAuthority> authorities;

    ... 各種 get set 方法
}

mapper中addUser方法定義如下,對於ctime字段,Mybatis默認不支持DateTime類型,且沒有提供對應的TypeHander,因此需自行實現,如下的實現必然報錯

錯誤案例
<insert id="addUser" parameterType="user">
	INSERT INTO users(username, password, ctime) VALUES(#{username}, #{password}, #{ctime})
</insert>

自定義實現DateTimeTypeHandler

參考此處外國友人的討論 Mybatis Joda Time Support

參考其源碼 LukeL99/joda-time-mybatis的實現

以下是是本人對DateTimeTypeHandler的實現,前人基礎上稍作重構

public class DateTimeTypeHandler implements TypeHandler<DateTime> {
    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, DateTime dateTime, JdbcType jdbcType)
            throws SQLException {
        if (dateTime != null) {
            preparedStatement.setTimestamp(i, new Timestamp(dateTime.getMillis()));
        } else {
            preparedStatement.setTimestamp(i, null);
        }
    }

    @Override
    public DateTime getResult(ResultSet resultSet, String s) throws SQLException {
        return toDateTime(resultSet.getTimestamp(s));
    }

    @Override
    public DateTime getResult(ResultSet resultSet, int i) throws SQLException {
        return toDateTime(resultSet.getTimestamp(i));
    }

    @Override
    public DateTime getResult(CallableStatement callableStatement, int i) throws SQLException {
        return toDateTime(callableStatement.getTimestamp(i));
    }

    private static DateTime toDateTime(Timestamp timestamp) {
        if (timestamp != null) {
            return new DateTime(timestamp.getTime(), DateTimeZone.UTC);
        } else {
            return null;
        }
    }
}

正確使用方式,在mapper xml中需要指定DateTime類型參數對應的 typeHandler

<insert id="addUser" parameterType="user">
    INSERT INTO users(username, password, ctime) VALUES(#{username}, #{password},
    #{ctime, typeHandler=DateTimeTypeHandler})
</insert>

這里的DateTimeTypeHandler為使用完全限定名(無命名空間),原因是我已經在配置中加好了alias,方法請參考本人上一篇博客,即在構建sqlSessionFactoryBean時,通過setTypeAliases方法指定使用的類型



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM