1. 程式人生 > 實用技巧 >SpringBoot+MyBatis+PostgreSQL配置

SpringBoot+MyBatis+PostgreSQL配置

SpringBoot+MyBatis+PostgreSQL配置


1.前置依賴配置

首先我們需要引入maven的依賴包

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.7</version>
</dependency>

連線PostgreSQL時需要手動指定schema位置,否則,連線上的database會預設使用public這個內建的schema,導致在查詢別的schema下的表時,會報類似如下的錯誤:

nested exception is org.postgresql.util.PSQLException: ERROR: relation "xxxTable" does not exist

我使用的方式是利用pgAdmin4,在控制介面上輸入如下的SQL切換schema:

ALTER ROLE postgres SET SEARCH_PATH ='ROS'; #ROS是schema名,postgres是database使用者名稱

當然也可以通過PostgreSQL提供的命令列介面來做切換:

root@1dc27bbb5253:/ su - postgres    #首先需要切換使用者到[postgres]使用者
postgres@1dc27bbb5253:~$ psql        #進入命令列模式
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.

postgres= \c minedb;    #切換資料庫
minedb=# ALTER ROLE postgres SET SEARCH_PATH ='ROS';
ALTER ROLE
root@1dc27bbb5253:/# psql -U postgres -d minedb
minedb
=# ALTER ROLE postgres SET SEARCH_PATH ='ROS'; ALTER ROLE

我們使用了mybatis-generator-maven-plugin這個外掛快速生成通用CRUD配置xml
為了使用這個外掛,我們需要新建一個mybatis-generator.xml檔案來指導外掛工作:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--資料庫驅動-->
    <classPathEntry location="C:\Users\xxxuser\.m2\repository\org\postgresql\postgresql\42.2.5\postgresql-42.2.5.jar"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--資料庫連結地址賬號密碼-->
        <jdbcConnection driverClass="org.postgresql.Driver" connectionURL="jdbc:postgresql://172.22.122.27:5432/minedb" userId="postgres" password="aq1sw2de"></jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--生成Model類存放位置-->
        <javaModelGenerator targetPackage="zsh.demos.postgres.dao.pojo" targetProject="./src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!--生成對映檔案存放位置-->
        <sqlMapGenerator targetPackage="mapping" targetProject="./src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--生成Dao類存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="zsh.demos.postgres.dao.mapper" targetProject="./src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!--生成對應表及類名-->
        <!--<table tableName="big_table" domainObjectName="BigTable" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>-->
        <table tableName="vehicle" domainObjectName="Vehicle" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>

前置準備工作完畢,我們開始配置連線引數


2. 使用YMAL方式配置:

spring:
  datasource:
    url: jdbc:postgresql://172.22.122.27:5432/minedb
    username: postgres
    password: aq1sw2de
    driver-class-name: org.postgresql.Driver

mybatis:
  type-handlers-package: zsh.demos.postgres.mybatis.typehandler
  mapper-locations: classpath:mapping/*.xml
配置中指定資料來源,指定xml格式的mapping檔案存放位置,指定對於JDBCType=OTHER屬性的欄位(例如PostgreSQL中的JSON型別)的處理handler存放位置


3. 使用註解配置:

@Configuration
@MapperScan(basePackages = "zsh.demos.postgres.dao.mapper", sqlSessionFactoryRef = "pgSqlSessionFactory")
public class PostgresConfig {

    @Value("${mybatis.mapper-locations}")
    private String MAPPER_LOCATION;
    @Value("${mybatis.type-handlers-package}")
    private String TYPE_HANDLERS_PACKAGE;

    @Bean(name = "pgSqlSessionFactory")
    public SqlSessionFactory postgresSqlSessionFactory(@Autowired DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);

        // case change.
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);

        sqlSessionFactoryBean.setConfiguration(configuration);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
        sqlSessionFactoryBean.setTypeHandlersPackage(TYPE_HANDLERS_PACKAGE);
        return sqlSessionFactoryBean.getObject();
    }
}


4. TypeHandler

TypeHandler是針對JDBCType=OTHER的擴充套件,例如Postgres支援的JSON格式資料,我們需要手動定義如下TypeHandler:

基類:

public abstract class JSONTypeHandler<T> implements TypeHandler<T> {

    /**
     * json資料和類名的分隔符號
     */
    protected Class<T> jsonClass = null;

    @Override
    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        // TODO Auto-generated method stub
        if (parameter == null) {
            ps.setString(i, "");
            return;
        }
        String json = JSONUtils.jsonToJSONStr(parameter);
        PGobject pGobject = new PGobject();
        pGobject.setType("json");
        pGobject.setValue(json);
//      ps.setString(i, json);
        ps.setObject(i, pGobject);
    }

    @Override
    public T getResult(ResultSet rs, String columnName) throws SQLException {
        // TODO Auto-generated method stub
        String json = rs.getString(columnName);
        return jsonToObject(json);
    }

    @Override
    public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
        // TODO Auto-generated method stub
        String json = cs.getString(columnIndex);
        return jsonToObject(json);
    }

    @Override
    public T getResult(ResultSet rs, int columnIndex) throws SQLException {
        // TODO Auto-generated method stub
        String json = rs.getString(columnIndex);
        return jsonToObject(json);
    }
    /**
     * json 轉換成物件
     */
    protected T jsonToObject(String json) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        T ob = JSONUtils.jsonStrToJSON(json, jsonClass);
        return ob;
    }
}
public class JSONUtils {
    //
    public static <T> String jsonToJSONStr(T json) {
        String jsonString = "";
        ObjectMapper mapper = new ObjectMapper();
        try {
            jsonString = mapper.writeValueAsString(json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonString;
    }
    //
    public static <T> T jsonStrToJSON(String json, Class<T> clazz) {
        ObjectMapper mapper = new ObjectMapper();
        T object = null;
        try {
            object = mapper.readValue(json, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
    //
    public static <T> T jsonStrToJSON(String json, TypeReference<T> type) {
        ObjectMapper mapper = new ObjectMapper();
        T object = null;
        try {
            object = mapper.readValue(json, type);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
}
具體業務物件類:
@MappedTypes(BusinessBean.class)
public class BusinessBeanHandler extends JSONTypeHandler<BusinessBean> {
    public BusinessBeanHandler () {this.jsonClass = BusinessBean.class;}
}
使用時,需要再resultMap中指定需要typeHandler轉換的欄位:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="zsh.demos.postgres.dao.mapper.VehicleMapper">
  <resultMap id="BaseResultMap" type="zsh.demos.postgres.dao.pojo.BusinessBean">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="business_json" jdbcType="OTHER" property="businessJSON" typeHandler="zsh.demos.postgres.mybatis.typehandler.BusinessBeanHandler"/>
    <result column="business_string" jdbcType="CHAR" property="businessString" />
  </resultMap>
</mapper>


4. 事務管理器

如果應用只配置了一個數據源,那麼在預設情況下,SpringBoot在
org.springframework.boot.autoconfig ure.jdbc.DataSourceTransactionManagerAutoConfiguration
自動配置類中已經為我們配好了一個預設的事務管理器。並且在
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
中幫我們自動啟動了事務管理支援@EnableTransactionManagement所以我們無需做任何配置。


作者:大豬小豬在菜盤
連結:https://www.jianshu.com/p/9347014b31a3
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。