创建自己的TypeHandler

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用typeHandler将获取的值以合适的方式转换成 Java 类型。Mybatis提供了大量的typeHandler实现上述操作,如,使用DoubleTypeHandler将Double以及double与NUMERIC或者DOUBLE进行转换。这些TypeHandler能够满足我们日常开发中的大量场景。但是,对于一些特殊的情况,需要我们自己进行编写TypeHander进行相关处理。

为此,Mybatis为我们提供了BaseTypeHandler抽象类以及TypeHandler接口,供我们实现自己的TypeHandler。在这里,实现自己的TypeHandler用于将User直接存储与数据库字段中,并取出后,并将其转换成User对象。

User对象的代码:

public class User {

    private Integer u_id;
    private String u_name;
    private String u_password;
    private String u_sex;
    private Date u_bornDate;
    private boolean u_locked;
    private Double u_salary;
    
    public User() {
        
    }
    
    public User(Integer id) {
        this.u_id = id;
    }

    public User(Integer u_id, String u_name, String u_password, String u_sex,
            Date u_bornDate, boolean u_locked, Double u_salary) {
        super();
        this.u_id = u_id;
        this.u_name = u_name;
        this.u_password = u_password;
        this.u_sex = u_sex;
        this.u_bornDate = u_bornDate;
        this.u_locked = u_locked;
        this.u_salary = u_salary;
    }

    public User(String u_name, String u_password, String u_sex,
            Date u_bornDate, boolean u_locked, Double u_salary) {
        super();
        this.u_name = u_name;
        this.u_password = u_password;
        this.u_sex = u_sex;
        this.u_bornDate = u_bornDate;
        this.u_locked = u_locked;
        this.u_salary = u_salary;
    }

    public Integer getU_id() {
        return u_id;
    }
       
    //省略getter与setter方法
}

包含有User的实体类对象(UserTypeHandlerModel):

public class UserTypeHandlerModel {

    private Integer uthm_id;
    private String uthm_name;
    private String uthm_describe;
    private User uthm_user;
    private Date uthm_createTime;
    
    public UserTypeHandlerModel() {
        
    }
    
    public UserTypeHandlerModel(String uthm_name, String uthm_describe,
            User uthm_user, Date uthm_createTime) {
        super();
        this.uthm_name = uthm_name;
        this.uthm_describe = uthm_describe;
        this.uthm_user = uthm_user;
        this.uthm_createTime = uthm_createTime;
    }

    public UserTypeHandlerModel(String uthm_name, String uthm_describe,
            User uthm_user) {
        super();
        this.uthm_name = uthm_name;
        this.uthm_describe = uthm_describe;
        this.uthm_user = uthm_user;
    }

    public UserTypeHandlerModel(Integer uthm_id, String uthm_name,
            String uthm_describe, User uthm_user, Date uthm_createTime) {
        super();
        this.uthm_id = uthm_id;
        this.uthm_name = uthm_name;
        this.uthm_describe = uthm_describe;
        this.uthm_user = uthm_user;
        this.uthm_createTime = uthm_createTime;
    }
//省略相关getter与setter方法

}

自定义的TypeHandler,NewUserTypeHandler

