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

下面是详细的攻略,包括自动映射字段和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可以大大简化代码和提高开发效率。同时需要注意上面提到的注意点。

阅读剩余 81%

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

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

相关文章

  • docke-cli的调试环境搭建过程

    介绍Docker-CLI前,请先介绍一下Docker? Docker简介 Docker是一个开源的应用容器引擎,可以将软件应用及其依赖项打包成一个可移植的容器中,然后发布到任何支持Docker的Linux机器上,运行容器就像运行任何其他应用一样简单,方便,并且有以下特点: 轻量化 弹性伸缩 隔离性 Docker-CLI简介 Docker-CLI是Docker…

    other 2023年6月27日
    00
  • Java Dubbo协议下的服务端线程使用详解

    Java Dubbo协议下的服务端线程使用详解 Dubbo协议 Dubbo 是一个高性能、轻量级的开源Java RPC框架,支持应用间高性能通信、服务治理、容错保障、可扩展性等,已在国内外很多互联网公司大规模使用。 Dubbo协议是Dubbo RPC的一种协议,本质上是一种基于TCP的传输协议。在Dubbo协议下,服务提供方和服务消费方通过TCP建立连接,并…

    other 2023年6月27日
    00
  • python支持多继承吗

    当涉及到面向对象编程(OOP)时,继承是一个非常重要的概念之一。继承是一种方式,可以创建一个新的类(子类),以重用现有类(父类)的属性和方法。Python是支持多继承的编程语言。 Python支持多继承的方式是通过在子类定义中列出多个父类名称来实现的。例如: class A: def method_a(self): print("method_a&…

    other 2023年6月27日
    00
  • 魔兽世界9.0兽王猎天赋盟约选择及输出手法教学 兽王入门指南

    魔兽世界9.0兽王猎天赋盟约选择及输出手法教学 一、天赋选择 作为兽王猎的玩家,我们在选取天赋时应该注重以下几点: 1、第一行天赋 第一行天赋的选择主要分为两种,分别是屠宰和狂野呼唤。如果我们更注重单体伤害的话,那么就选择屠宰;如果我们更注重团队的贡献,加上副本中有各种各样的光环,那么就需要选择狂野呼唤。 2、第二行天赋 第二行天赋的选择主要分为两种,分别是…

    other 2023年6月27日
    00
  • amd锐龙处理器5怎么样 AMD锐龙Ryzen5 1600X全面深度评测

    很抱歉,由于我是一个文本模型,无法以标准的markdown格式回答您的问题。但是,我可以为您提供一份详细的攻略,包含AMD锐龙处理器5 1600X的全面深度评测,并提供两个示例说明。 AMD锐龙处理器5 1600X全面深度评测 1. 性能表现 AMD锐龙处理器5 1600X是一款六核心十二线程的处理器,采用Zen架构。它具有较高的性能表现,在多线程任务和游戏…

    other 2023年10月17日
    00
  • 详解Android控件之DatePicker、TimePicker探究

    详解Android控件之DatePicker、TimePicker探究 前言 Android控件库中包含了许多常用的控件,其中DatePicker和TimePicker控件可以帮助开发者轻松实现日期选择和时间选择功能。在本篇文章中,我们将深入探究这两个控件的实现原理、用法以及注意事项。 DatePicker控件 实现原理 DatePicker控件是一个复合控…

    other 2023年6月26日
    00
  • oracle四种列转行的方法

    Oracle四种列转行的方法 在数据处理中,经常需要将列按照行拆分,这里我们介绍一下在Oracle数据库中几种列转行的方法。 1. 使用UNION ALL 使用UNION ALL是一种常见的列转行的方法。将需要拆分的列通过UNION ALL合并成一列,再通过SELECT和CASE WHEN来重新构造为行。 SELECT id, ‘col1’ AS col_n…

    其他 2023年3月28日
    00
  • linux配置nginx.service设置nginx开机启动

    Linux配置nginx.service设置nginx开机启动 nginx是一款高性能的Web服务器和反向代理服务器,它可以处理大量的并发请求。在Linux中,我们可以使用systemd配置nginx.service,实现nginx的开机启动。以下是Linux配置nginx.service设置nginx开机启动的完整攻略,包括常见问题和两个示例说明。 常见问…

    other 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部