# 字段格式化/填充

使用场景:

  • 字段自动赋值,保存到数据库中,如:更新时间,当前操作人
  • 数据库读到值,格式化后再返回,如:枚举值转成枚举描述

# 自定义填充器

自定义填充类要继承com.gitee.fastmybatis.core.handler.BaseFormatter类。

# 实战:对象-JSON互转

将对象转成json保存到数据库,查询时将json转成对象

表结构:

CREATE TABLE `user_hobby` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`hobby` VARCHAR(1000) NULL DEFAULT '',
	PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB;

实体类:

@Table(name = "user_hobby")
public class UserHobby {
    private Integer id;

    // 定义格式化类
    @Column(formatClass = HobbyFormatter.class)
    // 数据库是varchar类型
    private Hobby hobby;
    
    getter setter

HobbyFormatter类:

/**
 * @author thc
 */
public class HobbyFormatter extends BaseFormatter<Hobby> {

    // 对象转成json字符串保存到数据库
    @Override
    public Object writeFormat(Hobby value) {
        return JSON.toJSONString(value);
    }

    // 从数据库读出,转成对象
    @Override
    public Hobby readFormat(Object value) {
        return JSON.parseObject(String.valueOf(value), Hobby.class);
    }
}

测试用例:

@Test
public void save() {
    UserHobby userHobby = new UserHobby();
    // 自定义类型
    userHobby.setHobby(new Hobby(1, "旅游"));
    userHobbyMapper.save(userHobby);


    userHobby = userHobbyMapper.getById(userHobby.getId());
    Hobby hobby = userHobby.getHobby();
    System.out.println(hobby);
}

# 实战:枚举值转换

CREATE TABLE `person`  (
  `id`       INTEGER PRIMARY KEY auto_increment,
  `gender`  varchar(32) DEFAULT  NULL
);

实体类:

@Table(name = "person")
public class Person {

    private Integer id;

    @Column(formatClass = GenderFormatter.class)
    private GenderEnum gender;

}

GenderFormatter:

public class GenderFormatter extends BaseFormatter<GenderEnum> {

    @Override
    public Object writeFormat(GenderEnum value) {
        return value.name();
    }

    @Override
    public GenderEnum readFormat(Object value) {
        for (GenderEnum genderEnum : GenderEnum.values()) {
            if (Objects.equals(genderEnum.name(), value)) {
                return genderEnum;
            }
        }
        return GenderEnum.OTHER;
    }
}

测试用例:

@Test
public void testGender() {
    Person person = new Person();
    person.setGender(GenderEnum.FEMALE);
    personMapper.save(person);

    Person person1 = personMapper.getById(person.getId());
    System.out.println(person1.getGender().getDescription());
}

对于枚举填充还有更好的实现方式,参考:实体类枚举字段 本质也是填充器一种实现

# 全局填充器设置

假设数据库表里面有两个时间字段gmt_create,gmt_update。

当进行insert操作时gmt_create,gmt_update字段需要更新。当update时,gmt_update字段需要更新。

通常的做法是通过Entity手动设置:

User user = new User();
user.setGmtCreate(new Date());
user.setGmtUpdate(new Date());

因为表设计的时候大部分都有这两个字段,所以对每张表都进行手动设置的话很容易错加、漏加。 fastmybatis提供了两个辅助类DateFillInsert和DateFillUpdate,用来处理添加修改时的时间字段自动填充。配置了这两个类之后,时间字段将会自动设置。

配置方式如下:

FastmybatisConfig config = new FastmybatisConfig();

    config.setFills(Arrays.asList(
			new DateFillInsert()
			,new DateFillUpdate()
			));

在spring的xml中配置如下:

<bean id="sqlSessionFactory"
		class="com.gitee.fastmybatis.core.ext.SqlSessionFactoryBeanExt">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:mybatis/mybatisConfig.xml</value>
		</property>
		<property name="mapperLocations">
			<list>
				<value>classpath:mybatis/mapper/*.xml</value>
			</list>
		</property>
		
		<!-- 以下是附加属性 -->
		
		<!-- dao所在的包名,跟MapperScannerConfigurer的basePackage一致 
			多个用;隔开
		-->
		<property name="basePackage" value="com.myapp.dao" />
		<property name="config">
			<bean class="com.gitee.fastmybatis.core.FastmybatisConfig">
                                <!-- 定义填充器 -->
				<property name="fills">
					<list>
                                        <bean class="com.gitee.fastmybatis.core.support.DateFillInsert"/>
                                        <bean class="com.gitee.fastmybatis.core.support.DateFillUpdate"/>
					</list>
				</property>
			</bean>
		</property>
	</bean>

springboot中定义:

在application.properties中添加:

mybatis.fill.com.gitee.fastmybatis.core.support.DateFillInsert=
mybatis.fill.com.gitee.fastmybatis.core.support.DateFillUpdate=

其中com.gitee.fastmybatis.core.support.DateFillInsert为类的全限定名,等号后面为构造方法参数值,没有可不填

yml可以写成

mybatis:
  fill: {com.gitee.fastmybatis.core.support.DateFillInsert: , com.gitee.fastmybatis.core.support.DateFillUpdate: }

如果要指定字段名,可以写成:

mybatis.fill.com.gitee.fastmybatis.core.support.DateFillInsert=add_time

如果使用LocalDateTime

mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time