MyBatis-plus SQLFeatureNotSupportedException 的解决办法

如图,SQLITE 的这个驱动似乎不支持使用 getBLOB,但 SQLITE 确实支持存储 BLOB 数据,如果用 Mybatis 也会遇到同样的问题, 毕竟 MP 是基于 MyBatis

image

解决办法也很简单,加上这个参数就行
image

image

或者也可以给某个字段加上 typeHandler 的参数,然后写一个 TypeHandler,这样就能指定 注入这个字段时使用的 TypeHandler

image
image

第二个方法只使用 Mybatis 也能用,只是需要在 xml 里配置 typeHandler


2022-05-08 更新 Mybatis xml 配置方式

最近又用到这个了,这次没有 SpringBoot 的加持, 麻烦了些许,贴上代码
项目结构

image

mybatis-config.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias alias="Question" type="com.mrx.jkbd.entity.Question"/>
    </typeAliases>

    <typeHandlers>
        <typeHandler javaType="byte[]" handler="com.mrx.mybatis.config.ByteArrayTypeHandler"/>
    </typeHandlers>

    <environments default="development">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="com.mrx.mybatis.config.XDruidDataSourceFactory">
                <property name="name" value="SQLITE"/>
                <property name="url" value="jdbc:sqlite::resource:question.db"/>
                <property name="driverClassName" value="org.sqlite.JDBC"/>
                <property name="initialSize" value="5"/>
                <property name="minIdle" value="5"/>
                <property name="maxActive" value="10"/>
                <property name="maxWait" value="10000"/>
                <property name="validationQuery" value="SELECT 1"/>
            </dataSource>
        </environment>

    </environments>

    <mappers>
        <mapper resource="mapper/QuestionMapper.xml"/>
    </mappers>

</configuration>

QuestionMapper.xml

<?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="com.mrx.mybatis.mapper.QuestionMapper">

    <resultMap id="questionMap" type="Question">
        <result column="question" property="question" javaType="byte[]"/>
        <result column="explain" property="explain" javaType="byte[]"/>
        <result column="keywords" property="keywords" javaType="byte[]"/>
        <result column="concise_explain" property="conciseExplain" javaType="byte[]"/>
        <result column="assured_keywords" property="assuredKeywords" javaType="byte[]"/>
        <result column="illiteracy_explain" property="illiteracyExplain" javaType="byte[]"/>
        <result column="illiteracy_keywords" property="illiteracyKeywords" javaType="byte[]"/>
        <result column="knack_keyword" property="knackKeyword" javaType="byte[]"/>
        <result column="knack_img_url" property="knackImgUrl" javaType="byte[]"/>
        <result column="knack_detail" property="knackDetail" javaType="byte[]"/>
        <result column="knack_voice_txt" property="knackVoiceTxt" javaType="byte[]"/>
    </resultMap>

    <select id="getQuestionById" resultType="Question" parameterType="long" resultMap="questionMap">
        SELECT *
        FROM t_question
        WHERE question_id = #{qid}
    </select>

</mapper>

ByteArrayTypeHandler

package com.mrx.mybatis.config

import org.apache.ibatis.type.JdbcType
import org.apache.ibatis.type.TypeHandler
import org.slf4j.LoggerFactory
import java.sql.CallableStatement
import java.sql.PreparedStatement
import java.sql.ResultSet

/**
 * @author Mr.X
 * @since 2022-05-08-0008
 **/
@Suppress("unused")
class ByteArrayTypeHandler : TypeHandler<ByteArray> {

    private val logger = LoggerFactory.getLogger(this::class.java)

    override fun setParameter(ps: PreparedStatement, i: Int, parameter: ByteArray, jdbcType: JdbcType) {
        ps.setBytes(i, parameter)
    }

    override fun getResult(rs: ResultSet, columnName: String): ByteArray? {
        return rs.getBytes(columnName)
    }

    override fun getResult(rs: ResultSet, columnIndex: Int): ByteArray? {
        return rs.getBytes(columnIndex)
    }

    override fun getResult(cs: CallableStatement, columnIndex: Int): ByteArray? {
        return cs.getBytes(columnIndex)
    }

}

MyBatisUtil

package com.mrx.mybatis.config

import org.apache.ibatis.session.SqlSessionFactory
import org.apache.ibatis.session.SqlSessionFactoryBuilder
import java.io.InputStream


/**
 * 配置 Mybatis
 */
object MybatisUtil {

    private val ins: InputStream = this::class.java.getResourceAsStream("/mybatis-config.xml")!!

    //定义默认 environment
    private val env: SqlSessionFactory = SqlSessionFactoryBuilder().build(ins)

    fun <T> getMapper(mapperClazz: Class<T>): T {

        return env.configuration.getMapper(mapperClazz, env.openSession())
    }

}
posted @ 2022-04-23 10:56  博麗靈夢  阅读(1246)  评论(1编辑  收藏  举报