日韩精品中文字幕久久臀_天堂av在线一区_午夜精品视频网站_99r精品视频_国产日韩亚洲欧美_亚洲欧美国产一本综合首页_日本一区二区三区久久久久久久久不 _国产精品高潮视频_久热99视频在线观看_91伊人久久大香线蕉

天天報(bào)道:最近火起的 Bean Searcher 與 MyBatis Plus 到底有啥區(qū)別?

2023-06-19 10:18:04 來(lái)源:互聯(lián)網(wǎng)

往期熱門(mén)文章:

1、別再重復(fù)造輪子了,一個(gè) Spring 注解輕松搞定循環(huán)重試功能!


(資料圖片)

2、2023最新互聯(lián)網(wǎng)公司時(shí)長(zhǎng)排行榜出爐!

3、棄用 Nginx 后!它成為了最受歡迎 Web 服務(wù)器。。。

4、計(jì)算機(jī)會(huì)成為下一個(gè)土木嗎?

5、干掉Maven和Gradle!推出更強(qiáng)更快更牛逼的新一代構(gòu)建工具,炸裂!

Bean Searcher 號(hào)稱 任何復(fù)雜的查詢都可以 一行代碼搞定,但 Mybatis Plus 似乎也有類似的動(dòng)態(tài)查詢功能,它們有怎樣的區(qū)別呢?

區(qū)別一(基本)

Mybatis Plus 依賴 MyBatis, 功能 CRUD 都有,而 Bean Seracher 不依賴任何 ORM,只專注高級(jí)查詢。

只有使用 MyBatis 的項(xiàng)目才會(huì)用 Mybatis Plus,而使用 Hibernate,Data Jdbc 等其它 ORM 的人則無(wú)法使用 Mybatis Plus。但是這些項(xiàng)目都可以使用 Bean Searcher(可與任何 ORM 配合使用,也可單獨(dú)使用)。

使用 Mybatis Plus 需要編寫(xiě)實(shí)體類 和 Mapper 接口,而 Bean Searcher 只需編寫(xiě) 實(shí)體類,無(wú)需編寫(xiě)任何接口。

這個(gè)區(qū)別意義其實(shí)不大,因?yàn)槿绻阌?Mybatis Plus,在增刪改的時(shí)候還是需要定義 Mapper 接口。

區(qū)別二(高級(jí)查詢)

Mybatis Plus 的 字段運(yùn)算符 是靜態(tài)的,而 Bean Searcher 的是動(dòng)態(tài)的。

字段運(yùn)算符指的是某字段參與條件時(shí)用的是=、>亦或是like這些條件類型。不只 Mybatis Plus,一般的傳統(tǒng) ORM 的字段運(yùn)算符都是靜態(tài)的,包括 Hibernate、Spring data jdbc、JOOQ 等。

下面舉例說(shuō)明。對(duì)于只有三個(gè)字段的簡(jiǎn)單實(shí)體類:

publicclassUser{ privatelongid; privateString name; privateintage; // 省略 Getter Setter}

1)使用 MyBatis Plus 查詢:

依賴:

implementation "com.baomidou:mybatis-plus-boot-starter:3.5.2

首先要寫(xiě)一個(gè) Mapper 接口:

publicinterfaceUserMapperextendsBaseMapper {}

然后在 Controller 里寫(xiě)查詢接口:

@RestController@RequestMapping("/user")publicclassUserController{ @AutowiredprivateUserMapper userMapper; @GetMapping("/mp")publicList mp(User user) { returnuserMapper.selectList(newQueryWrapper<>(user)); } }

此時(shí)這個(gè)接口可以支持 三個(gè)檢索參數(shù),id, name, age,例如:

GET /user/mp? name=Jack查詢 name等于Jack 的數(shù)據(jù)

GET /user/mp? age=20查詢 age等于20 的數(shù)據(jù)

但是他們所能表達(dá)的關(guān)系都是等于,如果你還想查詢age > 20的數(shù)據(jù),則無(wú)能為力了,除非在實(shí)體類的 age 字段上加上一條注解:

@TableField(condition = "%s>#{%s}")privateintage;

