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可以大大简化代码和提高开发效率。同时需要注意上面提到的注意点。

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

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

相关文章

  • win10预览版9918下载地址 win10 9918官方下载

    Win10预览版9918下载攻略 Win10预览版9918是Windows 10操作系统的一个预览版本,本攻略将详细介绍如何下载和安装该版本。以下是完整的攻略过程: 步骤一:访问官方网站 首先,你需要访问Windows官方网站以获取Win10预览版9918的下载地址。你可以在以下网址找到官方下载页面:https://www.microsoft.com/zh-…

    other 2023年8月4日
    00
  • delphicase语句

    当然,我很乐意为您提供有关“Delphi Case语句”的完整攻略。以下是详细的步骤和两个示例: 1 Delphi Case语句 Delphi Case语句是一种条件语句,用于根据不同的条件执行不同的代码块。它类似于其他编程语言中的switch语句。 2 Delphi Case语句语法 以下是Delphi Case语句的语法: case expression…

    other 2023年5月6日
    00
  • linux取消挂载命令

    Linux取消挂载命令 在 Linux 系统中,挂载命令是一个非常重要的命令,它用于将文件系统附加到指定的挂载点。然而,在有时候我们需要取消挂载指定的文件系统,该如何操作呢? 取消挂载命令 取消挂载命令是 umount 命令,它会从文件系统挂载表中移除指定的文件系统。取消挂载命令的一般语法如下: umount 挂载点 其中, umount 代表取消挂载命令,…

    其他 2023年3月28日
    00
  • Java getResource()如何获取class文件目录位置

    Java中的getResource()方法用于从类路径中获取资源,获取资源的路径可以是绝对路径,也可以是相对路径。方法的返回值是一个URL对象。 下面我们来讲解如何使用getResource()方法获取class文件目录位置: 获取class文件所在目录绝对路径 获取class文件所在目录的绝对路径可以使用以下代码: URL url = xxx.class.…

    other 2023年6月27日
    00
  • C# WPF开源UI控件库MaterialDesign介绍

    C# WPF开源UI控件库MaterialDesign介绍 MaterialDesign是一个基于Google Material Design风格的开源UI控件库,支持C#和WPF框架。它提供了一系列高质量的UI控件和组件,能够帮助快速搭建出美观且具有交互性的应用程序界面。 MaterialDesign的介绍 MaterialDesign是一个免费的开源项目…

    other 2023年6月26日
    00
  • Python单例模式实例详解

    Python单例模式实例详解 单例模式是一种常见的设计模式之一,它保证一个类有且只有一个实例,并且提供了一个全局访问点。Python中可以用多种方式实现单例模式,比如使用模块、装饰器、元类等。接下来我们分别介绍这三种方式的实现方法,并给出示例说明。 使用模块实现单例模式 Python中的模块天生就是单例的,因为导入一个模块时,模块只会被加载一次并且一直可用。…

    other 2023年6月27日
    00
  • php中的datetime类

    当然,我很乐意为您提供有关“PHP中的DateTime类”的完整攻略。以下是详细的步骤和两个示例: 1 DateTime类 DateTime类是PHP中用于处理日期和时间的类。它提供了许多方法来创建、格式化和操作日期和时间。 2 DateTime类的常用方法 以下是DateTime类的常用方法: 2.1 创建DateTime对象 可以使用DateTime类的…

    other 2023年5月6日
    00
  • fw.qq.com/ipaddress已失效 javascript获得客户端IP的新方法

    \”fw.qq.com/ipaddress已失效 javascript获得客户端IP的新方法\”攻略 背景 在过去,我们可以通过访问\”fw.qq.com/ipaddress\”来获取客户端的IP地址。然而,最近这个方法已经失效了。本攻略将介绍一种新的方法,使用JavaScript来获取客户端的IP地址。 步骤 步骤一:使用第三方服务 我们可以使用第三方服务…

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