精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Mybatis Insert后返回主鍵ID實現(xiàn)方法及源碼分析

開發(fā) 前端
mybatis這類ORM在往數(shù)據(jù)庫insert對象后,會順帶將數(shù)據(jù)庫中的自增主鍵值賦值給對象的id,這個功能給我們的開發(fā)帶來了很多方便,那它是怎么實現(xiàn)的呢?

[[409050]]

本文轉(zhuǎn)載自微信公眾號「肌肉碼農(nóng)」,作者鄒學(xué)。轉(zhuǎn)載本文請聯(lián)系肌肉碼農(nóng)公眾號。

引子:

mybatis這類ORM在往數(shù)據(jù)庫insert對象后,會順帶將數(shù)據(jù)庫中的自增主鍵值賦值給對象的id,這個功能給我們的開發(fā)帶來了很多方便,那它是怎么實現(xiàn)的呢?

源碼分析:

利用mybatis實現(xiàn)這一功能非常簡單,網(wǎng)絡(luò)上有一大把資料,今天我們主要看它是怎么實現(xiàn)的?

通過斷點insert可以跟蹤到這個類:PreparedStatementHandler.java的update方法。

  1. public int update(Statement statement) throws SQLException { 
  2.   PreparedStatement ps = (PreparedStatement) statement; 
  3. //執(zhí)行insert操作 
  4.   ps.execute(); 
  5. //獲得執(zhí)行行數(shù) 
  6.   int rows = ps.getUpdateCount(); 
  7.   Object parameterObject = boundSql.getParameterObject(); 
  8.     //獲得id 
  9.   KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); 
  10.   keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject); 
  11.   return rows

進(jìn)一步跟蹤getKeyGenerator()獲得id的方法, 會進(jìn)入Jdbc3KeyGenerator類的processBatch方法,如下:

  1. public void processBatch(MappedStatement ms, Statement stmt, Object parameter) { 
  2.     final String[] keyProperties = ms.getKeyProperties(); 
  3.     if (keyProperties == null || keyProperties.length == 0) { 
  4.       return
  5.     } 
  6.         //利用了statement的 getGeneratedKeys()方法 
  7.     try (ResultSet rs = stmt.getGeneratedKeys()) { 
  8.       final ResultSetMetaData rsmd = rs.getMetaData(); 
  9.       final Configuration configuration = ms.getConfiguration(); 
  10.       if (rsmd.getColumnCount() < keyProperties.length) { 
  11.         // Error? 
  12.       } else { 
  13.         assignKeys(configuration, rs, rsmd, keyProperties, parameter); 
  14.       } 
  15.     } catch (Exception e) { 
  16.       throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e, e); 
  17.     } 
  18.   } 

通過代碼的注釋我們可以看到,mybatis就是利用了Jdbc的Statement來獲得會話insert id的,那我們可不可以自己直接利用jdbc來實現(xiàn)呢?

jdbc statement示例

首先創(chuàng)建一個test表:

  1. create table test id int  not null auto_increment, td intprimary key(id); 

然后執(zhí)行以下代碼就可以批量獲得id了。

  1. Class.forName("com.mysql.jdbc.Driver"); 
  2.         Connection connection = DriverManager.getConnection(url, userName, pwd); 
  3.         String sql = "insert into test(td) values(5)"
  4.         Statement statement = connection.createStatement(); 
  5.         statement.execute(sql, 1); 
  6.  
  7.         ResultSet resultSet = statement.getGeneratedKeys(); 
  8.         while (resultSet.next()){ 
  9.             System.out.println(resultSet.getObject(1)); 
  10.         } 
  11.  
  12.         connection.close(); 

原理:

既然jdbc能獲得insert后的id,那它是怎么實現(xiàn)的呢? 通過斷點繼續(xù)跟蹤到這個類:StatementImpl.java

  1. protected ResultSetInternalMethods getGeneratedKeysInternal(long numKeys) throws SQLException { 
  2.         synchronized (checkClosed().getConnectionMutex()) { 
  3.             Field[] fields = new Field[1]; 
  4.             fields[0] = new Field("""GENERATED_KEY", Types.BIGINT, 20); 
  5.             fields[0].setConnection(this.connection); 
  6.             fields[0].setUseOldNameMetadata(true); 
  7.  
  8.             ArrayList<ResultSetRow> rowSet = new ArrayList<ResultSetRow>(); 
  9.  
  10.             //獲得上一次獲得insert后的id 
  11.             long beginAt = getLastInsertID(); 
  12.  
  13.             if (beginAt < 0) { // looking at an UNSIGNED BIGINT that has overflowed 
  14.                 fields[0].setUnsigned(); 
  15.             } 
  16.  
  17.             if (this.results != null) { 
  18.                 String serverInfo = this.results.getServerInfo(); 
  19.  
  20.                 // 
  21.                 // Only parse server info messages for 'REPLACE' queries 
  22.                 // 
  23.                 if ((numKeys > 0) && (this.results.getFirstCharOfQuery() == 'R') && (serverInfo != null) && (serverInfo.length() > 0)) { 
  24.                     //計算有多少行數(shù)據(jù) 
  25.                     numKeys = getRecordCountFromInfo(serverInfo); 
  26.                 } 
  27.                 //生成批量id 
  28.                 if ((beginAt != 0 /* BIGINT UNSIGNED can wrap the protocol representation */) && (numKeys > 0)) { 
  29.                     for (int i = 0; i < numKeys; i++) { 
  30.                         byte[][] row = new byte[1][]; 
  31.                         if (beginAt > 0) { 
  32.                             row[0] = StringUtils.getBytes(Long.toString(beginAt)); 
  33.                         } else { 
  34.                             byte[] asBytes = new byte[8]; 
  35.                             asBytes[7] = (byte) (beginAt & 0xff); 
  36.                             asBytes[6] = (byte) (beginAt >>> 8); 
  37.                             asBytes[5] = (byte) (beginAt >>> 16); 
  38.                             asBytes[4] = (byte) (beginAt >>> 24); 
  39.                             asBytes[3] = (byte) (beginAt >>> 32); 
  40.                             asBytes[2] = (byte) (beginAt >>> 40); 
  41.                             asBytes[1] = (byte) (beginAt >>> 48); 
  42.                             asBytes[0] = (byte) (beginAt >>> 56); 
  43.  
  44.                             BigInteger val = new BigInteger(1, asBytes); 
  45.  
  46.                             row[0] = val.toString().getBytes(); 
  47.                         } 
  48.                         rowSet.add(new ByteArrayRow(row, getExceptionInterceptor())); 
  49.                         beginAt += this.connection.getAutoIncrementIncrement(); 
  50.                     } 
  51.                 } 
  52.             } 
  53.  
  54.             com.mysql.jdbc.ResultSetImpl gkRs = com.mysql.jdbc.ResultSetImpl.getInstance(this.currentCatalog, fields, new RowDataStatic(rowSet), 
  55.                     this.connection, this, false); 
  56.  
  57.             return gkRs; 
  58.         } 
  59.     } 

代碼的流程是這樣的:獲得上一次insert后的id,再計算本次插入數(shù)據(jù)的行數(shù),最后自己批量生成,也就是說jdbc并沒有一行一行的去數(shù)據(jù)庫查詢id.然后我們再看下它是怎么獲得上一次insert后的Id的?

  1. /** 
  2. 支持自增主鍵 
  3.   * getLastInsertID returns the value of the auto_incremented key after an 
  4.   * executeQuery() or excute() call. 
  5.   *  
  6.   * <p> 
  7.   * This gets around the un-threadsafe behavior of "select LAST_INSERT_ID()" which is tied to the Connection that created this Statement, and therefore could 
  8.   * have had many INSERTS performed before one gets a chance to call "select LAST_INSERT_ID()"
  9.   * </p> 
  10.   *  
  11.   * @return the last update ID. 
  12.   */ 
  13.  public long getLastInsertID() { 
  14.      try { 
  15.          synchronized (checkClosed().getConnectionMutex()) { 
  16.              return this.lastInsertId; 
  17.          } 
  18.      } catch (SQLException e) { 
  19.          throw new RuntimeException(e); // evolve interface to throw SQLException 
  20.      } 
  21.  } 

光看上面的代碼注釋就明白了它的邏輯,通過select LAST_INSERT_ID()來獲得會話內(nèi)的insert后Id,并且只支持自增主鍵。

mysql client獲得id

 

責(zé)任編輯:武曉燕 來源: 肌肉碼農(nóng)
相關(guān)推薦

2021-08-09 11:15:28

MybatisJavaSpring

2010-09-25 09:55:14

sql server主

2021-04-28 06:26:11

Spring Secu功能實現(xiàn)源碼分析

2022-06-27 07:56:36

Mybatis源碼Spring

2024-11-22 15:32:19

2009-07-21 16:08:35

JDBC insert

2023-11-09 09:08:38

RibbonSpring

2014-12-11 13:37:13

WPF架構(gòu)

2019-11-25 16:05:20

MybatisPageHelpeJava

2012-02-23 12:53:40

JavaPlay Framew

2010-10-20 10:19:33

sql server刪

2020-05-28 16:50:59

源碼分析 MybatisJava

2010-10-19 17:34:10

sql server主

2024-12-04 09:36:37

2020-10-09 14:13:04

Zookeeper Z

2014-06-13 11:08:52

Redis主鍵失效

2013-08-28 10:11:37

RedisRedis主鍵失效NoSQL

2014-06-17 10:27:39

Redis緩存

2019-10-16 16:33:41

Docker架構(gòu)語言

2015-11-23 09:50:15

JavaScript模塊化SeaJs
點贊
收藏

51CTO技術(shù)棧公眾號

粗大黑人巨茎大战欧美成人| 丰满少妇xoxoxo视频| 欧美高清影院| 亚洲欧美另类图片小说| 国产一区喷水| 亚洲国产无线乱码在线观看 | 欧美伦理视频网站| 菠萝蜜视频在线观看入口| 日本高清视频在线| 日韩黄色免费电影| 波多野结衣在线观看一区二区三区 | 亚洲国产精品久久艾草纯爱| 免费观看成人在线| 国产suv精品一区二区69| 亚洲综合日韩| 美女扒开尿口让男人操亚洲视频网站 | 成人免费av电影| 伊人色综合久久天天人手人婷| 欧美大香线蕉线伊人久久国产精品 | 欧美巨大xxxx做受沙滩| 国产日韩欧美一区二区三区乱码| 亚洲一区中文字幕| 波多野结衣爱爱| 亚洲国产精品一区| 久热爱精品视频线路一| 亚洲码无人客一区二区三区| 91精品久久久久久综合五月天| 日本韩国精品在线| 91免费黄视频| 日本免费a视频| 国产精品老女人| 雨宫琴音一区二区三区| 亚洲人线精品午夜| 黄色片视频免费观看| 精品国产一区二| 在线观看日韩一区| 欧美色图另类小说| h片在线观看| 一二三区精品视频| 亚洲日本一区二区三区在线不卡| 少妇激情av一区二区| 粉嫩aⅴ一区二区三区四区| 国产精品一区二区久久久久| 亚洲GV成人无码久久精品| 在线成人亚洲| 欧美激情精品久久久久久变态| 日本午夜在线观看| 99热国内精品| 日韩在线观看免费| av片在线免费看| 狠狠做深爱婷婷综合一区| 日韩精品欧美激情| 加勒比精品视频| 日韩精品社区| 亚洲欧洲视频在线| 在线观看国产精品一区| 精品高清在线| 日韩在线一区二区三区免费视频| 国产又粗又猛又爽又黄的视频四季 | www日韩av| www.蜜桃av.com| 国产ts人妖一区二区| 91文字幕巨乱亚洲香蕉| 精品久久国产视频| 在线亚洲a色| 国内外成人在线视频| 国产精品三级久久久久久电影| 夜夜爽妓女8888视频免费观看| 校园春色综合网| 国产成人精品a视频一区www| 免费av中文字幕| 久久成人羞羞网站| 91丨九色丨国产在线| 性欧美18一19性猛交| 国产精品888| 国产一区二区三区四区hd| 天堂网在线观看视频| 久久亚洲春色中文字幕久久久| 欧美性大战久久久久| 番号集在线观看| 亚洲色欲色欲www| 国产在线观看欧美| 欧美少妇精品| 欧美日韩在线播放一区| 99精品视频国产| 国产精品色呦| 亚洲天堂av高清| 日本一二三区在线观看| 波多野结衣家庭主妇| 欧美日中文字幕| 粗暴蹂躏中文一区二区三区| 国产一级视频在线| 久久久噜噜噜| 91亚洲va在线va天堂va国| 国产 日韩 欧美 综合| 久久亚洲精精品中文字幕早川悠里| 亚洲国产欧美日韩| 91视频欧美| 欧美日韩你懂得| 日本一区二区免费视频| 欧美视频网址| 久久久久免费精品国产| 精品黑人一区二区三区| 国产成人精品一区二| 日本一区二区三区视频在线观看| 国内精品久久久久国产| 欧美日韩免费在线观看| www.污网站| 自拍亚洲一区| 欧美精品成人91久久久久久久| 欧美一区免费看| 国产不卡视频一区二区三区| 视频一区免费观看| 国产高清在线a视频大全| 欧美性色黄大片手机版| 北京富婆泄欲对白| 久久久久久免费视频| 亲爱的老师9免费观看全集电视剧| 国产三级伦理片| 国产欧美日韩精品a在线观看| 成人精品视频在线播放| 国产精品视频一区二区三区| 亚洲天堂第二页| 亚欧视频在线观看| 国产精品一区专区| 人人妻人人澡人人爽精品欧美一区| 一区二区乱码| 欧美精品一区二区三区蜜桃| 亚洲人与黑人屁股眼交| 奇米影视在线99精品| 精品久久久久久亚洲| 欧美亚洲天堂| 国产一区二区剧情av在线| 欧美日韩亚洲综合在线 | 国产精品久久一级| 国产精品69页| 天天躁日日躁狠狠躁欧美巨大小说 | 在线精品视频一区二区三四| 中文字幕5566| 国产一区二区三区久久| 狠狠色伊人亚洲综合网站色| 狂野欧美激情性xxxx欧美| 91精品欧美福利在线观看| 欧美日韩中文字幕视频| 日韩国产欧美在线播放| 欧美日韩亚洲一区二区三区在线观看 | 窝窝社区一区二区| 韩国欧美亚洲国产| 神马一区二区三区| 亚洲国产wwwccc36天堂| av漫画在线观看| 激情综合网址| 狠狠色噜噜狠狠色综合久| 美女的胸无遮挡在线观看| 亚洲成av人片在线观看香蕉| 在线免费观看毛片| 91玉足脚交白嫩脚丫在线播放| 日韩免费一级视频| 九九久久婷婷| 国产精品久久久av| av在线之家电影网站| 欧美日韩一区二区三区在线看| 欧美a在线播放| 久久成人精品无人区| 自拍亚洲欧美老师丝袜| 久久久久久久久久久久电影| 欧美激情乱人伦一区| 色欲av永久无码精品无码蜜桃 | 久色视频在线播放| 婷婷综合福利| 国产精品美女视频网站| 国产在线一区二区视频| 精品福利二区三区| 国产精品人人人人| 久久精品人人做人人综合 | 日韩av在线发布| 日韩av影视| 天天综合在线观看| 欧美丰满少妇xxxxx| 艳母动漫在线看| 欧美性猛片xxxx免费看久爱| 欧日韩不卡视频| 国产精品自拍网站| 欧美日韩精品在线一区二区| 国产一区网站| 成人中心免费视频| 色戒汤唯在线观看| 日韩有码在线播放| 蜜桃av噜噜一区二区三区麻豆| 高跟丝袜一区二区三区| 日本视频在线免费| 成人午夜视频免费看| 无码日韩人妻精品久久蜜桃| 亚洲久久久久| 免费日韩av电影| 91精品一久久香蕉国产线看观看| 国内精品久久久久影院优| 玖玖综合伊人| 日韩免费观看高清完整版在线观看| 成人免费看片98欧美| 国产精品国产三级国产aⅴ中文| 亚洲精品乱码久久久久久9色| 国产精品亚洲综合久久| 欧美 日韩 国产 在线观看| 色综合久久中文| 亚洲一区亚洲二区| 日韩欧美精品一区二区综合视频| 欧美激情精品久久久久久久变态 | 夜夜嗨aⅴ一区二区三区| 亚洲一区欧美一区| 亚洲一级片在线播放| 成人激情文学综合网| 九九热免费在线观看| 亚洲伊人网站| 欧美无砖专区免费| 99精品视频精品精品视频| 久久66热这里只有精品| 日韩精品久久久久久久软件91| 国产成人在线播放| 交100部在线观看| 久久综合网hezyo| av网站在线免费观看| 日韩激情视频在线播放| 亚洲AV无码国产精品午夜字幕| 欧美日韩国产一区| 国产suv精品一区二区33| 亚洲电影第三页| 精品欧美一区二区久久久久| 国产精品进线69影院| 最新中文字幕视频| 中文字幕视频在线免费观看| 国产美女永久免费无遮挡| 国产99久久久国产精品潘金| 怡红院亚洲色图| 丝袜美腿一区二区三区| 成人一区二区免费视频| 欧美日韩ab| 中文字幕一区二区三区有限公司 | 人人九九精品视频| 国产日韩av在线播放| 三级成人在线| 国产成人精品视频在线观看| 性感女国产在线| 国产91精品久久久| 亚洲电影观看| 欧美一级电影久久| 日本不卡1234视频| 91av免费观看91av精品在线| 黄网站在线观| 国内精品视频一区| av中文资源在线资源免费观看| 欧美日本黄视频| 男女视频在线| 国模极品一区二区三区| a√中文在线观看| 亚州欧美日韩中文视频| 绿色成人影院| 欧美一级淫片播放口| 日本综合字幕| 国产精品视频免费观看www| 国产亚洲人成a在线v网站| 国产精品一区二区三区免费视频| 成人一级视频| 91精品国产自产在线观看永久| 国产区一区二| 国产传媒一区二区| 日韩高清在线免费观看| 日本视频一区二区在线观看| 日韩在线第七页| 中文字幕在线观看一区二区三区| 天天做天天爱天天综合网| 中文字幕一区二区三区最新| 国产精品v一区二区三区| 日本中文字幕在线视频观看| 亚洲欧美久久| 日本xxxx黄色| 国产一区二区看久久| 国产污在线观看| 91美女视频网站| 国产福利在线导航| 一区二区三区在线播| 日本免费观看视| 欧美系列亚洲系列| h片在线免费看| 日韩成人中文字幕在线观看| 国产福利小视频在线观看| www国产91| www555久久| 日韩免费中文字幕| 国产999精品在线观看| 国产视频精品网| 精品理论电影在线| 国内自拍中文字幕| 国产免费成人| 天堂av手机在线| 91小视频免费观看| 国产色无码精品视频国产| 亚洲国产日韩a在线播放性色| 三级网站在线播放| 欧美一区二区三区在线视频| 亚洲色大成网站www| 爱福利视频一区| 秋霞伦理一区| 91在线免费视频| 国产成人1区| 日本福利视频在线观看| 日本免费新一区视频| 一本色道久久hezyo无码| 中文字幕欧美国产| 国产成人亚洲欧洲在线| 在线成人免费视频| 可以在线观看的av| 久久琪琪电影院| 99精品在线免费观看| 日韩高清三级| av成人国产| 日韩大尺度视频| 国产精品人妖ts系列视频| 日韩污视频在线观看| 日韩欧美一二三| 日本福利在线| 国产99视频精品免视看7| 国产成人高清精品免费5388| 一区二区三区视频| 日韩精品免费视频人成| 奇米777第四色| 樱桃视频在线观看一区| 国产又粗又猛又黄| 一级做a爰片久久毛片美女图片| 黑人玩欧美人三根一起进| 91手机视频在线观看| 热久久天天拍国产| www日韩在线观看| 91视频在线看| 日韩精品人妻中文字幕| 欧美成人r级一区二区三区| 国产黄色在线免费观看| 国产日韩在线精品av| japanese国产精品| 国产第一页视频| 久久免费美女视频| 国产精品国产三级国产专区52| 亚洲成人网在线| 丁香花在线影院| 国产精品国产精品| 激情欧美亚洲| 在线天堂www在线国语对白| 亚洲一区视频在线观看视频| 亚洲欧美激情在线观看| 欧美国产精品人人做人人爱| 日韩一区二区三区色| 国产午夜精品视频一区二区三区| 国产在线精品不卡| 久久久精品视频免费观看| 日韩亚洲国产中文字幕欧美| 午夜伦理在线视频| 国产成人精品免费视频大全最热| 欧美视频在线观看| 妖精视频一区二区| 婷婷中文字幕一区三区| 色av男人的天堂免费在线| 日本久久久久久久| 成人嫩草影院| 五月天激情播播| 亚洲另类在线视频| 蜜臀av中文字幕| 日本视频久久久| 色喇叭免费久久综合网| 国产毛片久久久久久| 亚洲国产精品自拍| 青青九九免费视频在线| 国产精品久久久久久久久久久久久| 日韩欧美视频专区| 日韩av福利在线观看| 婷婷国产v国产偷v亚洲高清| 国产露出视频在线观看| 91久久久久久久一区二区| 狠狠色狠狠色综合日日tαg| 黑丝av在线播放| 欧美性生活久久| 女同视频在线观看| 欧美亚洲丝袜| 国产乱一区二区| 欧美精品亚洲精品日韩精品| 国产亚洲精品久久久久久牛牛| 91国产一区| 国产精品50p| 日韩美女精品在线| 色窝窝无码一区二区三区| 国产精品极品在线| 欧美精品成人| www.中文字幕av| 91精品国产综合久久久久久久久久| 黄色羞羞视频在线观看| 欧美欧美一区二区| 国产一区二区在线观看视频| 精品国产免费观看| 久久偷看各类女兵18女厕嘘嘘| 亚洲国产合集| 国产伦精品一区二区三区妓女下载|