但加了注解后,age 就只能表達(dá)大于的關(guān)系了,不再可以表達(dá) 等于了。所以說(shuō),MyBatit Plus 的字段運(yùn)算符靜態(tài)的,不能由參數(shù)動(dòng)態(tài)指定。

當(dāng)然我們可以在 Controller 里根據(jù)參數(shù)調(diào)用 QueryWrapper 的不同方法讓它支持,但這樣代碼就不只一行了,檢索的需求越復(fù)雜,需要編寫(xiě)的代碼就越多了。

2)使用 Bean Searcher 查詢:

依賴:

implementation "cn.zhxu:bean-searcher-boot-starter:4.1.2"

不用編寫(xiě)任何接口,復(fù)用同一個(gè)實(shí)體類,直接進(jìn)行查詢:

@RestController@RequestMapping("/user")publicclassUserController{ @AutowiredprivateBeanSearcher beanSearcher; @GetMapping("/bs")publicList bs(@RequestParamMap params) { // 你是否對(duì)入?yún)?Map 有偏見(jiàn)?如果有,請(qǐng)耐心往下看,有方案 returnbeanSearcher.searchList(User.class, params); } }

此時(shí)這個(gè)接口可以支持的檢索參數(shù)就非常多了:

GET /user/bs? name=Jack查詢 name等于Jack 的數(shù)據(jù)

GET /user/bs? name=Jack & name-ic=true查詢 name等于Jack 時(shí)忽略大小寫(xiě)

GET /user/bs? name=Jack & name-op=ct查詢 name包含Jack 的數(shù)據(jù)

GET /user/bs? age=20查詢 age等于20 的數(shù)據(jù)

GET /user/bs? age=20 & age-op=gt查詢 age大于20 的數(shù)據(jù)

等等...

可以看出,Bean Searcher對(duì)每個(gè)字段使用的運(yùn)算符都可以由參數(shù)指定,它們是動(dòng)態(tài)的。

無(wú)論查詢需求簡(jiǎn)單還是復(fù)雜,Controller 里都只需一行代碼。參數(shù)xxx-op可以傳哪些值?參閱這里:bs.zhxu.cn/guide/lates…

看到這里,如果看的明白,應(yīng)該有一半的讀者開(kāi)始感慨:好家伙,這不是把后端組裝查詢條件的過(guò)程都甩給了前端?誰(shuí)用了這個(gè)框架,不會(huì)被前端打死嗎?

哈哈,我是不是道出了你現(xiàn)在心里的想法?如果你真的如此想,請(qǐng)仔細(xì)回看我們正在討論的主題:【高級(jí)查詢】! 如果不能理解什么是高級(jí)查詢,我再貼個(gè)圖助你思考

當(dāng)然也并不是所有的檢索需求都如此復(fù)雜,當(dāng)前端不需要控制檢索方式時(shí),xxx-op參數(shù) 可以省略,省略時(shí),默認(rèn)表達(dá)的是等于,如果你想表達(dá) 其它方式,只需一個(gè)注解即可,例如:

@DbField(onlyOn = GreaterThan.class)privateintage;

這時(shí),當(dāng)前端只傳一個(gè)age參數(shù)時(shí),執(zhí)行的 SQL 條件就是age > ?了,并且即使前端多傳一個(gè)age-op參數(shù),也不再起作用了。

這其實(shí)是條件約束,下文會(huì)繼續(xù)講到。

區(qū)別三(邏輯分組)

就上文所例的代碼,除卻運(yùn)算符 動(dòng)靜 的區(qū)別,Mybatis Plus 對(duì)接收到的參數(shù)生成的條件 都是且的關(guān)系,而 Bean Searcher 默認(rèn)也是且,但支持 邏輯分組。

再舉例說(shuō)明,假設(shè)查詢條件為:

(name = Jack 并且 age = 20)或者(age = 30)

此時(shí),MyBatis Plus 的一行代碼就無(wú)能為力了,但 Bean Searcher 的一行代碼仍然管用,只需這樣傳參即可:

GET /user/bs? a.name=Jack & a.age=20 & b.age=30 & gexpr=a|b

這里 Bean Searcher 將參數(shù)分為a,b兩組,并用新參數(shù)gexpr來(lái)表達(dá)這兩組之間的關(guān)系(a或b)。

實(shí)際傳參時(shí)gexpr的值需要URLEncode編碼一下: URLEncode("a|b") => "a%7Cb",因?yàn)?HTTP 規(guī)定參數(shù)在 URL 上不可以出現(xiàn)|這種特殊字符。當(dāng)然如果你喜歡 POST, 可以將它放在報(bào)文體里。

什么場(chǎng)景下適合使用此功能?當(dāng)遇見(jiàn)類似下圖中的需求時(shí),它將助你一招制敵:

分組功能非常強(qiáng)大,但如此復(fù)雜的檢索需求也確實(shí)罕見(jiàn),這里不再細(xì)述,詳情可閱:bs.zhxu.cn/guide/lates…

區(qū)別四(多表聯(lián)查)

在不寫(xiě) SQL 的情況下,Mybatis Plus 的動(dòng)態(tài)查詢 僅限于 單表,而 Bean Searcher 單表 和 多表 都支持的一樣好。

這也是很重要的一點(diǎn)區(qū)別,因?yàn)?strong>大多數(shù)高級(jí)查詢場(chǎng)景都是需要聯(lián)表的。

