您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“mybatis-plus怎么配置自定義數據類型TypeHandle”,內容詳細,步驟清晰,細節處理妥當,希望這篇“mybatis-plus怎么配置自定義數據類型TypeHandle”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
mybatis-plus在mybatis的基礎的上,做了全面增強功能,極大的提高了我們的開發效率。有時候我們使用的實體字段類型,與數據庫創建的字段類型無法對應上,這時候就需要配之自定義的類型處理類,來處理代碼和數據庫之間的數據流轉。
我們有個實體類TestEntity,使用注解@TableName表示對應數據庫表名為test
@Data @TableName(value = "test") public class TestEntity{ private static final long serialVersionUID = 8565214506859404278L; private String id; private String type; private Document content; }
DAO層對象
@Mapper public interface TestDao extends BaseMapper<TestEntity> { }
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.aisino.dao.TestDao"> <resultMap type="com.aisino.entity.TestEntity" id="testMap"> <result property="id" column="id"/> <result property="type" column="name"/> <result property="content" column="content"/> </resultMap> </mapper>
其中Document使用的是org.w3c.dom.Document對象,數據庫存儲的字段類型為bytea,我這里使用的是postgresql,顯然數據類型無法匹配,這里需要編寫類型處理類進行數據類型轉換。
1.編寫TypeHandle,首先需要明確我們代碼中和數據庫中各自的數據類型,編寫處理類DocumentTypeHandler繼承BaseTypeHandler,并重寫4個方法:
(1)setNonNullParameter表示從代碼中的數據類型轉換成數據庫數據類型,即Document轉為BLOB類型。這里的基本思路就是將Document轉為String再轉為字節流,最后利用setBinaryStream方法轉為數據庫對象。
(2)getNullableResult,getNullableResult,getNullableResult表示從數據庫類型中獲取數據并轉換為代碼中的數據類型,即BLOB轉為Document類型。這里的基本思路就是上一步的逆過程。
@MappedTypes
中填寫的是我們代碼中的數據類型
@MappedJdbcTypes
中填寫的是數據庫中的數據類型
@MappedTypes(Document.class) @MappedJdbcTypes(JdbcType.BLOB) public class DocumentTypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { String docStr = docToString((org.w3c.dom.Document) parameter); InputStream in = new ByteArrayInputStream(docStr.getBytes()); ps.setBinaryStream(i, in); } @Override public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { byte[] bytes = rs.getBytes(columnName); return !rs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null; } @Override public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException { byte[] bytes = rs.getBytes(columnIndex); return !rs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null; } @Override public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { byte[] bytes = cs.getBytes(columnIndex); return !cs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null; } public static String docToString(Document doc) { // XML轉字符串 String xmlStr = ""; try { TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.setOutputProperty("encoding", "UTF-8"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); t.transform(new DOMSource(doc), new StreamResult(bos)); xmlStr = bos.toString(); } catch (TransformerConfigurationException e) { // TODO e.printStackTrace(); } catch (TransformerException e) { // TODO e.printStackTrace(); } return xmlStr; } public static Document stringToDoc(String xmlStr) { //字符串轉XML Document doc = null; try { xmlStr = new String(xmlStr.getBytes(), "UTF-8"); StringReader sr = new StringReader(xmlStr); InputSource is = new InputSource(sr); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; builder = factory.newDocumentBuilder(); doc = builder.parse(is); } catch (ParserConfigurationException e) { // TODO e.printStackTrace(); } catch (SAXException e) { // TODO e.printStackTrace(); } catch (IOException e) { // TODO e.printStackTrace(); } return doc; } }
2.回到實體類配置,以下是修改后的實體類
(1)在注解@TableName中增加autoResultMap = true表示使用xml中的映射配置
(2)增加注解配置@TableField(typeHandler = DocumentTypeHandler.class)表示content字段使用數據類型處理類DocumentTypeHandler.class
@Data @TableName(value = "test",autoResultMap = true) public class TestEntity{ private static final long serialVersionUID = 8565214506859404278L; private String id; private String type; @TableField(typeHandler = DocumentTypeHandler.class) private Document content; }
3.以下是修改后的xml配置
(1)content字段配置jdbcType=“OTHER”,配置數據處理類typeHandler=“com.aisino.jdbc.ibatis.DocumentTypeHandler”
<?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.aisino.dao.TestDao"> <resultMap type="com.aisino.entity.TestEntity" id="testMap"> <result property="id" column="id"/> <result property="type" column="name"/> <result property="content" column="content" jdbcType="OTHER" typeHandler="com.aisino.jdbc.ibatis.DocumentTypeHandler"/> </resultMap> </mapper>
4.注意事項
(1)編寫TypeHandle類時候,繼承BaseTypeHandler<Document>試過不行,原因暫未深究。
(2)實體類的注解@TableField(typeHandler = DocumentTypeHandler.class)與xml配置的處理類路徑typeHandler="com.aisino.jdbc.ibatis.DocumentTypeHandler"缺一不可,因為看過網上說只配置注解即可,我試了不行,原因暫未深究。
可通過自定義的TypeHandler實現某個屬性在插入數據庫以及查詢時的自動轉換,本例中是要將Map類型的屬性轉化成CLOB,然后存入數據庫。由于是復雜的Map,mp自帶的json轉換器會丟失部分信息。
@MappedTypes
:注解配置 java 類型
@MappedJdbcTypes
:注解配置 jdbc 類型
定義:
@Slf4j @MappedTypes({Object.class}) @MappedJdbcTypes(JdbcType.VARCHAR) public class WeightListTypeHandler extends AbstractJsonTypeHandler<Object> { private static Gson gson = new Gson(); private final Class<?> type; public WeightListTypeHandler(Class<?> type) { if (log.isTraceEnabled()) { log.trace("WeightListTypeHandler(" + type + ")"); } Assert.notNull(type, "Type argument cannot be null"); this.type = type; } @Override protected Object parse(String json) { Type type1 = new TypeToken<Map<String, List<WeightItem>>>(){}.getType(); return gson.fromJson(json, type1); } @Override protected String toJson(Object obj) { return gson.toJson(obj); } public static void setGson(Gson gson) { Assert.notNull(gson, "Gson should not be null"); WeightListTypeHandler.gson = gson; } }
使用:
注意@TableName 注解 autoResultMap 屬性
@Data @NoArgsConstructor @TableName(value = "mix_target",autoResultMap = true) public class MixTarget extends Model<MixTarget> { @TableId(value = "id", type = IdType.AUTO) private Long id; /** *指標描述 */ @TableField("description") private String description; /** * 指標名 */ @TableField("name") private String name; /** * 對應屬性名 */ @TableField("property_name") private String propertyName; /** * 起始點類型 */ @TableField("source_type") private String sourceType; /** * 屬性對應權值列表 * key 屬性名 value指定條件下的權值 */ @TableField(value = "weight_list",typeHandler = WeightListTypeHandler.class,jdbcType = JdbcType.CLOB) private Map<String, List<WeightItem>> weightList; /** * 運行狀態 * 0 新建未運行 * 1 運行中 * 2 已運行 成功 * 3 已運行 失敗 */ @TableField("status") private Integer status; /** * 是否可用 * 1 true * 0 false */ @TableField("enable") private Integer enable; @TableField("create_time") private LocalDateTime createTime; }
讀到這里,這篇“mybatis-plus怎么配置自定義數據類型TypeHandle”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。