For example, I have a Date datatype in Java and I want to save it to the database as milliseconds from 1970 to the present. How can I do that? Another example is that I have a User class. In the User class, there is an attribute called interest, which is used to describe the User’s hobbies. Its data type is a List set. When I read from the database, I also read such a string, and then automatically convert it to a List set after the success of reading, OK, the above two requirements can be achieved with our traditional database read and write operation, but the workload is slightly larger. There is a slightly more powerful typeHandler in Mybatis for converting data types from databases to Java data types, so let’s use the above two requirements as examples to see how typeHandler can be used. If you are not familiar with Mybatis, it is recommended to read the first few blogs (first know MyBatis/first know MyBatis (ii)/ MyBatis common configuration/MyBatis Mapper configuration rules). The content of this article will be expanded on the basis of the previous blogs. Of course, if you have mybatis foundation, you can look directly down. As a matter of fact, Mybatis already provides a lot of typeHandler for us. The typeHandler provided by the system can meet most of the requirements in our daily development. These two special requirements need to be defined by ourselves. To start with the date conversion, suppose I create a table like this:

public class User { private Long id; private String username; private String password; private Date regTime; // omit getter/setter}Copy the code

Mybatis (2) this JavaBean also has a regTime field, the difference is that the data type here is Date, OK, if I do not do any special processing, directly like mybatis(2) this blogpost introduced to insert data into the database, also can be successfully inserted, but after the insertion success is like this:

@MappedJdbcTypes({JdbcType.VARCHAR})
@MappedTypes({Date.class})
public class MyDateTypeHandler extends BaseTypeHandler<Date> {
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        preparedStatement.setString(i, String.valueOf(date.getTime()));
    }

    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return new Date(resultSet.getLong(s));
    }

    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return new Date(resultSet.getLong(i));
    }

    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        returncallableStatement.getDate(i); }}Copy the code

Here are a few things TO say about this class:

1. @ MappedJdbcTypes definition is JdbcType type, the type definition, freely their must be enumerated type org. Apache. Ibatis. The JdbcType enumeration data type. 2.@MappedTypes defines JavaType data types that describe which Java types can be intercepted. 3. After we enable our custom TypeHandler, all data reads and writes are filtered by this class. In the setNonNullParameter method, we redefine the data to write to the database. 5. In the other three methods we convert data types read from the database.

After customizable typeHandler, we need to do a simple configuration in usermapper. XML. First, we can configure resultMap as described above, as follows:

<resultMap id="userResultMap" type="org.sang.bean.User">
        <result typeHandler="org.sang.db.MyDateTypeHandler" column="regTime" javaType="java.util.Date"
                jdbcType="VARCHAR"
                property="regTime"/>
    </resultMap>
Copy the code

When configuring a resultMap, we specify javaType and jdbcType, and specify the typeHandler to handle. Then we use this resultMap in select:

<select id="getUser" resultMap="userResultMap">
        select * from user4
    </select>
Copy the code

The only disadvantage of this method is that it is only applicable to query operations, that is, the system will enable our custom typeHandler during the query process, and will convert the number of seconds to Date objects, but will not enable our custom typeHandler at insert time. To enable custom typeHandler at insert time, we need to do a simple configuration in the INSERT node as follows:

<insert id="insertUser" parameterType="org.sang.bean.User">
        INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,javaType=Date,jdbcType=VARCHAR,typeHandler=org.sang.db.MyDateTypeHandler})
    </insert>
Copy the code

You can also configure only javaType and jdbcType as follows:

<insert id="insertUser2">
        INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,javaType=Date,jdbcType=VARCHAR})
    </insert>
Copy the code

Or just configure typeHandler:

<insert id="insertUser3">
        INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,typeHandler=org.sang.db.MyDateTypeHandler})
    </insert>
Copy the code

All three effects are the same, converting the Date object to seconds at insertion time. After that, we can change the number of seconds after the Date object is inserted into the database and automatically convert the number of seconds from the database into a Date object. Let’s take a simple test:

    @Test
    public void test2() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setPassword("222222");
            user.setUsername("Bill");
            Date regTime = new Date();
            user.setRegTime(regTime);
            userMapper.insertUser(user);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if(sqlSession ! = null) { sqlSession.close(); }}}Copy the code

Insert result as follows:

Read code:

@Test
    public void test1() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = userMapper.getUser();
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if(sqlSession ! = null) { sqlSession.close(); }}}Copy the code

The read result is as follows:

In addition to defining a resultMap and referencing it in the SELECT node, we can also use the following method: We need to register typeHandler in our Mybatis configuration file. There are two different ways to register typeHandler, one class at a time, as follows:

<typeHandlers>
        <typeHandler handler="org.sang.db.MyDateTypeHandler"/>
    </typeHandlers>
Copy the code

You can also register all TypeHandlers in a package directly, and the system will automatically scan all files in the package at startup, as follows:

<typeHandlers>
        <package name="org.sang.db"/>
    </typeHandlers>
Copy the code

Once this configuration is complete, the number of seconds will automatically be converted to a Date object when we read from the database.

TypeHandler = db; typeHandler = db; db; db; db; db; db; db TypeHandlers are configured in the resultMap and Mybatis configuration file, respectively, and are configured in the INSERT node.

#List collection conversion

If you have learned how to convert a Date to a number of seconds, you can download the Demo at the end of the article. There is a case of converting a List. When the List collection is stored in the database, it looks like this:

OK, that’s our brief introduction to typeHandler.

GitHub address github.com/lenve/JavaE… .

The above.

Pay attention to the public account [Jiangnan little Rain], focus on Spring Boot+ micro service and front and back end separation and other full stack technology, regular video tutorial sharing, after attention to reply to Java, get Songko for you carefully prepared Java dry goods!

Reference materials: the third chapter of MyBatis technology principle and actual combat