當(dāng)然有些人堅(jiān)持用單表做查詢,為了避免聯(lián)表,從而在主表中冗余了很多字段,這不僅造成了 數(shù)據(jù)庫(kù)存儲(chǔ)空間壓力急劇增加,還讓項(xiàng)目更加難以維護(hù)。因?yàn)樵磾?shù)據(jù)一但變化,你必須同時(shí)更新這些冗余的字段,只要漏了一處,BUG 就跳出來(lái)了。

還是舉個(gè)例子,某訂單列表需要展示 訂單號(hào),訂單金額,店鋪名,買家名 等信息,用 Bean Searcher 實(shí)體類可以這么寫(xiě):

@SearchBean(tables = "order o, shop s, user u", // 三表關(guān)聯(lián) where = "o.shop_id = s.id and o.buyer_id = u.id", // 關(guān)聯(lián)關(guān)系 autoMapTo = "o" // 未被 @DbField 注解的字段都映射到 order 表)publicclassOrderVO{ privatelongid; // 訂單ID o.id privateString orderNo; // 訂單號(hào) o.order_no privatelongamount; // 訂單金額 o.amount @DbField("s.name")privateString shop; // 店鋪名 s.name @DbField("u.name")privateString buyer; // 買家名 u.name // 省略 Getter Setter}

有心的同學(xué)會(huì)注意到,這個(gè)實(shí)體類的命名并不是 Order, 而是 OrderVO。這里只是一個(gè)建議的命名,因?yàn)樗潜举|(zhì)上就是一個(gè) VO(View Object),作用只是一個(gè)視圖實(shí)體類,所以建議將它和普通的單表實(shí)體類放在不同的 package 下(這只是一個(gè)規(guī)范)。

然后我們的 Controller 中仍然只需一行代碼:

@RestController@RequestMapping("/order")publicclassOrderController{ @AutowiredprivateBeanSearcher beanSearcher; @GetMapping("/index")publicSearchResult index(@RequestParamMap params) { // search 方法同時(shí)會(huì)返回滿足條件的總條數(shù) returnbeanSearcher.search(OrderVO.class, params); }}

這就實(shí)現(xiàn)了一個(gè)支持高級(jí)查詢的 訂單接口,它同樣支持在上文區(qū)別二區(qū)別三中所展示的各種檢索方式。

從本例可以看出,Bean Searcher 的檢索結(jié)果是 VO 對(duì)象,而非普通的單表實(shí)體類(DTO),這省去了 DTO 向 VO 的轉(zhuǎn)換過(guò)程,它可以直接返回給前端。

區(qū)別五(使用場(chǎng)景)

在事務(wù)性的接口用推薦使用 MyBatis Plus, 非事務(wù)的檢索接口中推薦使用 Bean Searcher

例如 創(chuàng)建訂單接口,在這個(gè)接口內(nèi)部同樣有很多查詢,比如你需要查詢 店鋪的是否已經(jīng)打烊,商品的庫(kù)存是否還足夠等,這些查詢場(chǎng)景,推薦依然使用 原有的 MyBatis Plus 或其它 ORM 就好,不必再用 Bean Seracher 了。

再如 訂單列表接口,純查詢,可能需要分頁(yè)、排序、過(guò)濾等功能,此時(shí)就可用 Bean Seracher 了。

網(wǎng)友疑問(wèn)

1)這貌似開(kāi)放很大的檢索能力,風(fēng)險(xiǎn)可控嗎?

Bean Searcher 默認(rèn)對(duì)實(shí)體類中的每個(gè)字段都支持了很多種檢索方式,但是我們也可以對(duì)它進(jìn)行約束。

條件約束

例如,User實(shí)體類的name字段只允許 精確匹配 與 后模糊 查詢,則在name字段上添加一個(gè)注解即可:

@DbField(onlyOn = {Equal.class, StartWith.class})privateString name;

再如:不允許age字段參與 where 條件,則可以:

@DbField(conditional = false)privateintage;

參考:bs.zhxu.cn/guide/lates…

排序約束

Bean Searcher 默認(rèn)允許按所有字段排序,但可以在實(shí)體類里進(jìn)行約束。例如,只允許按 age 字段降序排序:

@SearchBean(orderBy = "age desc", sortType = SortType.ONLY_ENTITY)publicclassUser{ // ...}

或者,禁止使用排序:

@SearchBean(sortType = SortType.ONLY_ENTITY)publicclassUser{ // ...}

參考:bs.zhxu.cn/guide/lates…

2)使用 Bean Searcher 后 Controller 的入?yún)⒈仨毷?Map 類型?

:這并不是必須的,只是 Bean Searcher 的檢索方法接受這個(gè)類型的參數(shù)而已。如果你在 Controller 入?yún)⒛抢?用一個(gè) POJO 來(lái)接收也是可以的,只需要再用一個(gè)工具類把它轉(zhuǎn)換為Map即可,只不過(guò)平白多寫(xiě)了一個(gè)類而已,例如:

@GetMapping("/bs")publicList bs(UserQuery query) { // 將 UserQuery 對(duì)象轉(zhuǎn)換為 Map 再傳入進(jìn)行檢索 returnbeanSearcher.searchList(User.class, Utils.toMap(query));}

這里為什么不直接使用 User 實(shí)體類來(lái)接收呢?因?yàn)?Bean Searcher 默認(rèn)支持很多參數(shù),而原有的User實(shí)體類中的字段不夠多,用它來(lái)接收的話會(huì)有很多參數(shù)接收不到。如果咱們的檢索需求比較簡(jiǎn)單,不需要前端指定那些參數(shù),則可以直接使用User實(shí)體類來(lái)接收。

這里的UserQuery可以這么定義:

// 繼承 User 里的字段publicclassUserQueryextendsUser{ // 附加:排序參數(shù) privateString order; privateString sort; // 附加:分頁(yè)參數(shù) privateInteger page; privateInteger size; // 附加:字段衍生參數(shù) privateString id_op; // 由于字段命名不能有中劃線,這里有下劃線替代 privateString name_op; // 前端傳參的時(shí)候就不能傳 name-op,而是 name_op 了 privateString name_ic; privateString age_op; // 省略其它附加字段... // 省略 Getter Setter 方法}

然后Utils工具類的toMap方法可以這樣寫(xiě)(這個(gè)工具類是通用的):

