摘要:一套數(shù)據(jù)庫的微型庫,提供簡(jiǎn)單高效的來操作數(shù)據(jù)庫。讓開發(fā)者不需要關(guān)心數(shù)據(jù)庫操作的具體細(xì)節(jié),只需專注和業(yè)務(wù)邏輯。和是兩個(gè)事務(wù)方法,他們之間完全隔離,提交和回滾互不影響。
Sqlla
一套數(shù)據(jù)庫的 ORM 微型庫,提供簡(jiǎn)單高效的 API 來操作數(shù)據(jù)庫。
簡(jiǎn)單使用Sqlla 擁有極少的API,使用方式簡(jiǎn)單。讓開發(fā)者不需要關(guān)心數(shù)據(jù)庫操作的具體細(xì)節(jié),只需專注SQL和業(yè)務(wù)邏輯。同時(shí)簡(jiǎn)單的事務(wù)模型讓開發(fā)過程增益很多。
創(chuàng)建實(shí)體類,用 @SqllaEntity 標(biāo)識(shí)
@SqllaEntity public class UserBean { private String uid; private String phone; private String name; // 使用 SqllaColumnAlias 標(biāo)識(shí)后的屬性使用 alias 的值來對(duì)應(yīng)表中的列 // 沒有標(biāo)識(shí)時(shí)直接使用屬性的名字來對(duì)應(yīng) @SqllaColumnAlias("gender") private int sex; // setter getter here }
DAO 接口類
public interface UserDao { // 用 @Sql 標(biāo)識(shí) @Sql("select * from t_user where uid = ?") UserBean getUserById(String uid); @Sql("select * from t_user desc by lastActiveTS limit ?") ListtopUsers(int limit); @Sql("select (count(*) > 0) from t_user where name = ?") boolean userExist(String name); @Sql("insert into t_user (id, uid, name, phone) values (null, ?, ?, ?)") boolean insertUser(String uid, String name, String phone); @Sql("delete from t_user where uid = ?") boolean deleteUserById(String uid); }
創(chuàng)建 Sqlla 實(shí)例
Sqlla.ConnectionPool pool = your implimention; Sqlla sqlla = new Sqlla.Builder().pool(pool).build();
數(shù)據(jù)庫操作 CRUD
UserDao dao = sqlla.createApi(UserDao.class); // 獲取結(jié)果集中的第一個(gè)對(duì)象(結(jié)果集的第一行) UserBean bean = dao.getUserById("uid_10000001"); // 查詢最新的10個(gè)用戶 ListbeanList = dao.topUsers(10); // 查詢用戶是否存在:對(duì)于updateable sql, 返回值可以是int, boolean(>0 for true), void boolean exists = dao.userExist("李多情"); // 插入用戶到數(shù)據(jù)庫(update count > 0 for true) boolean inserted = dao.insertUser("uid_10000002", "李明洙", "1324113361*"); // 刪除指定用戶 boolean deleted = dao.deleteUserById("uid_10000003");
概念DAO接口不需要任何的實(shí)現(xiàn)類,是不是使用非常簡(jiǎn)單??
實(shí)體: 庫中預(yù)置了兩種實(shí)體模型
@SqllaEntity 標(biāo)識(shí)的Pojo實(shí)體
ViewObject 結(jié)果集視圖實(shí)體,代表著結(jié)果集的一樣。類似于扁平的 JSONObject
轉(zhuǎn)換器: 將結(jié)果集轉(zhuǎn)換成實(shí)體的部件,可以自定義
DAO接口: CRUD操作集合,每個(gè)方法代表一條SQL操作
事務(wù): Transaction
Sqlla.Builder 提供 pool() 和 addConverterFactory() 方法。
pool()方法必須設(shè)置一個(gè)ConnectionPool實(shí)例(test 代碼提供了一個(gè)基于c3p0數(shù)據(jù)源的 pool)。
addConverterFactory() 方法設(shè)置 自定義的結(jié)果集轉(zhuǎn)換工廠(實(shí)現(xiàn) ResultConverter.Factory 接口)。 內(nèi)部預(yù)置了三種工廠,
PrimitiveTypeConverterFactory 轉(zhuǎn)換基礎(chǔ)數(shù)據(jù)類型
SqllaEntityConverterFactory 轉(zhuǎn)換 @SqllaEntity 表示的實(shí)體類和其列表(List)
ViewObjectConverterFactory 轉(zhuǎn)換 ViewObject 結(jié)果集視圖和其列表(List
事物支持外部可以自定義針對(duì)自己特定類型的轉(zhuǎn)換工廠 (ResultSet --> CustomType),自定義的轉(zhuǎn)換工廠 return !null 時(shí)會(huì)攔截系統(tǒng)預(yù)置的轉(zhuǎn)換工廠。
當(dāng)前版本對(duì)事物進(jìn)行了簡(jiǎn)單的支持,與Spring的配合暫時(shí)沒有做過測(cè)試。
例子Boolean ret = sqlla.transact(new Transaction(Isolation.SERIALIZABLE) { public Boolean transact() throw Exception { UserDao dao = sqlla.createApi(UserDao.class); dao.deleteUserById("uid_10000004"); // 也可以手動(dòng)rollback() or commit(true) dao.deleteUserById("uid_10000005"); return true; } }, false); // failed value
上面的代碼執(zhí)行了一個(gè)簡(jiǎn)單的事務(wù),事務(wù)中包含兩條刪除語句。如果都成功,則自動(dòng) commit;只要有一個(gè)失敗,則會(huì)rollback。當(dāng)回滾之后,事務(wù)將返回給定的 failed value。在事務(wù)中,也可以手動(dòng) rollback() 或者 commit(val),這兩個(gè)操作只能調(diào)用一次,而且會(huì)中斷其后面的代碼執(zhí)行,要謹(jǐn)慎使用。
void sqlla.transact(Transaction0 transaction);
注意: transact方法是一個(gè)同步方法,它會(huì)立馬調(diào)用transaction, 并返回。
Transaction
Sqlla 對(duì)事務(wù)的嵌套提供了簡(jiǎn)單的支持。相比于Spring事務(wù)間的多種傳播機(jī)制,Sqlla只提供了 REQUIRES_NEW 的傳播機(jī)制:內(nèi)層和外層完全隔離開來,互不影響。
methodA 和 methodB 是兩個(gè)事務(wù)方法,他們之間完全隔離,提交和回滾互不影響。
public void methodA() { sqlla.transact(new Transaction0() { protected void transact0() throws Exception { UserDao dao = sqlla.createApi(UserDao.class); boolean inserted = dao.insertUser("uid_1000007", "王五", "13241133615"); methodB(); // 事務(wù)B方法 boolean deleted = dao.deleteUserByName("張三"); } }); } public void methodB() { sqlla.transact(new Transaction0() { protected void transact0() throws Exception { UserDao dao = sqlla.createApi(UserDao.class); boolean inserted = dao.insertUser("uid_1000008", "趙六", "13241133616"); } } }
如何驗(yàn)證兩個(gè)事務(wù)之間互不影響?
我們先把 mehtodA 中的 deleteUserByName 方法的sql改成一個(gè)錯(cuò)的sql
@Sql("delete from t_user where name = ????????") boolean deleteUserByName(String name);
現(xiàn)在再調(diào)用 methodA,你會(huì)發(fā)現(xiàn) “王五” 這個(gè)用戶并未插入到數(shù)據(jù)庫中, “張三” 也沒有被刪除,而 “趙六” 卻實(shí)實(shí)在在的插入到了數(shù)據(jù)庫中。
注意:假如 methodB 本身并不是一個(gè)多帶帶的事務(wù)方法 (未用 sqlla.transact 開啟),那么他將使用外層的事務(wù)。所以要不要使用事務(wù),一定要考慮好,不然可能會(huì)有一些意想不到的效果。
Sqlla雖然提供了注解的方式來操作SQL,但是事務(wù)并沒有使用注解的方式, 這和MyBatis一致。實(shí)際內(nèi)部實(shí)現(xiàn)也和 MyBatis 相差無幾。
GitHub鏈接
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70066.html
摘要:支持設(shè)置圓角,并且能夠精確的控制圓角位置。如果你想要設(shè)置的顯示出來,必須設(shè)置為。如此驚艷的效果得益于內(nèi)置的動(dòng)畫驅(qū)動(dòng),你能夠結(jié)合來實(shí)現(xiàn)難以置信的動(dòng)畫效果。一切只需要在你合理的編寫好后,調(diào)用和來啟動(dòng)停止動(dòng)畫。 showImg(https://segmentfault.com/img/remote/1460000009148011); 簡(jiǎn)介 歡迎使用SuperTextView,這篇文檔將會(huì)向...
摘要:版本以上的分頁比之前的更簡(jiǎn)單和人性化首先獲取到數(shù)據(jù),方法能夠自動(dòng)判定當(dāng)前頁面正確的數(shù)量限制和偏移數(shù)。默認(rèn)情況下,當(dāng)前頁數(shù)由請(qǐng)求所帶的參數(shù)來決定。當(dāng)然,該值由自動(dòng)檢測(cè),并自動(dòng)插入由分頁器生成的鏈接。 laravel5.3版本以上的分頁比之前的更簡(jiǎn)單和人性化 1.首先獲取到數(shù)據(jù),paginate方法 能夠自動(dòng)判定當(dāng)前頁面正確的數(shù)量限制和偏移數(shù)。默認(rèn)情況下,當(dāng)前頁數(shù)由HTTP 請(qǐng)求所帶的 ...
摘要:作為解決方案的和和是解決短時(shí)記憶問題的解決方案,它們具有稱為門的內(nèi)部機(jī)制,可以調(diào)節(jié)信息流。隨后,它可以沿著長(zhǎng)鏈序列傳遞相關(guān)信息以進(jìn)行預(yù)測(cè),幾乎所有基于遞歸神經(jīng)網(wǎng)絡(luò)的技術(shù)成果都是通過這兩個(gè)網(wǎng)絡(luò)實(shí)現(xiàn)的。和采用門結(jié)構(gòu)來克服短時(shí)記憶的影響。 短時(shí)記憶RNN 會(huì)受到短時(shí)記憶的影響。如果一條序列足夠長(zhǎng),那它們將很難將信息從較早的時(shí)間步傳送到后面的時(shí)間步。 因此,如果你正在嘗試處理一段文本進(jìn)行預(yù)測(cè),RNN...
閱讀 3626·2021-11-22 15:22
閱讀 2604·2021-09-06 15:00
閱讀 1046·2020-06-22 14:39
閱讀 3855·2019-08-30 15:56
閱讀 1683·2019-08-30 12:55
閱讀 3579·2019-08-29 17:19
閱讀 3374·2019-08-26 11:41
閱讀 780·2019-08-23 17:14