版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、79/79Mybatis框架課程講師:傳智.燕青Mybatis入門單獨(dú)使用jdbc編程問題總結(jié)jdbc程序Publicstaticvoid main(String args) Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try /加載數(shù)據(jù)庫驅(qū)動Class.forName(com.mysql.jdbc.Driver);/通過驅(qū)動管理類獲取數(shù)據(jù)庫鏈接connection = DriverManager.getConnection(jdbc:mys
2、ql:/localhost:3306/mybatis?characterEncoding=utf-8, root, mysql);/定義sql語句 ?表示占位符String sql = select *from userwhere username = ?;/獲取預(yù)處理statementpreparedStatement = connection.prepareStatement(sql);/設(shè)置參數(shù),第一個參數(shù)為sql語句中參數(shù)的序號(從1開始),第二個參數(shù)為設(shè)置的參數(shù)值preparedStatement.setString(1, 王五);/向數(shù)據(jù)庫發(fā)出sql執(zhí)行查詢,查詢出結(jié)果集resul
3、tSet = preparedStatement.executeQuery();/遍歷查詢結(jié)果集while(resultSet.next()System.out.println(resultSet.getString(id)+ +resultSet.getString(username); catch (Exception e) e.printStackTrace();finally/釋放資源if(resultSet!=null)try resultSet.close(); catch (SQLException e) / TODO Auto-generated catch blocke.pr
4、intStackTrace();if(preparedStatement!=null)try preparedStatement.close(); catch (SQLException e) / TODO Auto-generated catch blocke.printStackTrace();if(connection!=null)try connection.close(); catch (SQLException e) / TODO Auto-generated catch blocke.printStackTrace();上邊使用jdbc的原始方法(未經(jīng)封裝)實(shí)現(xiàn)了查詢數(shù)據(jù)庫表記錄
5、的操作。jdbc編程步驟:加載數(shù)據(jù)庫驅(qū)動創(chuàng)建并獲取數(shù)據(jù)庫鏈接創(chuàng)建jdbc statement對象設(shè)置sql語句設(shè)置sql語句中的參數(shù)(使用preparedStatement)通過statement執(zhí)行sql并獲取結(jié)果對sql執(zhí)行結(jié)果進(jìn)行解析處理釋放資源(resultSet、preparedstatement、connection)jdbc問題總結(jié)如下:數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。Sql語句在代碼中硬編碼,造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動需要改變java代碼。使用preparedStatement向占有位符
6、號傳參數(shù)存在硬編碼,因?yàn)閟ql語句的where條件不一定,可能多也可能少,修改sql還要修改代碼,系統(tǒng)不易維護(hù)。對結(jié)果集解析存在硬編碼(查詢列名),sql變化導(dǎo)致解析代碼變化,系統(tǒng)不易維護(hù),如果能將數(shù)據(jù)庫記錄封裝成pojo對象解析比較方便。MyBatis介紹MyBatis 本是 HYPERLINK :/baike.baidu /view/28283.htm apache的一個開源項(xiàng)目 HYPERLINK :/baike.baidu /view/628102.htm iBatis, 2010年這個項(xiàng)目由apache software foundation 遷移到了google code,并且改名
7、為MyBatis,實(shí)質(zhì)上Mybatis對ibatis進(jìn)行一些改進(jìn)。MyBatis是一個優(yōu)秀的持久層框架,它對jdbc的操作數(shù)據(jù)庫的過程進(jìn)行封裝,使開發(fā)者只需要關(guān)注SQL 本身,而不需要花費(fèi)精力去處理例如注冊驅(qū)動、創(chuàng)建connection、創(chuàng)建statement、手動設(shè)置參數(shù)、結(jié)果集檢索等jdbc繁雜的過程代碼。Mybatis通過xml或注解的方式將要執(zhí)行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,并通過java對象和statement中的sql進(jìn)行映射生成最終執(zhí)行的sql語句,最后由mybatis框架執(zhí)行sql并
8、將結(jié)果映射成java對象并返回。Mybatis架構(gòu)mybatis配置SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運(yùn)行環(huán)境等信息。mapper.xml文件即sql映射文件,文件中配置了操作數(shù)據(jù)庫的sql語句。此文件需要在SqlMapConfig.xml中加載。通過mybatis環(huán)境等配置信息構(gòu)造SqlSessionFactory即會話工廠由會話工廠創(chuàng)建sqlSession即會話,操作數(shù)據(jù)庫需要通過sqlSession進(jìn)行。mybatis底層自定義了Executor執(zhí)行器接口操作數(shù)據(jù)庫,Executor接口有兩個實(shí)現(xiàn),一個是基本執(zhí)行器、一個是緩存
9、執(zhí)行器。Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息與sql映射信息等。mapper.xml文件中一個sql對應(yīng)一個Mapped Statement對象,sql的id即是Mapped statement的id。Mapped Statement對sql執(zhí)行輸入?yún)?shù)進(jìn)行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執(zhí)行sql前將輸入的java對象映射至sql中,輸入?yún)?shù)映射就是jdbc編程中對preparedStatement設(shè)置參數(shù)。Mapped Statement對sql執(zhí)行輸出結(jié)果進(jìn)行
10、定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執(zhí)行sql后將輸出結(jié)果映射至java對象中,輸出結(jié)果映射過程相當(dāng)于jdbc編程中對結(jié)果的解析處理過程。mybatis下載mybaits的代碼由github管理,地址: s:/github /mybatis/mybatis-3/releasesmybatis-3.2.7.jarmybatis的核心包libmybatis的依賴包mybatis-3.2.7.pdfmybatis使用手冊創(chuàng)建mysql數(shù)據(jù)庫先導(dǎo)入sql_table.sql,再導(dǎo)入 sql_data.sql腳本:如下:Mybatis入門程
11、序需求實(shí)現(xiàn)以下功能:根據(jù)用戶id查詢一個用戶信息根據(jù)用戶名稱模糊查詢用戶信息列表添加用戶更新用戶刪除用戶第一步:創(chuàng)建java工程使用eclipse創(chuàng)建java工程,jdk使用1.7.0_72。第二步:加入jar包加入mybatis核心包、依賴包、數(shù)據(jù)驅(qū)動包。第三步:perties在classpath下創(chuàng)建perties如下:# Global logging configurationlog4j.rootLogger=DEBUG, stdout# Console output.log4j.appender.stdout=org.apache.log4j.Con
12、soleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p %t - %m%nmybatis默認(rèn)使用log4j作為輸出日志信息。第四步:SqlMapConfig.xml在classpath下創(chuàng)建SqlMapConfig.xml,如下:SqlMapConfig.xml是mybatis核心配置文件,上邊文件的配置內(nèi)容為數(shù)據(jù)源、事務(wù)管理。第五步:po類Po類作為mybatis進(jìn)行sql映射使用,po類通常與數(shù)據(jù)庫表對應(yīng)
13、,User.java如下:PublicclassUser privateintid;private String username;/ 用戶XXprivate String sex;/ 性別private Date birthday;/ 生日private String address;/ 地址get/set第六步:程序編寫查詢映射文件:在classpath下的sqlmap目錄下創(chuàng)建sql映射文件Users.xml:namespace :命名空間,用于隔離sql語句,后面會講另一層非常重要的作用。在SqlMapConfig.xml中添加:select * from userwhere id =
14、 #id select * from userwhere username like %$value% parameterType:定義輸入到sql中的映射類型,#id表示使用preparedstatement設(shè)置占位符號并將輸入變量id傳到sql。resultType:定義結(jié)果映射類型。加載映射文件mybatis框架需要加載映射文件,將Users.xml添加在SqlMapConfig.xml,如下:測試程序:publicclass Mybatis_first /會話工廠private SqlSessionFactory sqlSessionFactory;Beforepublicvoid c
15、reateSqlSessionFactory() throws IOException / 配置文件String resource = SqlMapConfig.xml;InputStream inputStream = Resources.getResourceAsStream(resource);/ 使用SqlSessionFactoryBuilder從xml配置文件中創(chuàng)建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);/ 根據(jù) id查詢用戶信息Testpublic
16、void testFindUserById() / 數(shù)據(jù)庫會話實(shí)例SqlSession sqlSession = null;try / 創(chuàng)建數(shù)據(jù)庫會話實(shí)例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 查詢單個記錄,根據(jù)用戶id查詢用戶信息Useruser = sqlSession.selectOne(test.findUserById, 10);/ 輸出用戶信息System.out.println(user); catch (Exception e) e.printStackTrace(); finally if (sqlSe
17、ssion != null) sqlSession.close();/ 根據(jù)用戶名稱模糊查詢用戶信息Testpublicvoid testFindUserByUsername() / 數(shù)據(jù)庫會話實(shí)例SqlSession sqlSession = null;try / 創(chuàng)建數(shù)據(jù)庫會話實(shí)例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 查詢單個記錄,根據(jù)用戶id查詢用戶信息List list = sqlSession.selectList(test.findUserByUsername, 張);System.out.println(
18、list.size(); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) sqlSession.close();#和$#表示一個占位符號,通過#可以實(shí)現(xiàn)preparedStatement向占位符中設(shè)置值,自動進(jìn)行java類型和jdbc類型轉(zhuǎn)換,#可以有效防止sql注入。#可以接收簡單類型值或pojo屬性值。如果parameterType傳輸單個簡單類型值,#括號中可以是value或其它名稱。$表示拼接sql串,通過$可以將parameterType 傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換
19、,$可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,$括號中只能是value。parameterType和resultTypeparameterType:指定輸入?yún)?shù)類型,mybatis通過ognl從輸入對象中獲取參數(shù)值拼接在sql中。resultType:指定輸出結(jié)果類型,mybatis將sql查詢結(jié)果的一行記錄數(shù)據(jù)映射為resultType指定類型的對象。selectOne和selectListselectOne查詢一條記錄,如果使用selectOne查詢多條記錄則拋出異常:org.apache.ibatis.exceptions.TooManyRes
20、ultsException: Expected one result (or null) to be returned by selectOne(), but found: 3at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)selectList可以查詢一條或多條記錄。添加映射文件:在SqlMapConfig.xml中添加:select LAST_INSERT_ID() insert into user(username,birthday,sex,address
21、) values(#username,#birthday,#sex,#address)測試程序:/ 添加用戶信息Testpublicvoid testInsert() / 數(shù)據(jù)庫會話實(shí)例SqlSession sqlSession = null;try / 創(chuàng)建數(shù)據(jù)庫會話實(shí)例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 添加用戶信息Useruser =new User();user.setUsername(張小明);user.setAddress(河南鄭州);user.setSex(1);user.setPrice(1999.9
22、f);sqlSession.insert(test.insertUser, user);/提交事務(wù)sqlSession mit(); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) sqlSession.close();mysql自增主鍵返回通過修改sql映射文件,可以將mysql自增主鍵返回:select LAST_INSERT_ID()insert into user(username,birthday,sex,address) values(#username,#birthday,#sex,
23、#address);添加selectKey實(shí)現(xiàn)將主鍵返回keyProperty:返回的主鍵存儲在pojo中的哪個屬性order:selectKey的執(zhí)行順序,是相對與insert語句來說,由于mysql的自增原理執(zhí)行完insert語句之后才將主鍵生成,所以這里selectKey的執(zhí)行順序?yàn)閍fterresultType:返回的主鍵是什么類型LAST_INSERT_ID():是mysql的函數(shù),返回auto_increment自增列新記錄id值。Mysql使用uuid實(shí)現(xiàn)主鍵需要增加通過select uuid()得到uuid值select uuid()insert into user(id,us
24、ername,birthday,sex,address) values(#id,#username,#birthday,#sex,#address)注意這里使用的order是“BEFORE”O(jiān)racle使用序列生成主鍵首先自定義一個序列且用于生成主鍵,selectKey使用如下:SELECT 自定義序列.NEXTVAL FROM DUALinsert into user(id,username,birthday,sex,address) values(#id,#username,#birthday,#sex,#address)注意這里使用的order是“BEFORE”刪除映射文件:delete
25、 from userwhere id=#id測試程序:/ 根據(jù)id刪除用戶TestpublicvoidtestDelete() / 數(shù)據(jù)庫會話實(shí)例SqlSession sqlSession = null;try / 創(chuàng)建數(shù)據(jù)庫會話實(shí)例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 刪除用戶sqlSession.delete(test.deleteUserById,18);/ 提交事務(wù)sqlSession mit(); catch (Exception e) e.printStackTrace(); finally if (sql
26、Session != null) sqlSession.close();修改映射文件update userset username=#username,birthday=#birthday,sex=#sex,address=#addresswhere id=#id測試程序/ 更新用戶信息TestpublicvoidtestUpdate() / 數(shù)據(jù)庫會話實(shí)例SqlSession sqlSession = null;try / 創(chuàng)建數(shù)據(jù)庫會話實(shí)例sqlSessionsqlSession = sqlSessionFactory.openSession();/ 添加用戶信息Useruser =new
27、 User();user.setId(16);user.setUsername(張小明);user.setAddress(河南鄭州);user.setSex(1);user.setPrice(1999.9f);sqlSession.update(test.updateUser, user);/ 提交事務(wù)sqlSession mit(); catch (Exception e) e.printStackTrace(); finally if (sqlSession != null) sqlSession.close();Mybatis解決jdbc編程的問題數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)
28、從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。Sql語句寫在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動需要改變java代碼。解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。向sql語句傳參數(shù)麻煩,因?yàn)閟ql語句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對應(yīng)。解決:Mybatis自動將java對象映射至sql語句,通過statement中的parameterType定義輸入?yún)?shù)的類型。對結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前
29、需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成pojo對象解析比較方便。解決:Mybatis自動將sql執(zhí)行結(jié)果映射至java對象,通過statement中的resultType定義輸出結(jié)果的類型。與hibernate不同Mybatis和hibernate不同,它不完全是一個ORM框架,因?yàn)镸yBatis需要程序員自己編寫Sql語句,不過mybatis可以通過XML或注解方式靈活配置要運(yùn)行的sql語句,并將java對象和sql語句映射生成最終執(zhí)行的sql,最后將sql執(zhí)行的結(jié)果再映射生成java對象。Mybatis學(xué)習(xí)門檻低,簡單易學(xué),程序員直接編寫原生態(tài)sql,可嚴(yán)格控制sql執(zhí)行性能,靈活度高,非常適
30、合對關(guān)系數(shù)據(jù)模型要求不高的軟件開發(fā),例如互聯(lián)網(wǎng)軟件、企業(yè)運(yùn)營類軟件等,因?yàn)檫@類軟件需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到數(shù)據(jù)庫無關(guān)性,如果需要實(shí)現(xiàn)支持多種數(shù)據(jù)庫的軟件則需要自定義多套sql映射文件,工作量大。Hibernate對象/關(guān)系映射能力強(qiáng),數(shù)據(jù)庫無關(guān)性好,對于關(guān)系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開發(fā)可以節(jié)省很多代碼,提高效率。但是Hibernate的學(xué)習(xí)門檻高,要精通門檻更高,而且怎么設(shè)計(jì)O/R映射,在性能和對象模型之間如何權(quán)衡,以與怎樣用好Hibernate需要具有很強(qiáng)的經(jīng)驗(yàn)和能力才行??傊?,按照用戶的需
31、求在有限的資源環(huán)境下只要能做出維護(hù)性、擴(kuò)展性良好的軟件架構(gòu)都是好架構(gòu),所以框架只有適合才是最好。Dao開發(fā)方法使用Mybatis開發(fā)Dao,通常有兩個方法,即原始Dao開發(fā)方法和Mapper接口開發(fā)方法。需求將下邊的功能實(shí)現(xiàn)Dao:根據(jù)用戶id查詢一個用戶信息根據(jù)用戶名稱模糊查詢用戶信息列表添加用戶信息SqlSession的使用范圍SqlSession中封裝了對數(shù)據(jù)庫的操作,如:查詢、插入、更新、刪除等。通過SqlSessionFactory創(chuàng)建SqlSession,而SqlSessionFactory是通過SqlSessionFactoryBuilder進(jìn)行創(chuàng)建。SqlSessionFact
32、oryBuilderSqlSessionFactoryBuilder用于創(chuàng)建SqlSessionFacoty,SqlSessionFacoty一旦創(chuàng)建完成就不需要SqlSessionFactoryBuilder了,因?yàn)镾qlSession是通過SqlSessionFactory生產(chǎn),所以可以將SqlSessionFactoryBuilder當(dāng)成一個工具類使用,最佳使用范圍是方法范圍即方法體內(nèi)局部變量。SqlSessionFactorySqlSessionFactory是一個接口,接口中定義了openSession的不同重載方法,SqlSessionFactory的最佳使用范圍是整個應(yīng)用運(yùn)行期間
33、,一旦創(chuàng)建后可以重復(fù)使用,通常以單例模式管理SqlSessionFactory。SqlSessionSqlSession是一個面向用戶的接口,sqlSession中定義了數(shù)據(jù)庫操作,默認(rèn)使用DefaultSqlSession實(shí)現(xiàn)類。執(zhí)行過程如下:加載數(shù)據(jù)源等配置信息Environment environment = configuration.getEnvironment();創(chuàng)建數(shù)據(jù)庫鏈接創(chuàng)建事務(wù)對象創(chuàng)建Executor,SqlSession所有操作都是通過Executor完成,mybatis源碼如下:if (ExecutorType.BATCH = executorType) execut
34、or = newBatchExecutor(this, transaction); elseif (ExecutorType.REUSE = executorType) executor = new ReuseExecutor(this, transaction); else executor = new SimpleExecutor(this, transaction); if (cacheEnabled) executor = new CachingExecutor(executor, autoCommit); SqlSession的實(shí)現(xiàn)類即DefaultSqlSession,此對象中對操
35、作數(shù)據(jù)庫實(shí)質(zhì)上用的是Executor結(jié)論:每個線程都應(yīng)該有它自己的SqlSession實(shí)例。SqlSession的實(shí)例不能共享使用,它也是線程不安全的。因此最佳的范圍是請求或方法范圍。絕對不能將SqlSession實(shí)例的引用放在一個類的靜態(tài)字段或?qū)嵗侄沃?。打開一個 SqlSession;使用完畢就要關(guān)閉它。通常把這個關(guān)閉操作放到 finally 塊中以確保每次都能執(zhí)行關(guān)閉。如下:SqlSession session = sqlSessionFactory.openSession();try / do work finally session.close();原始Dao開發(fā)方式原始Dao開發(fā)方
36、法需要程序員編寫Dao接口和Dao實(shí)現(xiàn)類。映射文件select * from userwhere id = #idselect LAST_INSERT_ID() insert into user(username,birthday,sex,address) values(#username,#birthday,#sex,#address)Dao接口Publicinterface UserDao publicUser getUserById(int id) throws Exception;publicvoid insertUser(Useruser)throws Exception;Publi
37、cclass UserDaoImpl implements UserDao /注入SqlSessionFactorypublic UserDaoImpl(SqlSessionFactory sqlSessionFactory)this.setSqlSessionFactory(sqlSessionFactory);private SqlSessionFactory sqlSessionFactory;Overridepublic UsergetUserById(int id) throws Exception SqlSession session = sqlSessionFactory.ope
38、nSession();Useruser =null;try /通過sqlsession調(diào)用selectOne方法獲取一條結(jié)果集/參數(shù)1:指定定義的statement的id,參數(shù)2:指定向statement中傳遞的參數(shù)user = session.selectOne(test.findUserById, 1);System.out.println(user); finallysession.close();returnuser;OverridePublicvoid insertUser(Useruser)throws Exception SqlSession sqlSession= sqlSes
39、sionFactory.openSession();try sqlSession.insert(insertUser, user);sqlSession mit(); finallysession.close();問題原始Dao開發(fā)中存在以下問題:Dao方法體存在重復(fù)代碼:通過SqlSessionFactory創(chuàng)建SqlSession,調(diào)用SqlSession的數(shù)據(jù)庫操作方法調(diào)用sqlSession的數(shù)據(jù)庫操作方法需要指定statement的id,這里存在硬編碼,不得于開發(fā)維護(hù)。Mapper動態(tài)代理方式實(shí)現(xiàn)原理Mapper接口開發(fā)方法只需要程序員編寫Mapper接口(相當(dāng)于Dao接口),由My
40、batis框架根據(jù)接口定義創(chuàng)建接口的動態(tài)代理對象,代理對象的方法體同上邊Dao接口實(shí)現(xiàn)類方法。Mapper接口開發(fā)需要遵循以下規(guī)范:Mapper.xml文件中的namespace與mapper接口的類路徑一樣。Mapper接口方法名和Mapper.xml中定義的每個statement的id一樣Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個sql 的parameterType的類型一樣Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個sql的resultType的類型一樣Mapper.xml(映射文件)定義mapper映射文件UserMapper.xml(
41、內(nèi)容同Users.xml),需要修改namespace的值為UserMapper接口路徑。將UserMapper.xml放在classpath 下mapper目錄下。select * from userwhere id = #id select * from user where username like %$value% select LAST_INSERT_ID() insert into user(username,birthday,sex,address) values(#username,#birthday,#sex,#address)Mapper.java(接口文件)/* * 用
42、戶管理mapper */Publicinterface UserMapper /根據(jù)用戶id查詢用戶信息publicUser findUserById(int id) throws Exception;/查詢用戶列表public List findUserByUsername(String username) throws Exception;/添加用戶信息publicvoid insertUser(Useruser)throws Exception; 接口定義有如下特點(diǎn):Mapper接口方法名和Mapper.xml中定義的statement的id一樣Mapper接口方法的輸入?yún)?shù)類型和map
43、per.xml中定義的statement的parameterType的類型一樣Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的statement的resultType的類型一樣加載UserMapper.xml文件修改SqlMapConfig.xml文件:測試Publicclass UserMapperTest extends TestCase private SqlSessionFactory sqlSessionFactory;protectedvoid setUp() throws Exception /mybatis配置文件String resource = sqlMap
44、Config.xml;InputStream inputStream = Resources.getResourceAsStream(resource);/使用SqlSessionFactoryBuilder創(chuàng)建sessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);Publicvoid testFindUserById() throws Exception /獲取sessionSqlSession session = sqlSessionFactory.openSession();
45、/獲取mapper接口的代理對象UserMapper userMapper = session.getMapper(UserMapper.class);/調(diào)用代理對象方法Useruser = userMapper.findUserById(1);System.out.println(user);/關(guān)閉sessionsession.close();Testpublicvoid testFindUserByUsername() throws Exception SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper us
46、erMapper = sqlSession.getMapper(UserMapper.class);List list = userMapper.findUserByUsername(張);System.out.println(list.size();Publicvoid testInsertUser() throws Exception /獲取sessionSqlSession session = sqlSessionFactory.openSession();/獲取mapper接口的代理對象UserMapper userMapper = session.getMapper(UserMapp
47、er.class);/要添加的數(shù)據(jù)Useruser =new User();user.setUsername(張三);user.setBirthday(new Date();user.setSex(1);user.setAddress(市);/通過mapper接口添加用戶userMapper.insertUser(user);/提交session mit();/關(guān)閉sessionsession.close();總結(jié)selectOne和selectList動態(tài)代理對象調(diào)用sqlSession.selectOne()和sqlSession.selectList()是根據(jù)mapper接口方法的返回值
48、決定,如果返回list則調(diào)用selectList方法,如果返回單個對象則調(diào)用selectOne方法。namespacemybatis官方推薦使用mapper代理方法開發(fā)mapper接口,程序員不用編寫mapper接口實(shí)現(xiàn)類,使用mapper代理方法時,輸入?yún)?shù)可以使用pojo包裝對象或map對象,保證dao的通用性。SqlMapConfig.xml配置文件配置內(nèi)容SqlMapConfig.xml中配置的內(nèi)容和順序如下:properties(屬性)settings(全局配置參數(shù))typeAliases(類型別名)typeHandlers(類型處理器)objectFactory(對象工廠)plug
49、ins(插件)environments(環(huán)境集合屬性對象)environment(環(huán)境子屬性對象)transactionManager(事務(wù)管理)dataSource(數(shù)據(jù)源)mappers(映射器)properties(屬性)SqlMapConfig.xml可以引用java屬性文件中的配置信息如下:在classpath下定義perties文件,jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql:/localhost:3306/mybatisjdbc.username=rootjdbc.password=mysqlSqlMapC
50、onfig.xml引用如下:注意: MyBatis 將按照下面的順序來加載屬性:在properties 元素體內(nèi)定義的屬性首先被讀取。然后會讀取properties 元素中resource或 url加載的屬性,它會覆蓋已讀取的同名屬性。最后讀取parameterType傳遞的屬性,它會覆蓋已讀取的同名屬性。因此,通過parameterType傳遞的屬性具有最高優(yōu)先級,resource或 url 加載的屬性次之,最低優(yōu)先級的是properties 元素體內(nèi)定義的屬性。settings(配置)mybatis全局配置參數(shù),全局參數(shù)將會影響mybatis的運(yùn)行行為。詳細(xì)參見“學(xué)習(xí)資料/mybatis-
51、settings.xlsx”文件typeAliases(類型別名)mybatis支持別名:別名映射的類型_byte byte _long long _short short _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal b
52、igdecimal BigDecimal 自定義別名:在SqlMapConfig.xml中配置:typeHandlers(類型處理器)類型處理器用于java類型和jdbc類型映射,如下:select * from userwhere id = #idmybatis自帶的類型處理器基本上滿足日常需求,不需要單獨(dú)定義。mybatis支持類型處理器:類型處理器Java類型JDBC類型BooleanTypeHandler Boolean,boolean 任何兼容的布爾值ByteTypeHandler Byte,byte 任何兼容的數(shù)字或字節(jié)類型ShortTypeHandler Short,short
53、任何兼容的數(shù)字或短整型IntegerTypeHandler Integer,int 任何兼容的數(shù)字和整型LongTypeHandler Long,long 任何兼容的數(shù)字或長整型FloatTypeHandler Float,float 任何兼容的數(shù)字或單精度浮點(diǎn)型DoubleTypeHandler Double,double 任何兼容的數(shù)字或雙精度浮點(diǎn)型BigDecimalTypeHandler BigDecimal 任何兼容的數(shù)字或十進(jìn)制小數(shù)類型StringTypeHandler String CHAR和VARCHAR類型ClobTypeHandler String CLOB和LONGVAR
54、CHAR類型NStringTypeHandler String NVARCHAR和NCHAR類型NClobTypeHandler String NCLOB類型ByteArrayTypeHandler byte 任何兼容的字節(jié)流類型BlobTypeHandler byte BLOB和LONGVARBINARY類型DateTypeHandler Date(java.util)TIMESTAMP類型DateOnlyTypeHandler Date(java.util)DATE類型TimeOnlyTypeHandler Date(java.util)TIME類型SqlTimestampTypeHand
55、ler Timestamp(java.sql)TIMESTAMP類型SqlDateTypeHandler Date(java.sql)DATE類型SqlTimeTypeHandler Time(java.sql)TIME類型ObjectTypeHandler 任意其他或未指定類型EnumTypeHandler Enumeration類型VARCHAR-任何兼容的字符串類型,作為代碼存儲(而不是索引)。mappers(映射器)Mapper配置的幾種方法:使用相對于類路徑的資源如:使用完全限定路徑如:使用mapper接口類路徑如:注意:此種方法要求mapper接口名稱和mapper映射文件名稱一樣
56、,且放在同一個目錄中。注冊指定包下的所有mapper接口如:注意:此種方法要求mapper接口名稱和mapper映射文件名稱一樣,且放在同一個目錄中。Mapper.xml映射文件Mapper.xml映射文件中定義了操作數(shù)據(jù)庫的sql,每個sql是一個statement,映射文件是mybatis的核心。parameterType(輸入類型)#與$#實(shí)現(xiàn)的是向prepareStatement中的預(yù)處理語句中設(shè)置參數(shù)值,sql語句中#表示一個占位符即?。select * from userwhere id = #id使用占位符#可以有效防止sql注入,在使用時不需要關(guān)心參數(shù)值的類型,mybatis會
57、自動進(jìn)行java類型和jdbc類型的轉(zhuǎn)換。#可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,#括號中可以是value或其它名稱。$和#不同,通過$可以將parameterType 傳入的內(nèi)容拼接在sql中且不進(jìn)行jdbc類型轉(zhuǎn)換, $可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,$括號中只能是value。使用$不能防止sql注入,但是有時用$會非常方便,如下的例子: select * from userwhere username like %$value%如果本例子使用#則傳入的字符串中必須有%號,而%是人為拼接在
58、參數(shù)中,顯然有點(diǎn)麻煩,如果采用$在sql中拼接為%的方式則在調(diào)用mapper接口傳遞參數(shù)就方便很多。/如果使用占位符號則必須人為在傳參數(shù)中加%List list = userMapper.selectUserByName(%管理員%);/如果使用$原始符號則不用人為在參數(shù)中加%Listlist = userMapper.selectUserByName(管理員);再比如order by排序,如果將列名通過參數(shù)傳入sql,根據(jù)傳的列名進(jìn)行排序,應(yīng)該寫為:ORDER BY $columnName如果使用#將無法實(shí)現(xiàn)此功能。傳遞簡單類型參考上邊的例子。傳遞pojo對象Mybatis使用ognl表達(dá)式
59、解析對象字段的值,如下例子: select * from userwhere id=#id and username like %$username%上邊紅色標(biāo)注的是user對象中的字段名稱。測試:Publicvoid testFindUserByUser()throws Exception/獲取sessionSqlSession session = sqlSessionFactory.openSession();/獲限mapper接口實(shí)例UserMapper userMapper = session.getMapper(UserMapper.class);/構(gòu)造查詢條件user對象Useru
60、ser =new User();user.setId(1);user.setUsername(管理員);/傳遞user對象查詢用戶列表Listlist = userMapper.findUserByUser(user);/關(guān)閉sessionsession.close();異常測試:Sql中字段名輸入錯誤后測試,username輸入dusername測試結(jié)果報(bào)錯:org.apache.ibatis.exceptions.PersistenceException: # Error querying database. Cause: org.apache.ibatis.reflection.Refl
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《固體廢物處理與處置》大學(xué)筆記
- 2023高考英語語法填空熱點(diǎn)話題分類訓(xùn)練:個人情況
- 濟(jì)南2024年10版小學(xué)英語第5單元測驗(yàn)卷
- 2025新譯林版英語七年級下Unit 8 Wonderland單詞表
- 強(qiáng)社會救助體系建設(shè)的調(diào)研
- 消防突發(fā)狀況的應(yīng)急預(yù)案(3篇)
- 運(yùn)輸合同(水陸聯(lián)運(yùn))(35篇)
- 試用期轉(zhuǎn)正總結(jié)(33篇)
- 致客戶慰問信
- 集團(tuán)2024年工作計(jì)劃6篇
- 金融求職自我介紹
- 標(biāo)志設(shè)計(jì)(全套課件88P)
- 2023年高考物理一輪復(fù)習(xí)練習(xí)題:靜電場及其應(yīng)用(含基礎(chǔ)、提升兩套)
- 鋰離子電池行業(yè)發(fā)展趨勢
- 第十八章 正比例函數(shù)和反比例函數(shù)(5類壓軸題專練)
- 單項(xiàng)式乘多項(xiàng)式教案
- 遼寧省大連市中山區(qū)2024-2025學(xué)年九年級上學(xué)期期中化學(xué)試題
- 天津市天津市紅橋區(qū)2024-2025學(xué)年八年級上學(xué)期10月期中英語試題
- 老舊房子改造合同模板
- 2024年云網(wǎng)安全應(yīng)知應(yīng)會考試題庫
- 湘教版(2024新版)七年級上冊數(shù)學(xué)期中考試模擬測試卷(含答案)
評論
0/150
提交評論