publicstaticMap toMap(Object bean) { Map map = newHashMap<>(); Class beanClass = bean.getClass(); while(beanClass != Object.class) { for(Field field : beanClass.getDeclaredFields()) { field.setAccessible(true); try{ // 將下劃線轉(zhuǎn)換為中劃線 Strubgname = field.getName().replace("_", "-"); map.put(name, field.get(bean)); } catch(IllegalAccessException e) { thrownewRuntimeException(e); } } beanClass = beanClass.getSuperclass(); } returnmap;}

這樣就可以了,該接口依然可以支持很多種檢索方式:

GET /user/bs? name=Jack查詢 name等于Jack 的數(shù)據(jù)

GET /user/bs? name=Jack &name_ic=true查詢 name等于Jack 時(shí)忽略大小寫(xiě)

GET /user/bs? name=Jack &name_op=ct查詢 name包含Jack 的數(shù)據(jù)

GET /user/bs? age=20查詢 age等于20 的數(shù)據(jù)

GET /user/bs? age=20 &age_op=gt查詢 age大于20 的數(shù)據(jù)

等等...

注意使用參數(shù)是name_op,不再是name-op了

以上的方式應(yīng)該滿足了一些強(qiáng)迫癥患者的期望,但是這樣的代價(jià)是多寫(xiě)一個(gè)UserQuery類,這不禁讓我們細(xì)想:這樣做值得嗎?

當(dāng)然,寫(xiě)成這樣是有一些好處的:

便于參數(shù)校驗(yàn)

便于生成接口文檔

但是:

這是一個(gè)非事務(wù)性的檢索接口,參數(shù)校驗(yàn)真的那么必要嗎?本來(lái)就可以無(wú)參請(qǐng)求,參數(shù)傳錯(cuò)了系統(tǒng)自動(dòng)忽略它是不是也可以?

如果了解了 Bean Searcher 參數(shù)規(guī)則,是不是不用這個(gè)UserQuery類也可以生成文檔,或者在文檔中一句話概括該接口是 Bean Searcher 檢索接口,請(qǐng)按照規(guī)則傳遞參數(shù),是不是也行呢?

所以,我的建議是:一切以真實(shí)需求為準(zhǔn)則,不要為了規(guī)范而去規(guī)范,莫名徒增代碼。

看到這里,你可能已經(jīng)在心里準(zhǔn)備了一大堆的話想要反駁我,別急,我們先回顧一下前面的 [多表聯(lián)查] 章節(jié)所提到的:

Bean Searcher 中的實(shí)體類(SearchBean),實(shí)際上是一個(gè)可以 直接與 DB 有跨表映射關(guān)系 的VO(View Ojbect),它代表一種檢索業(yè)務(wù),在概念上它與傳統(tǒng) ORM 的實(shí)體類(Entity)或 域類(Domain)有著本質(zhì)的區(qū)別!

這一句話,道出了 Bean Searcher 的靈魂。它看似簡(jiǎn)單,實(shí)則難以悟透。如果您不是那種千古罕見(jiàn)先天通靈的奇才,強(qiáng)烈建議閱讀官方文檔的介紹 > 設(shè)計(jì)思想(出發(fā)點(diǎn))章節(jié),那里有對(duì)這一句話的詳細(xì)解釋。

3)想手動(dòng)添加或修改參數(shù),只能向Map里put嗎?有沒(méi)有優(yōu)雅點(diǎn)寫(xiě)法?

答:當(dāng)然有。Bean Searcher 提供了一個(gè)參數(shù)構(gòu)建器,可讓后端人員想手動(dòng)添加或修改檢索參數(shù)時(shí)使用。例如:

@GetMapping("/bs")publicList bs(@RequestParamMap params) { params = MapUtils.builder(params) // 在原有參數(shù)基礎(chǔ)之上 .field(User::getAge, 20, 30).op(Between.class) // 添加一個(gè)年齡區(qū)間條件 .field(User::getName).op(StartWith.class) // 修改 name 字段的運(yùn)算符為 StartWith,參數(shù)值還是用前端傳來(lái)的參數(shù) .build(); returnbeanSearcher.searchList(User.class, params);}

4)前端亂傳參數(shù)的話,存在 SQL 注入風(fēng)險(xiǎn)嗎?

答:不存在的,Bean Searcher 是一個(gè)只讀 ORM,它也存在對(duì)象關(guān)系映射,所傳參數(shù)都是實(shí)體類內(nèi)定義的 Java 屬性名,而非數(shù)據(jù)庫(kù)表里的字段名(當(dāng)前端傳遞實(shí)體類未定義的字段參數(shù)時(shí),會(huì)被自動(dòng)忽略)。

也可以說(shuō):檢索參數(shù)與數(shù)據(jù)庫(kù)表是解耦的

5)可以隨意傳參,會(huì)讓用戶獲取本不該看到的數(shù)據(jù)嗎?

答:不會(huì)的,因?yàn)橛脩?strong>可獲取數(shù)據(jù)最多的請(qǐng)求就是無(wú)參請(qǐng)求,用戶嘗試的任何參數(shù),都只會(huì)縮小數(shù)據(jù)范圍,不可能擴(kuò)大

如果想做數(shù)據(jù)權(quán)限,根據(jù)不同的用戶返回不同的數(shù)據(jù):可在參數(shù)過(guò)濾器里為權(quán)限字段統(tǒng)一注入條件(前提是 實(shí)體類中得有一個(gè)數(shù)據(jù)權(quán)限字段,可以在基類中定義)。

6)效率雖有提高,但性能如何呢?

