mybatis plus配置postgreSQL及映射数组

mybatis plus介绍

mybatis plus作为一款优秀的数据库连接插件,在国内还是非常火爆的,其中的一些功能可以极大的提供开发人员的效率,详情可以移步官网 https://mp.baomidou.com/guide/

mybatis在SpringBoot中的配置

基本可以参考如下的 pom.xml,这里面有MySQL和PGSQL的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>person-home-page</artifactId>
        <groupId>com.heng</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>home-page-dynamicDB</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.18</version>
        </dependency>
        <!-- jdbc启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- mybatis-plus启动器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.3</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

连接PGSQL的信息

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/Pudongtest
    username: postgres
    password: 123456

参照这个来基本是没什么问题的,而难点在于 PGSQL 中存在着一个特殊的项:数组,如下:

注意,这不是字符串,而是PGSQL中的数组,具体的创建表的语句如下:

CREATE TABLE arr_test (
	serial_id VARCHAR,
	name VARCHAR[],
	scores INTEGER[]
);

那么,如何在PGSQL中做实体类映射的时候,成功的将其作为数组接收到呢?步骤如下:

  1. 定义实体类
@TableName(value = "arr_test", autoResultMap = true)
@Data
public class ArrTest {
    @TableField(value = "serial_id")
    @TableId
    String serialId;
    @TableField(value = "name", jdbcType = JdbcType.ARRAY, typeHandler = ArrayTypeHandler.class)
    String[] name;
    @TableField(value = "scores", jdbcType = JdbcType.ARRAY, typeHandler = ArrayTypeHandler.class)
    Integer[] scores;
}

注意啊,@Data注解是lombok包下的简化getset函数的注解,不会的同学可以学一下,或者直接补全getset,而其他的注解也相当重要,一个都不能少,如
@TableName中的autoResultMap = true得开启,然后 @TableField中的 jdbcType = JdbcType.ARRAY就是转化数组的,而后面的 typeHandler = ArrayTypeHandler.class中的类则是自定义的了,如下:
2. 添加自定义的转化类

package com.jack.db.entity;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.sql.*;

public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ArrayTypeHandler.class);
	
	private static final String TYPE_NAME_VARCHAR = "varchar";
    private static final String TYPE_NAME_INTEGER = "integer";
    private static final String TYPE_NAME_BOOLEAN = "boolean";
    private static final String TYPE_NAME_NUMERIC = "numeric";

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType)
			throws SQLException {
		String typename = null;
        if (parameter instanceof Integer[]) {
            typename = TYPE_NAME_INTEGER;
        } else if (parameter instanceof String[]) {
            typename = TYPE_NAME_VARCHAR;
        } else if (parameter instanceof Boolean[]) {
            typename = TYPE_NAME_BOOLEAN;
        } else if (parameter instanceof Double[]) {
            typename = TYPE_NAME_NUMERIC;
        }
        
        if (typename == null) {
            throw new TypeException("arraytypehandler parameter typename error, your type is " + parameter.getClass().getName());
        }
        
        // 这2行是关键的代码,创建array,然后ps.setarray(i, array)就可以了
        Array array = ps.getConnection().createArrayOf(typename, parameter);
        ps.setArray(i, array);
	}

	@Override
	public Object[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return getArray(rs.getArray(columnName));
	}

	
	@Override
	public Object[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return getArray(rs.getArray(columnIndex));
	}

	
	@Override
	public Object[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return getArray(cs.getArray(columnIndex));
	}

	private Object[] getArray(Array array) {

		if (array == null) {
			return null;
		}

		try {
			return (Object[]) array.getArray();
		} catch (SQLException e) {
			LOGGER.error("ArrayTypeHandler getArray SQLException",e);
		}
		return null;

	}
}

可以直接拿去用,注意这里的类其实mybatis plus中也自带了一个,但是实现的并不好,所以建议用自定义的
3. 测试
就直接在 @Test里面测试即可,这就不细讲了,如下:

@Test
public void get() {
    IPage<ArrTest> arrTestIPage = new Page<>(1, 10);
    IPage<ArrTest> iPage = iArrTestService.page(arrTestIPage);
    List<ArrTest> arrTestList = iPage.getRecords();
    arrTestList.forEach(System.out::println);
}

普及一下,上面的 IPage是mybatis plus自带的分页插件,可以参考https://baomidou.com/guide/crud-interface.html#page,但是需要提前配置,配置方式如下:
4. mybatis plus配置分页插件
(1) 在Springboot中添加配置类

@Configuration
@MapperScan("com.jack.db.mapper")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
        return interceptor;
    }
}

(2) 在需要使用的地方创建IPage
(3) 解析结果,包括总记录数和当前页码,结果等信息
官网配置链接https://baomidou.com/guide/page.html
PS:注意,使用数组功能时,对于数据库的操作只能使用mybatis plus的API函数,而不能使用xml中的SQL语句,或者注解上面的SQL语句,不知道为什么,有知道的小伙伴可以告知一下谢谢;

posted on 2021-04-20 16:03  高冷的恒哥  阅读(13468)  评论(0编辑  收藏  举报