Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part D)(下)

简介: Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part D)

9.3 自定义类型处理器TypeHandler

以上问题的解决方式有两种。第一种是新建一张address表,建立user表到address表的关联关系,在MyBatis Mapper XML中使用resultMap和collection标签重新定义映射关系

第二种方式是不创建新的表,就将Address属性的内容全部存到表的address字段中,这就需要使用到自定义的类型处理器

自定义类型处理器要注意字段存储的内容为字符串,所以自定义的类型处理器的主要功能是建立一个规则,将address属性转化为字符串存储在数据库中,并按照一定的格式存储,这个规则还包括查询时,将字符串转化为实体类类型。

image.png

查看类型转换的顶级接口TypeHandler以及BaseTypeHandler

image.png

  • setNonNullParameter:将要做类型处理的parameter对象转换为字符串存在ps对象的i位置
  • getNullableResult:从结果集中获取查询结果转换为原始对象

可以通过继承BaseTypeHandler实现自定义的类型处理器

9.3.1 实现自定义类型处理器AddressTypeHandler

新建一个类AddressTypeHandler继承BaseTypeHandler

public class AddressTypeHandler extends BaseTypeHandler<Address> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Address parameter, JdbcType jdbcType) throws SQLException {
        // 1.对传进来的address对象进行校验
        if (parameter == null){
            return;
        }
        // 2.从address对象中取出数据
        String province = parameter.getProvince();
        String city = parameter.getCity();
        String street = parameter.getStreet();
        // 3.拼接成一个字符串,用","隔开
        StringBuilder builder = new StringBuilder();
        builder.append(province).append(",").append(city).append(",").append(street);
        // 4.设置参数
        String parameterValue = builder.toString();
        ps.setString(i,parameterValue);
    }
    @Override
    public Address getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根据字段名从rs对象中获取字段值
        String columnValue = rs.getString(columnName);
        // 校验 columnValue是否有效
        if (columnValue == null || columnValue.length() == 0|| !columnValue.contains(",")){
            return null;
        }
        // 拆分columnValue
        String[] split = columnValue.split(",");
        // 从拆分结果中给对象赋值
        Address address = new Address();
        address.setProvince(split[0]);
        address.setCity(split[1]);
        address.setStreet(split[2]);
        return address;
    }
    @Override
    public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根据字段索引从rs对象中获取字段值
        String columnValue = rs.getString(columnIndex);
        // 校验 columnValue是否有效
        if (columnValue == null || columnValue.length() == 0|| !columnValue.contains(",")){
            return null;
        }
        // 拆分columnValue
        String[] split = columnValue.split(",");
        // 从拆分结果中给对象赋值
        Address address = new Address();
        address.setProvince(split[0]);
        address.setCity(split[1]);
        address.setStreet(split[2]);
        return address;
    }
    @Override
    public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 根据字段索引从cs对象中获取字段值
        String columnValue = cs.getString(columnIndex);
        // 校验 columnValue是否有效
        if (columnValue == null || columnValue.length() == 0|| !columnValue.contains(",")){
            return null;
        }
        // 拆分columnValue
        String[] split = columnValue.split(",");
        // 从拆分结果中给对象赋值
        Address address = new Address();
        address.setProvince(split[0]);
        address.setCity(split[1]);
        address.setStreet(split[2]);
        return address;
    }
}
复制代码

注册AddressTypeHandler的方式有两种

  • 字段/属性级别注册:在要使用自定义类型转换器的属性上使用@ColumnType注解
  • 全局注册:在MyBatis全局配置文件中使用typeHandlers标签注册,并在要转换的属性上增加@Colum注解。

首先使用@ColumnsType注解注册

@ColumnType(typeHandler = AddressTypeHandler.class)
private Address address;
复制代码

执行查询测试

image.png

输出的Address对象不再是空对象

执行插入测试

image.png

查看插入的数据

image.png

插入的address字段也不再是空。说明自定义的类型处理器生效

然后使用MyBatis全局配置文件注册AddressTypeHandler 给address属性增加@Column注解,让通用Mapper处理普通字段一样处理address 在全局配置文件中增加配置,settings标签下

<typeHandlers>
    <typeHandler handler="com.citi.handler.AddressTypeHandler"
                 javaType="com.citi.entity.Address" />