前段時(shí)間又不少朋友看了這篇文章私下問(wèn)我 Bean Searcher 的性能如何,這個(gè)周末我就在家做了下對(duì)比測(cè)試,結(jié)果如下:

比 Spring Data Jdbc 高5 ~ 10

比 Spring Data JPA 高2 ~ 3

比 原生 MyBatis 高1 ~ 2

比 MyBatis Plus 高2 ~ 5

完整報(bào)告:

github.com/troyzhxu/be…

gitee.com/troyzhxu/be…

以上測(cè)試是基于 H2 內(nèi)存數(shù)據(jù)庫(kù)進(jìn)行

測(cè)試源碼地址,大家可自行測(cè)試對(duì)比:

github.com/troyzhxu/be…

gitee.com/troyzhxu/be…

7)支持哪些數(shù)據(jù)庫(kù)呢?

只要支持正常的 SQL 語(yǔ)法,都是支持的,另外 Bean Searcher 內(nèi)置了四個(gè)方言實(shí)現(xiàn):

分頁(yè)語(yǔ)法和 MySQL 一樣的數(shù)據(jù)庫(kù),默認(rèn)支持

分頁(yè)語(yǔ)法和 PostgreSql 一樣的數(shù)據(jù)庫(kù),選用 PostgreSql 方言 即可

分頁(yè)語(yǔ)法和 Oracle 一樣的數(shù)據(jù)庫(kù),選用 Oracle 方言 即可

分頁(yè)語(yǔ)法和 SqlServer(v2012+)一樣的數(shù)據(jù)庫(kù),選用 SqlServer 方言 即可

如果分頁(yè)語(yǔ)法獨(dú)創(chuàng)的,自定義一個(gè)方言,只需實(shí)現(xiàn)一個(gè)方法即可,參考:高級(jí) > SQL 方言章節(jié)。

總結(jié)

上文所述的各種區(qū)別,并不是說(shuō) MyBatis Plus 和 Bean Searcher 哪個(gè)好哪個(gè)不好,而是它們專注的領(lǐng)域確實(shí)不一樣(BS 也不會(huì)替代 MP)。

Bean Searcher 在剛誕生的時(shí)候是專門(mén)用來(lái)處理那種特別復(fù)雜的檢索需求(如上文中的例圖所示),一般都用在管理后臺(tái)系統(tǒng)里。但用著用著,我們發(fā)現(xiàn),對(duì)檢索需求沒(méi)那么復(fù)雜的普通分頁(yè)查詢接口,Bean Searcher 也非常好用。代碼寫(xiě)起來(lái)比用傳統(tǒng)的ORM要簡(jiǎn)潔的多,只需一個(gè)實(shí)體類和Controller里的幾行代碼,ServiceDao什么的全都消失了,而且它返回的結(jié)果就是VO, 也不需要再做進(jìn)一步的轉(zhuǎn)換了,可以直接返回給前端。

在項(xiàng)目中配合使用它們,事務(wù)中使用 MyBatis Plus,列表檢索場(chǎng)景使用 Bean Searcher,你將如虎添翼

