mybatis-plus之自动映射字段(typeHandler)的注意点及说明

yizhihongxing

下面是详细的攻略,包括自动映射字段和typeHandler的注意点及示例说明。

1. 什么是mybatis-plus的自动映射字段

Mybatis-Plus中的自动映射字段指的是ORM框架通过对象和表结构的映射关系,在数据操作时自动完成对象属性和表字段之间的映射。即当我们使用Mybatis-Plus进行数据库操作时,我们不需要手动编写SQL语句,只需要编写Java代码就可以进行CRUD操作。

2. 注意点

在使用Mybatis-Plus中的自动映射字段时需要注意以下几点:

2.1 数据库字段名和Java实体类属性名的映射规则

Mybatis-Plus默认的映射规则为驼峰式和下划线式的互相转换。例如,一个字段名为user_name,在Java实体类中的对应属性名为userName。可以通过在实体类的属性上使用注解来指定字段名和属性名的映射关系:

@TableName("t_user")
public class User implements Serializable {
    private static final long serialVersionUID = -5593099211726283450L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @TableField("user_name")
    private String userName;

    private String password;

    @TableField(exist = false)
    private String email;

    // ... getter and setter
}

2.2 关于类型转换

当Java实体类属性的类型和数据库表中字段类型不对应时,需要使用typeHandler来进行类型转换。

2.3 自动映射有可能会造成列名冲突

当表中有两列名称相同时,Mybatis-Plus的自动映射会抛出org.apache.ibatis.executor.ExecutorException:TooManyResultsException..异常。这种情况下需要手动处理。

3. 关于typeHandler

typeHandler主要用于数据类型的转换,Mybatis-Plus中扩展了很多类型的typeHandler,这些typeHandler可以实现自定义的类型转换。使用typeHandler可以大大简化代码和提高开发效率,但需要注意一些细节。

Mybatis-Plus提供了默认的typeHandler,如下所示:

默认类型处理器(typeHandler) 对应的JavaType
BooleanTypeHandler Boolean
ByteTypeHandler Byte
DateTypeHandler Date
DoubleTypeHandler Double
FloatTypeHandler Float
IntegerTypeHandler Integer
LongTypeHandler Long
ShortTypeHandler Short
StringTypeHandler String
BlobTypeHandler Blob
ClobTypeHandler Clob

如果我们需要使用自定义类型转换器,需要实现相应的类型转换器和这个类型转换器对应的Java类型,使用方式如下所示:

3.1 自定义typeHandler

@MappedTypes({MyEnum.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class MyEnumTypeHandler extends BaseTypeHandler<MyEnum> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, MyEnum parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.getValue());
    }

    @Override
    public MyEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        return StringUtils.isEmpty(value) ? null : MyEnum.getEnum(value);
    }

    @Override
    public MyEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String value = rs.getString(columnIndex);
        return StringUtils.isEmpty(value) ? null : MyEnum.getEnum(value);
    }

    @Override
    public MyEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        return StringUtils.isEmpty(value) ? null : MyEnum.getEnum(value);
    }
}

3.2 注册typeHandlers

使用自定义的typeHandler需要在Mybatis配置文件中配置,在Mybatis-Plus中可以使用注解@MybatisPlusConfigurer通过一个Java配置类来配置typeHandler:

@Configuration
@MapperScan("com.example.demo.mapper*")
@MybatisPlusConfigurer
public class MybatisPlusConfig {

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return new MybatisPlusCustomizers();
    }

    static class MybatisPlusCustomizers implements ConfigurationCustomizer {
        @Override
        public void customize(Configuration configuration) {
            configuration.setDefaultEnumTypeHandler(MyEnumTypeHandler.class);
        }
    }
}

4. 示例说明

下面以一个实际的例子来说明如何使用自动映射字段和typeHandler:

4.1 数据库表

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `gender` varchar(2) DEFAULT NULL,
  `phone` varchar(15) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

4.2 Java实体类

@Data
@NoArgsConstructor
@Table("user")
@ApiModel(description = "用户信息")
public class User implements Serializable {

    public enum Gender {
        MALE("男"),
        FEMALE("女");

        private final String desc;
        Gender(String desc) {
            this.desc = desc;
        }
        public String getDesc() {
            return desc;
        }
    }

    private static final long serialVersionUID = -5593099211726283450L;

    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "用户ID", position = 1)
    private Long id;

    @TableField(value = "user_name", el = "userName")
    @NotNull
    @Length(max = 255)
    @ApiModelProperty(value = "用户名", position = 2)
    private String userName;

    @TableField
    @ApiModelProperty(value = "密码", position = 3)
    private String password;

    @TableField(value = "email", el = "email")
    @ApiModelProperty(value = "邮箱", position = 4)
    private String email;

    @TableField(value = "gender", typeHandler = MyEnumTypeHandler.class)
    @ApiModelProperty(value = "性别", position = 5)
    private Gender gender;

    @TableField(value = "phone", el = "phone")
    @ApiModelProperty(value = "手机号", position = 6)
    private String phone;

}

4.3 Mybatis-Plus操作数据库

@SpringBootTest
@RunWith(SpringRunner.class)
public class MybatisPlusTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testAutoMapping() {

        // INSERT
        User user = new User();
        user.setUserName("张三");
        user.setPassword("123");
        user.setEmail("zhangsan@qq.com");
        user.setGender(User.Gender.MALE);
        user.setPhone("12345678910");
        int count = userMapper.insert(user);
        Assert.assertEquals(1, count);