</typeHandlers>
复制代码

再次执行查询测试

image.png

Address对象不为空

9.4 枚举类型的处理

9.4.1 将枚举类型当作简单类型来处理

配置enumAsSimpleType=true会把枚举类型当作简单类型处理,默认simpleType会忽略枚举类型,默认不处理,所以出现了一开始枚举内容为空的情况

在MyBatis全局配置文件中配置枚举类型处理的配置

<bean id="mapperScannerConfigurer" class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--其他被容不变-->
    <property name="properties">
        <value>
            enumAsSimpleType=true
        </value>
    </property>
</bean>
复制代码

执行查询测试

image.png

成功输出枚举类型的内容

执行插入测试

image.png

根据输出的SQL语句,插入时枚举内容不为空,可以查看数据库中插入的数据

image.png

枚举类型的内容也被成功插入到数据库中,说明配置生效。

9.4.2 为枚举类型配置对应的类型处理器

image.png

MyBatis内置了两种枚举类型的处理器

  • org.apache.ibatis.type.EnumTypeHandler
  • org.apache.ibatis.type.EnumOrdinalTypeHandler

使用EnumTypeHandler类型处理器

使用@ColumnType注解方式注册EnumTypeHandler处理器

image.png

编译阶段就已经报错,不能使用@Column注解注册EnumTypeHandler处理器

MyBatis全局配置文件中注册类型处理器,并在season属性上增加@Column注解

<typeHandlers>
    <typeHandler handler="org.apache.ibatis.type.EnumTypeHandler"
                 javaType="com.citi.entity.SeasonEnum" />
</typeHandlers>
复制代码

增加@Column注解的作用是让通用Mapper不忽略枚举类型

执行查询测试

image.png

成功输出枚举类型的内容

执行插入测试

image.png

根据INSERT语句内容来看,插入的内容不为空,可以查看数据库插入的内容

image.png

成功将枚举内容插入到数据库中

使用EnumOrdinalTypeHandler类型处理器

枚举处理器中带Ordinal与不带Ordinal的区别:

  • 带Ordinal存的是索引值
  • 不带Ordinal存的是具体内容

在MyBatis全局配置文件中注册EnumOrdinalTypeHandler类型处理器

<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
             javaType="com.citi.entity.SeasonEnum" />
复制代码

执行插入测试

image.png

查看数据库

image.png

查询刚刚插入的数据

image.png

针对索引对应的内容非常大的时候比较适用

十、通用Mapper的配置项

通用Mapper的配置项配置位置在name=propertiesy的property标签下

<bean id="mapperScannerConfigurer" class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--指定接口所在的包-->
    <property name="basePackage" value="com.citi.mapper"></property>
    <property name="properties">
        <value>
            enumAsSimpleType=true
        </value>
    </property>
</bean>
复制代码

有多个配置项可以设置多个value标签。

通用 Mapper 提供了十几个配置参数,具体请参考通用Mapper配置

至此,通用Mapper部分完结✿✿ヽ(°▽°)ノ✿!


相关文章
|
3月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
65 10
|
5月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
4月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
78 1
|
5月前
|
XML Java 数据库连接
Mybatis 模块拆份带来的 Mapper 扫描问题
Mybatis 模块拆份带来的 Mapper 扫描问题
56 0
|
6月前
|
SQL
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
|
6月前
|
Java 数据库连接 Maven
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
|
7月前
|
SQL Java 数据库连接
Mybatis如何使用mapper代理开发
Mybatis如何使用mapper代理开发
|
7月前
|
XML 关系型数据库 数据库
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
644 0
|
7月前
|
SQL Java 数据库连接
Mybatis中一对多mapper配置
Mybatis中一对多mapper配置
|
7月前
|
Java 数据库连接 mybatis
Mybatis mapper动态代理解决方案
该文介绍了Mybatis中使用Mapper接口的方式代替XML配置执行SQL。Mapper接口规范包括:namespace与接口类路径相同,select ID与接口方法名一致,parameterType和方法参数类型匹配,resultType与返回值类型一致。实现过程中,需配置Mapper.xml,编写Mapper.java接口,并在Mybatis-config.xml中设置。测试类中,通过SqlSession的getMapper方法获取接口的动态代理对象,调用方法执行SQL。
231 0