一、使用TEXT还是BLOB?
1、TEXT和BLOB主要差别
主要差别就是BLOB保存二进制数据,TEXT保存字符数据
。
目前几乎博客内容里图片都不是二进制存储在数据库的,而是把图片上传到服务器,然后正文里使用<img>标签引用,这样的博客就可以使用TEXT类型,而BLOB就可以把图片换算成二进制保存到数据库中。
2、类型区别
TEXT类型是一种特殊的字符串类型,包括TINYTEXT
、TEXT
、MEDIUMTEXT
和LONGTEXT
,其长度和储存空间不同而已:
BLOB 是一个二进制的对象,用来存储可变数量的数据。BLOB 类型分为 4 种:TINYBLOB
、BLOB
、MEDIUMBLOB
和 LONGBLOB
,它们可容纳值的最大长度不同,如下表所示:
通常像图片、文件、音乐等信息就用BLOB字段来存储,先将文件转为二进制再存储进去。而像文章或者是较长的文字,就用CLOB存储
3、严格模式
运行在非严格模式时,如果为BLOB 或TEXT列分配一个超过该列类型的最大长度的值时,值被截取以保证适合。如果截掉的字符不是空格,将会产生一条警告。使用严格SQL模式,会产生错误,并且值将被拒绝而不是截取并警告。
4、其他:
1)text不设置长度,当不知道属性的最大长度时,适合用text,能用varchar的地方不用text。查询速度varchar比text快。
2)TEXT和BLOB在存储和检索过程中不存在大小写转换,都一样。
3)对于BLOB 和TEXT列的索引,必须指定索引前缀的长度;
4)BLOB 和TEXT列不能有默认值;
二、Mybatis对MySQL中BLOB字段的读取
对text的读取各个实体类不需要特殊处理,均用String处理即可
本文以mybatis-plus 3.1.1+mysql为例,说下Mybatis对MySQL中BLOB字段的读取和写入处理:
1、修改mapper.xml
在mapper.xml中相应字段添加jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler"
eg:文章表:标题、摘要、作者、文章内容(富文本框BLOB类型)
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.test.common.entity.ArticleInfo">
<id column="seq_id" property="seqId"/>
<result column="title" property="title"/>
<result column="summary" property="summary"/>
<result column="author" property="author"/>
<result column="article" property="article" jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler"/>
</resultMap>
2、修改对应的实体类
修改实体类对应的字段为byte[]类型:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ArticleInfo对象", description="文章表 ")
public class ArticleInfo extends Model<ArticleInfo> {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键")
@TableId(value = "seq_id", type = IdType.AUTO)
private Long seqId;
@ApiModelProperty(value = "标题")
@TableField("title")
private String title;
@ApiModelProperty(value = "摘要")
@TableField("summary")
private String summary;
@ApiModelProperty(value = "作者")
@TableField("author")
private String author;
@ApiModelProperty(value = "文章内容")
@TableField("article")
private byte[] article;
}
3、读取
与前端交互的dto或者vo里,可以用String接受和存储:
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "脚本信息")
public class ArticleInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
private Long seqId;
@ApiModelProperty(value = " 标题 ")
private String title;
@ApiModelProperty(value = " 摘要 ")
private String summary;
@ApiModelProperty(value = " 作者 ")
private String author;
@ApiModelProperty(value = " 文章内容 ")
private String article;
}
//保存接口:
@Override
public void saveInfo(ArticleInfoVo infoVo) {
ArticleInfo info = new ArticleInfo();
BeanUtils.copyProperties(infoVo, info);
try {
//将String转为byte[]
if (StringUtils.isNotBlank(infoVo.getTitle())) {
info.setArticle(infoVo.getArticle().getBytes());
}
} catch (Exception e) {
log.error("处理文章内容异常", e);
}
baseMapper.save(info);
}
//根据唯一标题查看详情接口:
@Override
public ArticleInfoVo queryInfo(String title) {
QueryWrapper<ArticleInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(ArticleInfo::getTitle, title);
ArticleInfo info = articleInfoMapper.selectOne(queryWrapper);
String article = "";
try {
//将byte[]转为String
if (info.getArticle() != null && info.getArticle().length > 0) {
article = new String(info.getArticle(), "UTF-8");
}
} catch (Exception e) {
log.error("处理文章内容异常", e);
}
BeanUtils.copyProperties(info, infoVo);
infoVo.setArticle(article);
return infoVo;
}