MyBatis-plus SQLFeatureNotSupportedException 的解决办法
如图,SQLITE
的这个驱动似乎不支持使用 getBLOB
,但 SQLITE
确实支持存储 BLOB
数据,如果用 Mybatis
也会遇到同样的问题, 毕竟 MP
是基于 MyBatis
的
解决办法也很简单,加上这个参数就行
或者也可以给某个字段加上 typeHandler
的参数,然后写一个 TypeHandler
,这样就能指定 注入这个字段时使用的 TypeHandler
第二个方法只使用 Mybatis
也能用,只是需要在 xml
里配置 typeHandler
2022-05-08 更新 Mybatis xml 配置方式
最近又用到这个了,这次没有 SpringBoot
的加持, 麻烦了些许,贴上代码
项目结构
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())
}
}