public class NewUserTypeHandler extends BaseTypeHandler<User> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
            User parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, changeUserToString(parameter));
    }

    @Override
    public User getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        User user = new User();
        try {
            user = changeStringToUser(rs.getString(columnName));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return user;
    }

    @Override
    public User getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        User user = new User();
        
        try {
            user = changeStringToUser(rs.getString(columnIndex));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return user;
    }

    @Override
    public User getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        User user = new User();
        
        try {
            user = changeStringToUser(cs.getString(columnIndex));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return user;
    }

    /**
     * 将格式化后的User对象,转化成User对象。
     * @param value:
     * @param dateFormat
     * @param regex
     * @return
     * @throws ParseException
     */
    private User changeStringToUser(String value , String dateFormat , String regex) throws ParseException {
        if(StringUtils.isEmpty(value)) {
            return null;
        }
        
        String[] result = value.split(regex , -1);
        if(result.length != 8) {
            throw new UserFormatException("提供的格式不正确,请提供正确的格式");
        }
        
        User user = new User();
        user.setU_id(StringUtils.isEmpty(result[0]) ? null : Integer.parseInt(result[0]));
        user.setU_name(StringUtils.isEmpty(result[1]) ? null : result[1]);
        user.setU_password(StringUtils.isEmpty(result[2]) ? null : result[2]);
        user.setU_sex(StringUtils.isEmpty(result[3]) ? null : result[3]);
        user.setU_bornDate(StringUtils.isEmpty(result[4]) ? null : new SimpleDateFormat(dateFormat).parse(result[4]));
        user.setU_locked(StringUtils.isEmpty(result[5]) ? null : Boolean.parseBoolean(result[5]));
        user.setU_salary(StringUtils.isEmpty(result[6]) ? null : Double.parseDouble(result[6]));
        
        return user;
    }
    
    /**
     * 将String类型的字符串转化成User对象。(精简版本)
     * @param value
     * @return
     * @throws ParseException
     */
    private User changeStringToUser(String value) throws ParseException {
        return changeStringToUser(value, "yyyy/MM/dd hh:mm:ss", ";");
    }
    
    /**
     * 将User对象,转换成String类型的字符串
     * @param user:需要进行转换的User对象
     * @param dateFormat:日期转换格式
     * @param regex:字符串分隔符
     * @return
     */
    private String changeUserToString(User user , String dateFormat , String regex) {
        StringBuffer result = new StringBuffer();
        
        System.out.println("NewUserTypeHandler class , changeUserToString function , user information :" + user);
        result.append((user.getU_id() != null ? Integer.toString(user.getU_id()) : "") + regex);
        result.append((user.getU_name() != null ? user.getU_name() : "") + regex);
        result.append((user.getU_password() != null ? user.getU_password() : "") + regex);
        result.append((user.getU_sex() != null ? user.getU_sex() : "") + regex);
        result.append((user.getU_bornDate() != null ? new SimpleDateFormat(dateFormat).format(user.getU_bornDate()) : "") + regex);
        result.append(Boolean.toString(user.isU_locked()) + regex);
        result.append((user.getU_salary() != null ? Double.toString(user.getU_salary()) : "") + regex);
        
        return result.toString();
    }
    
    /**
     * 将User对象转换成String类型的对象。(精简版本)
     * @param user
     * @return
     */
    private String changeUserToString(User user) {
        return changeUserToString(user, "yyyy/MM/dd hh:mm:ss", ";");
    }
}

UserTypeHandlerModel的mapper文件:

<mapper namespace="com.quelongjiang.mybatis.dao.UserTypeHandlerDao">
    
    <resultMap type="com.quelongjiang.mybatis.model.UserTypeHandlerModel" id="uthmEntity">
        <result property="uthm_id" column="uthm_id"/>
        <result property="uthm_name" column="uthm_name"/>
        <result property="uthm_describe" column="uthm_describe"/>
        <result property="uthm_user" column="uthm_user" 
                typeHandler="com.quelongjiang.springSecurity.mybatis.typeHandler.NewUserTypeHandler"  />
        <result property="uthm_createTime" column="uthm_createTime"/>
    </resultMap>
    
    <insert id="saveOneRecord">
        insert into sys_usertypehandlermodel(uthm_id , uthm_name , uthm_describe , uthm_user , uthm_createTime)
                                    values(#{uthm_id} , 
                                           #{uthm_name} , 
                                           #{uthm_describe} ,
                                           #{uthm_user , typeHandler="com.quelongjiang.springSecurity.mybatis.typeHandler.NewUserTypeHandler"} , 
                                           #{uthm_createTime})
    </insert>
    
    <insert id="saveMoreRecord">
        insert into sys_usertypehandlermodel(uthm_id , uthm_name , uthm_describe , uthm_user , uthm_createTime) values
        <foreach collection="list" item="item" separator=",">
            (#{item.uthm_id} , 
             #{item.uthm_name} , 
             #{item.uthm_describe} , 
             #{item.uthm_user , typeHandler=com.quelongjiang.springSecurity.mybatis.typeHandler.NewUserTypeHandler} , 
             #{item.uthm_createTime})
        </foreach>
    </insert>
    
    <!-- 省略其他的update、delete和select -->
</beans>

好了,到此整个TypeHandler就完成了。但是,有些地方需要注意:

1、若在mybatis-config.xml配置文件中,注册了这个TypeHandler,那么,TypeHandler就会成为User对象与VARCHAR之后的typehandler。当然了,这在UserTypeHandlerModel实体类的操作,是没有问题的,但是,若只想操作User对象,那么,就有问题了。因为,此时该TypeHandler就成了User对象与VARCHAR的默认解析器。其实,这个问题也好解决,不再mybatis-config.xml中注册该typeHandler,只在相关的mapper文件中进行注册使用就可以了。这样,就不会影响其他操作。

2、在insert语句中,使用typeHandler指定解析器时,不要添加引号,否则,会出现异常。

好了,到此,自定义的TypeHandler就操作完成了。

posted on 2017-05-02 20:28  longfei2013  阅读(279)  评论(0)    收藏  举报

导航