天天看點

使用mysql的XML Functions讓mysql schema free橫縱表方案XML Functions方案能再簡單一點嗎?更新清單參考資料:

schema free 是mongodb裡的一個重要的特性,很适合業務系統對某些非重點字段的維護,但是mongodb在運維上比mysql代價高,是以dba也不會推薦使用。一般業務系統都預設使用成熟而又穩定的mysql。

但是,<b>如何在mysql上實作schema free呢?</b>

業務系統最常見的是橫縱表方案

橫表存儲主要字段(用于查詢、排序的字段)

縱表用 key-value的形式存儲非主要字段

而當業務需要擷取一個實體時,需要在業務代碼中這樣處理

1.查詢主表

select * from main_table where id=?

2.查詢縱表

select key,value from vertical_table where obj_id=?

3.然後将這個kv結果集合塞回到實體中,然後傳回

這樣做當然可以滿足要求,但是,邏輯的複雜度增加了,不但是查詢,建立、更新、删除都需要操作2張表去完成。

當我看到了mysql的xml functions後,突然感到世界打開了一扇新的窗,完全可以通過它來實作schema free。

xml functions 的兩個函數

name

description

extractvalue()

extracts a value from an xml string using xpath notation

updatexml()

return replaced xml fragment

這樣可以查詢table1表中的memo字段裡中間的内容

可以更新table1 表中memo字段中的中間的内容為fff

我們需要做的,隻需要縱表的表中增加一個大字段(varchar(1000)?大小自己預估),然後在這個大字段存儲非主要資訊

事情到這裡是不是完成了呢?

寫這樣繁瑣的sql是不是有點複雜啊?

于是我寫了一個myibatis的攔截器,封裝的xml的操作,讓使用方感覺是在<b>操作橫表一樣去操作大字段</b>

比如:

id,title 和橫表字段,大字段是memo,author是xml節點

查詢時隻要輸入sql

就可以完成查詢,當然,在攔截器中将它轉換成了

通過myibatis的orm可以将大字段中的節點直接映射到對象屬性上

insert操作也一樣

author節點如果不存在,會在xml中新加,如果存在,會修改

下面這個是jar包

隻需要在myibatis攔截器清單中增加攔截器

1、攔截器不作用在prepare階段,改到 executor 接口

2、sql解析在第一次注冊為sqlmap,以後直接調用

3、對象不在需要memo屬性,通過cglib動态添加

4、加入 處理特殊字元

修複了如果更新字段為空時,更新不成功bug