實(shí)際上,在舊項(xiàng)目中集成 Bean Searcher 更加容易,已有的單表實(shí)體類都能直接復(fù)用,而多表關(guān)聯(lián)的 VO 對(duì)象類也只需添加相應(yīng)注解即可擁有強(qiáng)大的檢索能力。無(wú)論項(xiàng)目原來(lái) ORM 用的是 MyBatis, MP, 還是 Hibernate,Data Jdbc 等,也無(wú)論 Web 框架是 Spring Boot, Spring MVC 還是 Grails 或 Jfinal 等,只要是 java 項(xiàng)目, 都可以用它,為系統(tǒng)賦能高級(jí)查詢。

往期熱門(mén)文章:

1、大公司為什么禁止SpringBoot項(xiàng)目使用Tomcat?

2、快速交付神器:阿里巴巴官方低代碼引擎開(kāi)源了!

3、為什么 Spring和IDEA 都不推薦使用 @Autowired 注解

4、程序員的悲哀是什么?

5、被問(wèn)懵了:MySQL 自增主鍵一定是連續(xù)的嗎?

6、點(diǎn)一下詳情系統(tǒng)掛了,CPU100%

7、我說(shuō)用count(*)統(tǒng)計(jì)行數(shù),面試官讓我回去等消息...

8、世界第三大瀏覽器正在消亡

9、被問(wèn)懵了:MySQL 自增主鍵一定是連續(xù)的嗎?

10、FastJson 很好,但不適合我!

關(guān)鍵詞:

相關(guān)新聞

