代碼地址以下:
http://www.demodashi.com/demo/12468.htmlhtml
衆所周知,mybatis 雖然易於上手,但放到互聯網環境下使用時,不可避免的要面對諸如‘’一級緩存存在髒數據‘’、‘’須要寫大量明文 SQL 語句‘’等問題。對於這些問題 mybatis 的開發團隊選擇了一種謙遜的方式,他們開放 mybatis 接口,容許用戶開發插件,按本身的方式來解決這些問題。因而,一切 ORM 領域相關的問題在 mybatis 上經過插件都有了解決方案。java
之前咱們在 mapper.xml 中要寫很複雜的 sql 語句,但如今在 mapper.xml 中只需這樣:git
<select id="select" resultMap="result"> flying#{?}:select </select> <select id="selectOne" resultMap="result"> flying:selectOne </select> <insert id="insert"> flying:insert </insert> <update id="update"> flying:update </update> <delete id="delete"> flying:delete </delete>
再在您的實體類上加上這樣一些標註:github
package myPackage; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; @Table(name = "account") public class Account { @Id @Column private Integer id; @Column private java.lang.String name; @Column private Integer age; /* 省略 getter 和 setter */ }
flying 就徹底明白您的數據結構和您想作的事情了。 接下來您增刪改查這個實體就會變得很是簡單:web
/* 新增 */ Account newAccount = new Account(); newAccount.setName("ann"); newAccount.setAge(18); accountService.insert(newAccount); /* 按主鍵查詢 */ Account account = accountService.select(newAccount.getId()); /* 按姓名查詢,這裏忽略了年齡 */ Account accountC1 = new Account(); accountC1.setName("ann"); Account account1 = accountService.selectOne(accountC1); /* account1 和 account 表明相同的業務數據 */ /* 按年齡查詢,這裏忽略了姓名 */ Account accountC2 = new Account(); accountC2.setAge(18); Account account2 = accountService.selectOne(accountC2); /* account2 和 account 表明相同的業務數據 */ /* 按姓名和年齡查詢 */ Account accountC3 = new Account(); accountC3.setName("ann"); accountC3.setAge(18); Account account3 = accountService.selectOne(accountC3); /* account3 和 account 表明相同的業務數據 */ /* 修改 */ account.setName("bob"); accountService.update(newAccount); /* 按主鍵刪除 */ accountService.delete(newAccount);
因爲 flying 掌握了您所有的數據結構和實體關係,因此操做數據變得很是簡單,您不再須要定義 「getAccountById、getAccountByName、getAccountByAge」 這樣重複性強的方法了,由此帶來更大的好處是您的 service 層只須要關注事務方面的邏輯便可,它從低級代碼中徹底解放了出來。以上只是 flying 功能的冰山一角,其它的功能如多表聯查、分頁、樂觀鎖、跨數據源查詢、二級緩存等 flying 都有簡單的解決方案,您能夠在 flying-doc.limeng32.com 中進行查看。redis
flying 特色總結以下:算法
數據操做入參和返回類型都是自定義的實體類,徹底 no sql 杜絕各類‘’手滑‘’,項目可隨意重構。sql
支持跨表操做和跨數據源操做。apache
非侵佔工做機制,能夠和您已有的 mybatis 方法協同工做。後端
加入了優化過的緩存插件,能夠對多數據源環境下 flying 方法和傳統 mybatis 方法同時進行緩存管理。
能夠自定義主鍵生成器,全面支持或邏輯查詢。(初雪版新增特性)
flying 的 maven 座標爲:
<groupId>com.github.limeng32</groupId> <artifactId>mybatis.flying</artifactId> <version>0.9.3</version>
mybatis 版本與 flying 最新版本初雪的對應關係見下:
mybatis 版本 | flying-初雪 |
---|---|
3.3.0、3.3.1 | 0.8.3 |
3.4.0、3.4.一、3.4.二、3.4.三、3.4.四、3.4.5 | 0.9.3 |
之因此採用分版本發佈的方式是由於咱們對 mybatis 每一個版本的用戶都認真負責,力求使您獲得 flying 最大的好處。
一、將代碼搭建成 maven 項目。
二、以 maven 命令執行 tomcat7:run
如下是初始化時的添加的數據源 dataSource 和 dataSource2,將商品業務數據和用戶數據分開存放是一種常見作法。dataSource 描述了兩個購物車和 12 種商品和商品裝入購物車的狀況:
<dataset> <CART ID="1" DEAL="0" DEAL_TIME=null PERSON_ID="1"/> <CART ID="2" DEAL="0" DEAL_TIME=null PERSON_ID="2" /> <COMMODITY ID="1" NAME="牙刷A" PRICE="1200" /> <COMMODITY ID="2" NAME="牙刷B" PRICE="1850" /> <COMMODITY ID="3" NAME="牙刷C" PRICE="2100" /> <COMMODITY ID="4" NAME="佳潔士牙膏" PRICE="1499" /> <COMMODITY ID="5" NAME="六必治牙膏" PRICE="1999" /> <COMMODITY ID="6" NAME="雲南白藥牙膏" PRICE="2499" /> <COMMODITY ID="7" NAME="潘婷洗髮露" PRICE="3500" /> <COMMODITY ID="8" NAME="多芬洗髮露" PRICE="3900" /> <COMMODITY ID="9" NAME="海飛絲洗髮露" PRICE="5100" /> <COMMODITY ID="10" NAME="浴液-1500ML" PRICE="2800" /> <COMMODITY ID="11" NAME="浴液-2000ML" PRICE="3200" /> <COMMODITY ID="12" NAME="浴液-4000ML" PRICE="4900" /> <CART_COMMODITY ID="1" CART_ID="1" COMM_ID="1" AMOUNT="3" /> <CART_COMMODITY ID="2" CART_ID="1" COMM_ID="5" AMOUNT="4" /> <CART_COMMODITY ID="3" CART_ID="1" COMM_ID="8" AMOUNT="1" /> <CART_COMMODITY ID="4" CART_ID="1" COMM_ID="12" AMOUNT="1" /> <CART_COMMODITY ID="5" CART_ID="2" COMM_ID="2" AMOUNT="2" /> <CART_COMMODITY ID="6" CART_ID="2" COMM_ID="4" AMOUNT="1" /> <CART_COMMODITY ID="7" CART_ID="2" COMM_ID="9" AMOUNT="2" /> <CART_COMMODITY ID="8" CART_ID="2" COMM_ID="11" AMOUNT="1" /> </dataset>
dataSource2 描述了 3 種會員級別和 3 位用戶的狀況:
<dataset> <ROLE ID="1" NAME="普通會員" VALUE="normal" /> <ROLE ID="2" NAME="銀牌會員" VALUE="silver" /> <ROLE ID="3" NAME="金牌會員" VALUE="gold" /> <PERSON ID="1" NAME="張三" ROLE_ID="1" /> <PERSON ID="2" NAME="李四" ROLE_ID="2" /> <PERSON ID="3" NAME="王五" ROLE_ID="3" /> </dataset>
運行起來後,具體的功能訪問頁面能夠用以下方式訪問到,在瀏覽器中輸入如下 url 能夠看到效果:
查看購物車: http://localhost:8080/flying-demo2/getCart?id=${購物車cart的id}
查看商品: http://localhost:8080/flying-demo2/getCommodity?id=${商品commodity的id}
翻頁查看商品(全部條件均爲可選): http://localhost:8080/flying-demo2/getCommodityInPage?pageNum=${頁碼}&priceOrder=${按價格升序或降序輸入asc或desc}&priceFrom=${價格最小值}&priceTo=${價格最大值}
增長新商品: http://localhost:8080/flying-demo2/addCommodity?name=${新商品名稱}&price=${新商品價格}
編輯商品: http://localhost:8080/flying-demo2/updateCommodity?id=${商品的id}&name=${商品的名稱}&price=${商品的價格}
查看購物車中的商品: http://localhost:8080/flying-demo2/getCommodityByCart?id=${購物車的id}
對購物車進行結帳: http://localhost:8080/flying-demo2/dealCart?id=${購物車的id}
取消購物車的結帳: http://localhost:8080/flying-demo2/undealCart?id=${購物車的id}
查看用戶: http://localhost:8080/flying-demo2/getPerson?id=${用戶的id}
查看會員級別: http://localhost:8080/flying-demo2/getRole?id=${會員級別的id}
編輯會員級別: http://localhost:8080/flying-demo2/updateRoleDirectly?id=${會員級別的id}&name=${會員級別的名稱}
查詢匹配兩個級別值(如gold、silver、normal)的會員級別(使用或邏輯特性):
http://localhost:8080/flying-demo2/getRoleValue1OrValue2?value1=${級別值1}&value2=${級別值2}
查詢會員級別值(如gold、silver、normal)或用戶名稱匹配給定值的用戶(使用外鍵或邏輯特性)
http://localhost:8080/flying-demo2/getRoleValueOrPersonName?value=${級別值}&name=${用戶名稱}
向當前購物車加入/刪除商品(amount爲負數時爲刪除),並自動處理最終結果(用來展現雙向相關算法下處理業務模型的優雅)
http://localhost:8080/flying-demo2/addCommodityToCart?cartId=${購物車的id}&commId=${商品的id}&amount=${購買數量}
按兩個用戶id查詢購買的商品詳情(使用跨庫或邏輯特性)
http://localhost:8080/flying-demo2/getCartCommodityByPersonId1OrId2?id1=${用戶id1}&id2=${用戶id2}
不刷新緩存的編輯會員級別:http://localhost:8080/flying-demo2/updateRoleDirectlyWithoutCache?id=${會員級別的id}&name=${會員級別的名稱}
以上方法的實現代碼可見: https://github.com/limeng32/flying-demo2/blob/use-flying-0.9.3/src/main/java/indi/demo/flying/web/CommonController.java
從 use-flying-0.9.3
分支開始咱們採用雙向相關的方式構建 pojo,以求打造一個真實可用的電商前臺,關於雙向相關的詳細信息請見: https://my.oschina.net/u/2280950/blog/1580056
以上API方法除最後一個外,其他均支持了二級緩存。您能夠調用 updateRoleDirectlyWithoutCache
修改會員級別名稱,以後調用 getRole
能看到新的名稱,但調用 getCart
和 getCommodityByCart
則只能看到修改前的名稱,這是由於 updateRoleDirectlyWithoutCache
設計爲不支持二級緩存,從這裏能夠看出緩存確實發揮了做用;若是您調用 updateRoleDirectly
修改會員級別名稱,在調用 getRole
、getCart
和 getCommodityByCart
都會顯示出新的名稱,由於 updateRoleDirectly
設計爲支持二級緩存。若是再使用 redis 託管 mybatis 的二級緩存,就成爲了可擴展的緩存解決方案,不過這已超過本例的討論範圍。
updateRoleDirectly
和 updateRoleDirectlyWithoutCache
都是普通 mybatis 方法而非 flying 自動映射方法,這個例子也說明改造 mybatis 二級緩存的插件可供 flying 自動映射方法和非 flying 自動映射方法同時工做。
最後,flying 項目介紹請見 flying-doc.limeng32.com ,咱們爲開發最好的 mybatis 插件而努力。
使用 mybatis + flying + 雙向相關建模 的電商後端
代碼地址以下:
http://www.demodashi.com/demo/12468.html
注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權