        // SELECT
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id", user.getId());
        User result = userMapper.selectOne(wrapper);
        Assert.assertEquals(user.getUserName(), result.getUserName());
        Assert.assertEquals(user.getPassword(), result.getPassword());
        Assert.assertEquals(user.getEmail(), result.getEmail());
        Assert.assertEquals(user.getGender(), result.getGender());
        Assert.assertEquals(user.getPhone(), result.getPhone());

        // UPDATE
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setUserName("李四");
        int updateCount = userMapper.updateById(updateUser);
        Assert.assertEquals(1, updateCount);

        User updatedUser = userMapper.selectById(user.getId());
        Assert.assertEquals(updateUser.getUserName(), updatedUser.getUserName());
        Assert.assertEquals(user.getPassword(), updatedUser.getPassword());
        Assert.assertEquals(user.getEmail(), updatedUser.getEmail());
        Assert.assertEquals(user.getGender(), updatedUser.getGender());
        Assert.assertEquals(user.getPhone(), updatedUser.getPhone());

        // DELETE
        int deleteCount = userMapper.deleteById(user.getId());
        Assert.assertEquals(1, deleteCount);
    }
}

通过上面的例子可以看出,使用自动映射字段和自定义typeHandler可以大大简化代码和提高开发效率。同时需要注意上面提到的注意点。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis-plus之自动映射字段(typeHandler)的注意点及说明 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • vue使用自定义指令实现拖拽

    下面我将详细介绍如何使用自定义指令来实现拖拽功能。 什么是Vue自定义指令 Vue自定义指令本质上是一个指令函数,它接收两个参数:被绑定的元素和一个对象。在对象中你可以设置指令的各种选项和事件钩子。 实现拖拽的步骤 下面是实现拖拽功能的步骤: 1. 创建自定义指令 我们需要创建一个自定义指令,来绑定拖拽事件。在Vue中自定义指令可以使用Vue.directi…

    other 2023年6月25日
    00
  • Java线程的调度与优先级详解

    Java线程的调度与优先级详解 什么是线程调度? 线程调度是指操作系统按照一定的策略分配CPU时间给不同的线程,以实现多线程并发执行的机制。Java中的线程调度由操作系统和JVM共同参与。 线程优先级 在Java中,每个线程都有一个优先级,用来指定该线程在竞争CPU资源时的优先级,优先级越高,获取CPU资源的几率越大。Java中的线程优先级范围是1-10,默…

    other 2023年6月28日
    00
  • vue中封装axios并实现api接口的统一管理

    下面我来为你详细讲解“Vue中封装axios并实现API接口的统一管理”。 1. 为什么需要封装axios并实现API接口的统一管理 在使用axios请求数据时,我们通常需要在每个组件中都引入axios,并且在每个组件中都配置请求拦截器和响应拦截器,这样不仅重复代码多,而且容易出错,难以维护。同时,如果需要修改或新增一个接口,也需要在每个组件中进行修改,非常…

    other 2023年6月25日
    00
  • 31. Ubuntu15.04系统中如何启用、禁用客人会话

    Ubuntu15.04系统中如何启用、禁用客人会话的完整攻略 本文将为您提供Ubuntu15.04系统中如何启用、禁用客人会话的完整攻略,包括介绍、方法和两个示例说明。 介绍 Ubuntu是一款自由和开放源代码的Linux操作系统,广泛应用于个人电脑和服务器。Ubuntu15.04系统中提供了客人会话功能,可以让用户在不登录系统的情况下使用计算机。本文将介绍…

    other 2023年5月6日
    00
  • curlget接口header赋值

    以下是curl get接口header赋值的完整攻略,包括两个示例说明。 步骤 以下是curl get接口header赋值的基本步骤: 打开终端。 在终端中输入curl命令。 输入curl命令。 使用curl命令来发送GET请求,并在请求头中添加需要的header。 curl -H "Header1: Value1" -H "H…

    other 2023年5月6日
    00
  • Android自定义view仿IOS开关效果

    下面我将为您详细讲解“Android自定义view仿IOS开关效果”的完整攻略。 简介 本文将介绍如何实现一个仿IOS开关的自定义View,当然,这种开关在Android中早已有其它的替代品,但是通过手动编写开关的代码,了解自定义View的知识,在此基础上进行风格的定制以及不同需求的实现,这是值得一学的。 实现思路 开关主要由背景圆角矩形、白色小球、阴影三部…

    other 2023年6月27日
    00
  • 关于工伤事故索赔计算很好用的一款APP

    关于工伤事故索赔计算很好用的一款APP的完整攻略 工伤事故索赔计算是一项繁琐的工作,需要考虑多种因素,如伤残程度、工龄、工资等。为了方便工伤事故索赔的计算,有一款很好用的APP可以帮助我们完成这项工作。本文将为您提供一份详细的关于工伤事故索赔计算很好用的一款APP的完整攻略,包括APP的基本介绍、使用方法和两个示例说明。 APP的基本介绍 这款APP是一款专…

    other 2023年5月5日
    00
  • ffmpeg——关于视频压缩

    ffmpeg——关于视频压缩 在在线视频服务越来越普及的今天,视频压缩已经成为了一个必须要掌握的技能。无论是为了减小视频文件大小以节省带宽,还是为了提高视频播放的流畅性,视频压缩都是不可或缺的一项操作。 而在视频压缩的领域里,FFmpeg 可谓是开源界的瑰宝,它是一套免费的、跨平台的、专业的视频音频处理工具。它支持多种格式的视频压缩和转换,并具有高效性、精确…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部