日韩精品中文字幕久久臀_天堂av在线一区_午夜精品视频网站_99r精品视频_国产日韩亚洲欧美_亚洲欧美国产一本综合首页_日本一区二区三区久久久久久久久不 _国产精品高潮视频_久热99视频在线观看_91伊人久久大香线蕉
久草这里只有精品视频| 丝袜美腿亚洲一区二区图片| 亚洲无人区一区| 国产成人午夜电影网| 91福利视频网站| 一区二区三区加勒比av| 精品嫩草影院久久| 亚洲精品国产品国语在线app| 一区二区三区国产精华| 99国产精品久久| 日本色综合中文字幕| 欧美变态tickling挠脚心| 成人免费看的视频| 婷婷综合另类小说色区| 久久蜜桃av一区精品变态类天堂| 欧美aaaaaa午夜精品| 欧美精品一区二区三区蜜臀| 自拍偷自拍亚洲精品播放| 亚洲黄色片在线观看| 日韩欧美精品在线| 欧美zozo另类异族| 激情综合色播五月| 日本一区二区三区国色天香| 欧美视频在线一区| 国产乱码精品1区2区3区| 亚洲视频一区在线观看| 制服丝袜中文字幕亚洲| 久久99国产精品尤物| 中文字幕中文字幕中文字幕亚洲无线| 国产盗摄女厕一区二区三区| 久久一日本道色综合| 国产成人高清视频| 亚洲一区二区在线视频| 欧美精品日韩精品| 日韩国产欧美在线视频| 色播五月激情综合网| 国产盗摄一区二区三区| 国产经典欧美精品| 久久精品国产一区二区三区免费看| 亚洲精选一二三| 欧美tickling网站挠脚心| 91福利在线观看| 91丨porny丨首页| 国产在线播放一区三区四| 亚洲欧美成aⅴ人在线观看| 日韩一级片网址| 欧美mv日韩mv国产网站| 久久精品国产精品亚洲红杏| 欧美成人精品3d动漫h| 国产剧情av麻豆香蕉精品| 精品国内片67194| 在线中文字幕不卡| 国产精品国产精品国产专区不蜜 | 日韩精品一区二区三区三区免费| 99re66热这里只有精品3直播 | 精品久久久三级丝袜| 91在线播放网址| 国产高清不卡一区二区| 热久久免费视频| 一区二区三区在线高清| 一区二区三区四区乱视频| 国产精品视频第一区| 久久久久国产成人精品亚洲午夜| 日韩欧美中文字幕公布| 成人丝袜视频网| 91在线视频播放地址| 久久99久久久久| 亚洲啪啪综合av一区二区三区| 午夜精品久久久久久久久久久| 亚洲综合区在线| 亚洲大片一区二区三区| 国产黄色精品网站| 国产精品一区二区不卡| 免费在线一区观看| 午夜电影网一区| 一区二区三区欧美亚洲| 国产suv精品一区二区6| 亚洲自拍另类综合| 国产精品成人免费精品自在线观看| 国产精品久久久久久久蜜臀 | 欧美精品丝袜久久久中文字幕| 日韩欧美资源站| 亚洲欧美偷拍卡通变态| 日本成人在线看| 91啪九色porn原创视频在线观看| 6080日韩午夜伦伦午夜伦| 国产精品久久久久久户外露出| 99久久综合精品| 午夜精品久久久久久久99樱桃| 欧美一区二区三区思思人| 亚洲日本欧美天堂| 亚洲裸体xxx| 日本一区二区三区在线观看| 日韩视频在线一区二区| 欧美久久久影院| 91精品一区二区三区久久久久久| av一本久道久久综合久久鬼色| 水野朝阳av一区二区三区| 日本一区二区在线不卡| 欧美一区二区久久久| 亚洲精品成人a在线观看| 日本va欧美va精品| 国产一区二区在线观看免费| 99久久婷婷国产综合精品| 国产日本欧洲亚洲| 亚洲私人影院在线观看| 婷婷中文字幕一区三区| 欧美精品一二三| 在线观看免费成人| 国产精品毛片大码女人| 亚洲福利一区二区三区| 国产精品99久久久久| 欧美大片在线观看| 午夜激情一区二区三区| 波多野结衣中文一区| 欧美激情在线免费观看| 男男视频亚洲欧美| 99视频热这里只有精品免费| 亚洲图片你懂的| 91在线你懂得| 欧美一级久久久| 中文字幕亚洲成人| 日韩电影在线观看网站| 成人丝袜高跟foot| 国产午夜精品福利| 成人一级片在线观看| 91精品国产综合久久香蕉麻豆| 亚洲免费av高清| 欧美人牲a欧美精品| 亚洲国产乱码最新视频| 中文字幕亚洲视频| 国产成人午夜电影网| 欧美一区二区三区精品| 久久精品国产第一区二区三区| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 玉米视频成人免费看| 51久久夜色精品国产麻豆| 91国偷自产一区二区三区成为亚洲经典 | 老司机精品视频导航| 欧美蜜桃一区二区三区| 国产高清亚洲一区| 亚洲一区二区综合| www亚洲一区| 国产午夜精品久久| 色婷婷亚洲精品| 免费观看成人av| 亚洲国产精品黑人久久久| 在线观看91视频| 色综合久久六月婷婷中文字幕| 亚洲国产中文字幕在线视频综合| 国产精品国模大尺度视频| 亚洲综合视频在线| 日韩一区二区免费电影| 极品少妇一区二区三区精品视频| 美日韩一区二区| 国产色一区二区| 8x福利精品第一导航| 色综合亚洲欧洲| 不卡免费追剧大全电视剧网站| 国产 欧美在线| 视频一区二区国产| 国产精品国产a级| 欧美国产成人精品| 国产日韩精品一区| 欧美精品一区二区蜜臀亚洲| 91麻豆高清视频| av激情成人网| 97久久超碰国产精品电影| 日日夜夜精品视频天天综合网| 欧美哺乳videos| 91国模大尺度私拍在线视频| 国产精品一品二品| 国产福利视频一区二区三区| 日韩一区和二区| 亚洲精品免费在线播放| 欧美激情中文字幕一区二区| 欧美精品一区二区三区一线天视频| 欧美一区二区私人影院日本| 久久影视一区二区| 91精品国产综合久久精品| 9191国产精品| 久久精品夜色噜噜亚洲aⅴ| 国产精品第一页第二页第三页| 久久久www成人免费毛片麻豆| 日本高清不卡在线观看| 本田岬高潮一区二区三区| 97超碰欧美中文字幕| 在线免费观看日韩欧美| 91精品国产美女浴室洗澡无遮挡| 欧美成人一区二区三区| 国产亚洲综合性久久久影院| 日韩专区一卡二卡| 美腿丝袜亚洲综合| 一本大道av伊人久久综合| 色综合久久久久| 在线观看一区日韩| 欧美mv日韩mv亚洲| 一区二区三区在线高清| 91在线观看美女| 中文字幕 久热精品 视频在线|