Java Web編程技術(shù) 課件 第15章配置文件和映射文件_第1頁
Java Web編程技術(shù) 課件 第15章配置文件和映射文件_第2頁
Java Web編程技術(shù) 課件 第15章配置文件和映射文件_第3頁
Java Web編程技術(shù) 課件 第15章配置文件和映射文件_第4頁
Java Web編程技術(shù) 課件 第15章配置文件和映射文件_第5頁
已閱讀5頁,還剩71頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

JavaWeb編程技術(shù)本章首先介紹MyBatis配置文件各種元素的含義及配置,然后學(xué)習(xí)映射文件的各種元素的使用,之后介紹MyBaits關(guān)聯(lián)映射,最后介紹動態(tài)SQL語句的定義和使用。MyBatis的配置文件MyBatis的映射文件MyBatis的關(guān)聯(lián)映射構(gòu)建動態(tài)SQL語句第15章配置文件和映射文件MyBatis應(yīng)用程序開始運(yùn)行時要讀取配置文件,配置文件用來配置MyBatis運(yùn)行的各種信息。MyBatis通過映射文件描述持久化類和數(shù)據(jù)庫表之間的映射關(guān)系。配置文件MyBatis配置文件的一些設(shè)置對MyBatis的特性有巨大影響。配置文件默認(rèn)文件名為mybatis-config.xml。配置文件的根元素是<configuration>,其子元素如下所示:properties,配置有關(guān)屬性。settings,設(shè)置運(yùn)行時全局參數(shù)。typeAliases,為Java類型設(shè)置短的別名。typeHandlers,創(chuàng)建類型處理器。objectFactory,設(shè)置自定義對象工廠。plugins,配置使用的插件。environments,配置運(yùn)行環(huán)境,如事務(wù)管理器、數(shù)據(jù)源等。databaseIdProvider,配置數(shù)據(jù)庫支持多廠商特性。mappers,配置映射器。15.1<enviroments>元素15.1.1清單15.1中的<environments>元素定義了如何配置環(huán)境。<environmentsdefault="development"><environmentid="development"><transactionManagertype="JDBC"><propertyname="closeConnection"value="false"/></transactionManager><dataSourcetype="POOLED"><propertyname="driver"value="${driver}"/><propertyname="url"value="${url}"/><propertyname="username"value="${username}"/><propertyname="password"value="${password}"/></dataSource></environment></environments><enviroments>元素15.1.1MyBatis可以配置成適應(yīng)多種環(huán)境,這種機(jī)制有助于將SQL映射應(yīng)用于多種數(shù)據(jù)庫之中。例如,開發(fā)、測試和生產(chǎn)環(huán)境需要有不同的配置。

不過要記住:盡管可以配置多個環(huán)境,每個SqlSessionFactory實(shí)例只能選擇一個環(huán)境。所以,如果想連接兩個數(shù)據(jù)庫,就需要創(chuàng)建兩個SqlSessionFactory實(shí)例,每個數(shù)據(jù)庫對應(yīng)一個環(huán)境。為了指定創(chuàng)建哪種環(huán)境,只要將它作為可選的參數(shù)傳遞給SqlSessionFactoryBuilder即可??梢越邮墉h(huán)境配置的兩個方法簽名是:SqlSessionFactoryfactory=sqlSessionFactoryBuilder.build(reader,environment);SqlSessionFactoryfactory=sqlSessionFactoryBuilder.build(reader,environment,properties);<properties>元素15.1.2<properties>元素用于配置MyBatis有關(guān)屬性,比如數(shù)據(jù)庫的連接信息。這些屬性都是可外部配置且可動態(tài)替換的,既可在典型的Java屬性文件中配置,也可通過子元素<property>配置,例如:屬性文件perties中的屬性可以在整個配置文件中使用來替換需要動態(tài)配置的屬性值。例如,下面在數(shù)據(jù)源配置<dataSource>元素中配置數(shù)據(jù)庫連接屬性。<propertiesresource="com/boda/example/perties"><propertyname="username"value="dev_user"/><propertyname="password"value="123456a"/></properties><dataSourcetype="POOLED">

<propertyname="driver"value="${driver}"/><propertyname="url"value="${url}"/><propertyname="username"value="${username}"/><propertyname="password"value="${password}"/></dataSource><settings>元素15.1.3<settings>元素用于設(shè)置MyBatis運(yùn)行時的全局參數(shù),例如開啟二級緩存、開啟延遲加載等。雖然不配置<settings>元素,MyBatis也可以正常運(yùn)行,但是熟悉<settings>的配置內(nèi)容以及它們的作用十分必要。下面是幾個常用參數(shù)的配置。<settings><settingname="cacheEnabled"value="true"/><settingname="lazyLoadingEnabled"value="true"/><settingname="multipleResultSetsEnabled"value="true"/><settingname="useColumnLabel"value="true"/><settingname="useGeneratedKeys"value="false"/>

<settingname="logImpl"value="LOG4J2"/></settings><typeAliases>元素15.1.4<typeAliases>元素用來為Java類型設(shè)置一個短的別名。它的主要作用是減少類完全限定名的冗余。使用<typeAliases>元素配置別名的方法如下。<typeAliases><typeAliasalias="Student"type="com.boda.domain.Student"/><typeAliasalias="Tutor"type="com.boda.domain.Tutor"/><typeAliasalias="Course"type="com.boda.domain.Course"/></typeAliases><typeHandlers>元素15.1.5在MyBatis為PreparedStatement設(shè)置參數(shù)或從ResultSet檢索一個值時,都會用類型處理器(TypeHandler)將獲取的值以合適的方式轉(zhuǎn)換為Java類型。表15-3列出了MyBatis常用的默認(rèn)類型處理器。注意,目前MyBatis已支持JSR-310(日期-時間API)。<objectFactory>元素15.1.6MyBatis每次創(chuàng)建結(jié)果對象的新實(shí)例時,都會使用一個對象工廠(ObjectFactory)實(shí)例來完成。

默認(rèn)的對象工廠需要做的僅僅是實(shí)例化目標(biāo)類,要么通過默認(rèn)構(gòu)造方法,要么在參數(shù)映射存在的時候通過參數(shù)構(gòu)造方法來實(shí)例化。如果想覆蓋對象工廠的默認(rèn)行為,則可以通過創(chuàng)建自己的對象工廠來實(shí)現(xiàn)。<databaseIdProvider>元素15.1.7MyBatis可以根據(jù)不同的數(shù)據(jù)庫廠商執(zhí)行不同的語句,這種多廠商的支持是基于映射語句中的databaseId屬性。MyBatis會加載不帶databaseId屬性和帶有匹配當(dāng)前數(shù)據(jù)庫databaseId屬性的所有語句。如果同時找到帶有databaseId和不帶databaseId的相同語句,則后者會被舍棄。為支持多廠商特性只要像下面這樣在mybatis-config.xml文件中加入databaseIdProvider即可:<databaseIdProvidertype="DB_VENDOR"/><mappers>元素5.1.8<mappers>元素用來配置映射器,它告訴MyBatis到哪里去找映射文件??梢允褂孟鄬τ陬惵窂降馁Y源引用,或完全限定資源定位符(包括file:///的URL),或類名和包名等。例如:<!--使用相對于類路徑的資源引用--><mappers><mapperresource="com/boda/mapper/AuthorMapper.xml"/><mapperresource="com/boda/mapper/BlogMapper.xml"/><mapperresource="com/boda/mapper/PostMapper.xml"/></mappers><!—使用URL完全限定路徑--><mappers><mapperurl="file:///var/mappers/AuthorMapper.xml"/><mapperurl="file:///var/mappers/BlogMapper.xml"/></mappers><!--使用映射器接口類--><mappers><mapperclass="com.boda.mapper.TutorMapper"/><mapperclass="com.boda.mapper.AddressMapper"/><mapperclass="com.boda.mapper.StudentMapper"/></mappers><!--注冊一個包中所有接口作為映射器--><mappers><packagename="com.boda.mapper"/></mappers>映射文件15.2

MyBatis使用映射文件描述持久化類和數(shù)據(jù)庫表之間的映射關(guān)系。映射文件的根元素是<mapper>,其namespace屬性用來指定一個命名空間名,namespace的值習(xí)慣上設(shè)置為“包名+映射文件名”,這樣可以保證namespace的值是唯一的。映射文件中<mapper>元素包含的子元素有:<select>,映射SQL查詢語句。<insert>,映射SQL插入語句。<delete>,映射SQL刪除語句。<update>,映射SQL更新語句。<cache>,給定命名空間的緩存配置。<cache-ref>,其他命名空間緩存配置的引用。<sql>,可被其他語句引用的可重用語句塊。<resultMap>,最復(fù)雜也是最強(qiáng)大的元素,描述如何從數(shù)據(jù)庫結(jié)果集中加載對象。<select>元素15.2.1<select>元素用于定義一個SQL查詢語句,該查詢語句供SqlSession對象的查詢方法執(zhí)行數(shù)據(jù)庫查詢。下面<select>元素根據(jù)學(xué)生stud_id查詢學(xué)生信息。<selectid="findStudentById"parameterType="Integer"resultType="com.boda.domain.Student">SELECTstud_idAS

studId,name,gender,birthday,phoneFROMstudentsWHEREstud_id=#{studId}</select><select>元素15.2.1注意,#{studId}用于指定一個名為studId的參數(shù)。這將使MyBatis創(chuàng)建一個預(yù)處理語句,語句中參數(shù)用一個“?”來標(biāo)識,并將參數(shù)值傳遞到預(yù)處理語句中。以上語句執(zhí)行時會生成如下JDBC代碼。Stringsql="SELECTstud_idASstudId,name,gender,birthday,phoneFROMstudentsWHEREstud_id=?";PreparedStatementps=conn.prepareStatement(sql);ps.setInt(1,studId);<select>元素15.2.1MyBatis將執(zhí)行查詢語句并將查詢結(jié)果映射到結(jié)果對象中,這就是MyBatis節(jié)省時間的地方。下面代碼是為該SQL語句創(chuàng)建的Mapper接口。packagecom.boda.mapper;publicinterfaceStudentMapper{StudentfindStudentById(IntegerstudId);}StudentMapper接口中定義了findStudentById()方法。注意,該方法名必須與<select>元素映射的id屬性值相同。在測試類MyBatisTest中編寫findStudentByIdTest()方法,查詢stud_id值為20221002的學(xué)生信息,代碼如下。@TestpublicvoidfindStudentByIdTest(){SqlSessionsession=MyBatisUtil.getSession();StudentMappermapper=session.getMapper(StudentMapper.class);try{ Studentstudent=mapper.findStudentById(20220009); if(student!=null)System.out.println(student);elseSystem.out.println("查無此記錄");}catch(Exceptione){ System.out.println(e);}finally{mit();session.close();}}<select>元素15.2.1有時查詢結(jié)果并不能(或不需要)映射到一個POJO對象,這時可以將resultType屬性設(shè)置為map或hashmap,使得查詢結(jié)果返回一個HashMap對象,查詢結(jié)果字段名作為Map的鍵名,字段值作為Map的值,在程序中對結(jié)果Map對象進(jìn)行迭代即可。<selectid="selectSumSalary"resultType="hashmap">SELECTid,name,salary*12assumsalaryFROMemployees</select><select>元素15.2.1假設(shè)在EmployeeMapper接口中定義了selectSumSalary()方法。在測試類MyBatisTest中編寫selectSumSalaryTest()方法,查詢所有員工id、name和sumsalary,它是salary*12的結(jié)果,代碼如下。publicvoidselectSumSalaryTest(){SqlSessionsession=MyBatisUtil.getSession();EmployeeMappermapper=session.getMapper(EmployeeMapper.class);try{

List<Map<String,Object>>result=mapper.selectSumSalary(); if(result!=null){for(Map<String,Object>hm:result){ System.out.println(hm);}}elseSystem.out.println("查無此記錄");}catch(Exceptione){System.out.println(e);}finally{ mit();session.close();}}參數(shù)傳遞15.2.2在有些SQL語句(包括SELECT、INSERT、UPDATE和DELETE)中可以使用參數(shù),參數(shù)可以是簡單的類型(如,int、double),也可以是復(fù)雜的類型(如,JavaBean或Map等)。語句的參數(shù)類型使用parameterType屬性指定。下面映射語句帶一個int型的簡單參數(shù)。<selectid="selectUser"parameterType="int"

resultType="com.boda.domain.User">SELECTuser_id,user_name,user_passwordFROMuserswhereuser_id=#{id}</select>參數(shù)傳遞15.2.2參數(shù)是MyBatis非常強(qiáng)大的元素,也可以為SQL語句傳遞一個復(fù)雜的對象,比如:這里為INSERT語句傳遞一個User類型的參數(shù),MyBatis會查找User對象的id、username和password屬性,然后將它們的值傳入PreparedStatement語句的對應(yīng)參數(shù)中。<insertid="insertUser"parameterType="com.boda.domain.User">INSERTINTOusers(user_id,user_name,user_password)VALUES(#{id},#{username},#{password})</insert>在傳遞參數(shù)時還可以指定參數(shù)的具體類型,如下所示。#{amount,javaType=int,jdbcType=NUMERIC}<insert>元素15.2.3<insert>元素用于定義SQL插入語句,在執(zhí)行完定義的SQL語句后,會返回一個表示插入記錄數(shù)的整數(shù)。下面的<insert>元素配置在students表中插入一行,如下所示:這里,語句id值為insertStudent,它唯一標(biāo)識INSERT語句。parameterType屬性值應(yīng)該是完全限定的類名或類型別名。<insertid="insertStudent"parameterType="com.boda.domain.Student">INSERTINTOstudents(stud_id,name,gender,birthday,phone)VALUES(#{studId},#{name},#{gender},#{birthday},#{phone})</insert><insert>元素15.2.3假設(shè)在StudentMapper接口中定義了如下insertStudent()方法:就可以像下面這樣調(diào)用insertStudent映射語句:publicinterfaceStudentMapper{intinsertStudent(Studentstudent);}StudentMappermapper=sqlSession.getMapper(StudentMapper.class);intcount=mapper.insertStudent(student);<insert>元素15.2.3<insert>元素用于定義SQL插入語句,在執(zhí)行完定義的SQL語句后,會返回一個表示插入記錄數(shù)的整數(shù)。下面的<insert>元素配置在students表中插入一行,如下所示:這里,語句id值為insertStudent,它唯一標(biāo)識INSERT語句。parameterType屬性值應(yīng)該是完全限定的類名或類型別名。<insertid="insertStudent"parameterType="com.boda.domain.Student">INSERTINTOstudents(stud_id,name,gender,birthday,phone)VALUES(#{studId},#{name},#{gender},#{birthday},#{phone})</insert><update>元素15.2.4<update>元素用于定義SQL更新語句,它的使用比較簡單,它的屬性與<select>元素屬性基本相同。下面的更新語句根據(jù)studId值更新students表的name、gender、birthday和phone字段值,新值通過一個Student對象提供。這里的參數(shù)名是傳遞來的持久對象的屬性名,它們可以與表的字段名不同,可以只更新部分字段值。與<insert>元素一樣,<update>元素定義的更新語句在執(zhí)行完后,也會返回一個表示所影響的記錄行數(shù)的整數(shù)值。<updateid="updateStudent"parameterType="com.boda.domain.Student">UPDATEstudentsSETname=#{name},gender=#{gender},birthday=#{birthday},phone=#{phone}WHEREstud_id=#{studId}</update><update>元素15.2.4假設(shè)在StudentMapper接口中定義了如下updateStudent(Studentstudent)方法:publicinterfaceStudentMapper{intupdateStudent(Studentstudent);}<update>元素15.2.4在測試類MyBatisTest中編寫updateStudentTest()方法,更新studId值為20221020的學(xué)生姓名name值修改為“張小明”,gender修改為“女”,出生日期birthday修改為“2000-05-10”,電話phone修改為“987654321”,代碼如下。publicvoidupdateStudentTest(){ SqlSessionsession=MyBatisUtil.getSession();StudentMappermapper=session.getMapper(StudentMapper.class);try{Studentstudent=newStudent(20221020,"張明宇","女",LocalDate.of(2000,05,10),"987654321"); introws=mapper.updateStudent(student);if(rows==1)System.out.println("記錄更新成功");elseSystem.out.println("記錄更新失敗");}finally{ mit();session.close();}}<delete>元素15.2.5<delete>元素用于定義SQL刪除語句,它的使用也比較簡單,它的屬性與<select>元素屬性基本相同。下面的<delete>元素定義了刪除語句,它根據(jù)studId值刪除students表中的記錄。這里的參數(shù)studId可以通過Student對象傳遞,也可以通過Map對象傳遞。假設(shè)在StudentMapper接口中定義了如下deleteStudent(Map<String,Integer>param)方法:<deleteid="deleteStudent"parameterType="map">DELETEFROMstudentsWHEREstud_id=#{studId}</delete>publicinterfaceStudentMapper{intdeleteStudent(Map<String,Integer>param);}<delete>元素15.2.5

在測試類MyBatisTest中編寫deleteStudentTest()方法,刪除studId值為20221020的學(xué)生,代碼如下。publicvoiddeleteStudentTest(){SqlSessionsession=MyBatisUtil.getSession();StudentMappermapper=session.getMapper(StudentMapper.class);try{Map<String,Integer>params=newHashMap<>();params.put("studId",20221020); introws=mapper.deleteStudent(params);if(rows==1)System.out.println("成功刪除"+rows+"條記錄");elseSystem.out.println("刪除記錄失敗");}finally{ mit();session.close();}}<resultMap>元素15.2.6<resultMap>元素用于定義一個結(jié)果集映射,它的作用是將SELECT語句的結(jié)果映射到JavaBean的屬性??梢远xResultMap,之后就可以在其他的SELECT語句中引用該<resultMap>。

該元素是功能最強(qiáng)大的元素,用它可以映射簡單的SELECT語句,也可以映射帶一對一關(guān)聯(lián)和一對多關(guān)聯(lián)的復(fù)雜SELECT語句。15.2.61.簡單的ResultMap下面是一個簡單的ResultMap,它將一個簡單查詢的結(jié)果映射到Student這個JavaBean上。<resultMapid="studentResult"type="com.boda.domain.Student"><idproperty="studId"column="stud_id"/><resultproperty="name"column="name"/><resultproperty="gender"column="gender"/><resultproperty="birthday"column="birthday"/><resultproperty="phone"column="phone"/></resultMap>這里,id屬性指定這個resultMap的唯一標(biāo)識,type屬性指定這個resultMap實(shí)際返回的類型,它可以是完整的類名,也可以是別名。property屬性指定結(jié)果JavaBean類的屬性名,column屬性指定數(shù)據(jù)庫表的字段名。15.2.6有了這個ResultMap,我們就可以在<select>元素中使用resultMap屬性而不是resultType來引用這個studentResult映射。當(dāng)為<select>元素配置resultMap屬性時,MyBatis使用屬性映射的列來填充JavaBean屬性。下面兩個<select>元素中使用了studentResult映射。<selectid="findAllStudents"resultMap="studentResult">SELECT*FROMSTUDENTS</select><selectid="findStudentById"parameterType="int"resultMap="studentResult">SELECT*FROMSTUDENTSWHEREstud_id=#{studId}</select>15.2.62.擴(kuò)展的ResultMap可以從另一個<resultMap>查詢擴(kuò)展一個<resultMap>查詢,從而繼承該列,從被擴(kuò)展的列進(jìn)行屬性映射。假設(shè)已經(jīng)定義了id為studentResult的映射,如果我們需要查詢學(xué)生及地址信息,就可以擴(kuò)展studentResult映射實(shí)現(xiàn),這需要使用extends屬性,如下代碼所示。<resultMapid="studentWithAddressResult"type="com.boda.domain.Student"

extends="studentResult"><resultproperty="address.addrId"column="addr_id"/><resultproperty="address.city"column="city"/><resultproperty="address.street"column="street"/><resultproperty="address.zipcode"column="zipcode"/></resultMap>15.2.6現(xiàn)在如果要將查詢Student結(jié)果與查詢Address結(jié)果映射到一起,就可以使用resultMap與studentWithAddressResult一起使用,如下所示:<selectid="selectStudentWithAddress"parameterType="int"resultMap="studentWithAddressResult">SELECTstud_id,name,gender,birthday,phone,a.addr_id,city,street,zipcodeFROMstudentssleftouterjoinaddressaons.addr_id=a.addr_idWHEREstud_id=#{studId}</select><sql>元素15.2.7<sql>元素用于定義一個可復(fù)用的SQL代碼片段,它可以包含在其他語句中。下面代碼定義一個名為empColumns的SQL片段,然后在<select>元素中引用它。在其他元素中使用<include>元素引用SQL片段,它用refid屬性指定所引用的SQL片段的id。<sqlid="empColumns">id,name,title,salary</sql><selectid="selectEmployee"resultType="com.boda.domain.Employee">SELECT<includerefid="empColumns"/>FROMemployees</select><sql>元素15.2.7還可定義參數(shù)化SQL片段,通過${param_name}指定參數(shù),在include元素中使用property子元素指定參數(shù)值,例如。該SQL片段就可被包含在另一個語句中,如下所示。<sqlid="userColumns">${alias}.id,${alias}.username,${alias}.password</sql><selectid="selectUsers"resultType="map">SELECT<includerefid="userColumns"><propertyname="alias"value="t1"/></include>,<includerefid="userColumns"><propertyname="alias"value="t2"/></include>FROMsome_tablet1CROSSJOINsome_tablet2</select>

<cache>元素15.2.8MyBatis提供了緩存機(jī)制來緩存查詢數(shù)據(jù),以提高查詢的性能。MyBatis的緩存分為一級緩存和二級緩存。1.一級緩存一級緩存是SqlSession級別的緩存,是基于HashMap的本地緩存。不同的SqlSession之間的緩存數(shù)據(jù)區(qū)域互不影響。一級緩存的作用域是會話范圍,當(dāng)同一個SqlSession執(zhí)行兩次相同的SQL語句時,第一次執(zhí)行完后會將查詢的數(shù)據(jù)寫到緩存,第二次查詢時直接從緩存獲取不用去數(shù)據(jù)庫查詢。當(dāng)SqlSession執(zhí)行INSERT、UPDATE、DELETE操做并提交到數(shù)據(jù)庫時,會清空緩存,保證緩存中的信息是最新的。

<cache>元素15.2.82.二級緩存二級緩存是Mapper級別的緩存,同樣是基于HashMap進(jìn)行存儲,多個SqlSession可以共用二級緩存,其作用域是mapper的同一個namespace。不同的SqlSession兩次執(zhí)行相同的namespace下的sql語句,會執(zhí)行相同的sql,第二次查詢只會查詢第一次查詢時讀取數(shù)據(jù)庫后寫到緩存的數(shù)據(jù),不會再去數(shù)據(jù)庫查詢。MyBatis默認(rèn)開啟一級緩存,要開啟二級緩存,只需在SQL映射文件中寫入如下代碼:<cache/>MyBatis關(guān)聯(lián)映射15.3

在SQL的查詢語句中,如果查詢結(jié)果來自多個表的數(shù)據(jù),需要使用連接查詢。這種關(guān)聯(lián)在Java程序中需要通過對象的關(guān)聯(lián)實(shí)現(xiàn)。

在MyBatis中,這種關(guān)聯(lián)通過<association>和<collection>元素實(shí)現(xiàn),前者實(shí)現(xiàn)一對一關(guān)聯(lián),后者實(shí)現(xiàn)一對多關(guān)聯(lián)。一對一關(guān)聯(lián)映射15.3.1一對一關(guān)聯(lián)在實(shí)際應(yīng)用中比較常見,例如學(xué)生(Student)與學(xué)生的地址(Address)之間就具有一對一的關(guān)聯(lián)關(guān)系,如圖15-7所示。一對一關(guān)聯(lián)映射15.3.1下面通過實(shí)例說明如何實(shí)現(xiàn)這種關(guān)聯(lián)映射。(1)創(chuàng)建數(shù)據(jù)表。在數(shù)據(jù)庫中創(chuàng)建address表和students表,同時插入兩條數(shù)據(jù)。執(zhí)行的SQL語句如清單15.2所示。清單15.2創(chuàng)建address表和students表及插入數(shù)據(jù)CREATETABLEaddress(addr_idINTPRIMARYKEYAUTO_INCREMENT,--IDcityVARCHAR(20),--城市streetVARCHAR(20),--街道zipcodeVARCHAR(6)--郵編);#插入兩條數(shù)據(jù)INSERTINTOaddressVALUES(1,'廣州','黃埔區(qū)5號','510700');INSERTINTOaddressVALUES(2,'北京','海淀區(qū)28號','100089');#創(chuàng)建students表,其中addr_id引用address表的addr_id列,是外鍵CREATETABLEstudents(stud_idINTEGERAUTO_INCREMENTPRIMARYKEY,--IDnameVARCHAR(20)NOTNULL,--姓名genderVARCHAR(4),--性別birthdayDATE,--出生日期phoneVARCHAR(14),--電話

addr_idINT,--外鍵,引用address表的addr_idFOREIGNKEY(addr_id)REFERENCESaddress(addr_id));#插入兩條數(shù)據(jù)INSERTINTOstudentsVALUES(20220008,'張大海','男','1983-10-20','8899123',1);INSERTINTOstudentsVALUES(20220009,'李清泉','女','1990-12-31','1305045168',2);一對一關(guān)聯(lián)映射15.3.1(2)在項(xiàng)目的com.boda.domain包中創(chuàng)建Address和Student實(shí)體類,為了建立Student和Address之間的一對一關(guān)聯(lián),在Student類中定義了引用Address類的屬性(address)及setter和getter方法。代碼如清單15.3和清單15.4所示。清單15.3Address.java清單15.4修改Student.java,添加address屬性及方法Address.java清單15.3@Data@NoArgsConstructor@AllArgsConstructorpublicclassAddressimplementsSerializable{privateIntegeraddrId;privateStringcity;privateStringstreet;@Override publicStringtoString(){ return"地址:"+city+street+zipcode; }}修改Student.java,添加address屬性及方法清單15.4publicclassStudentimplementsSerializable{…privateAddressaddress;

publicAddressgetAddress(){ returnaddress;}publicvoidsetAddress(Addressaddress){ this.address=address;}

@OverridepublicStringtoString(){ return"學(xué)生[studId="+studId+",name="+name+",gender="+gender+",birthday="+birthday+",phone="+phone+"]“+"\n"+address;}}一對一關(guān)聯(lián)映射15.3.1(3)在com.boda.mapper包中創(chuàng)建Address類和Student類的映射文件AddressMapper.xml和StudentMapper.xml,并在兩個映射文件中編寫一對一關(guān)聯(lián)映射查詢的配置信息,如清單15.5和清單15.6所示。清單15.5AddressMapper.xml清單15.6StudentMapper.xmlAddressMapper.xml清單15.5<mappernamespace="com.boda.mapper.AddressMapper"><!--定義addressResult結(jié)果映射--><resultMapid="addressResult"type="com.boda.domain.Address"><idproperty="addrId"column="addr_id"/><resultproperty="city"column="city"/><resultproperty="street"column="street"/><resultproperty="zipcode"column="zipcode"/></resultMap><!--根據(jù)addrId查詢地址信息--><selectid="selectAddressById"parameterType="Integer“

resultMap="addressResult">SELECT*FROMaddressWHEREaddr_id=#{addrId}</select></mapper>StudentMapper.xml清單15.6<mappernamespace="com.boda.mapper.StudentMapper"><!--定義一個resultMap進(jìn)行關(guān)聯(lián)查詢--><resultMapid="studentResultWithAddress"type="com.boda.domain.Student"><idproperty="studId"column="stud_id"/><resultproperty="name"column="name"/><resultproperty="gender"column="gender"/>…

<associationproperty="address"column="addr_id"javaType="com.boda.domain.Address"select="com.boda.mapper.AddressMapper.selectAddressById"/></resultMap><!--定義一個SELECT語句,根據(jù)指定studId查詢表數(shù)據(jù)。--><selectid="selectStudentById"parameterType="Integer"resultMap="studentResultWithAddress">SELECT*FROMstudentsWHEREstud_id=#{studId}</select></mapper>一對一關(guān)聯(lián)映射15.3.1(4)在核心配置文件mybatis-config.xml中,引入Mapper映射文件并定義別名,如程序所示。<mappers><mapperresource="com/boda/mapper/AddressMapper.xml"/><mapperresource="com/boda/mapper/StudentMapper.xml"/></mappers>一對一關(guān)聯(lián)映射15.3.1(5)在com.boda.mapper包中,創(chuàng)建Address類和Student類的Mapper映射器接口,代碼如下所示。清單15.7AddressMapper.javapublicinterfaceAddressMapper{//根據(jù)addrId查詢Address方法AddressselectAddressById(intaddrId);}一對一關(guān)聯(lián)映射15.3.1清單15.8StudentMapper.javapackagecom.boda.mapper;importcom.boda.doamin.Student;publicinterfaceStudentMapper{//根據(jù)studId查詢Student方法StudentselectStudentById(intstudId);}一對一關(guān)聯(lián)映射15.3.1(6)在com.boda.test包的MyBatisTest類中,編寫測試方法selectStudentByIdTest(),代碼如下所示。@TestpublicvoidselectStudentByIdTest(){SqlSessionsession=MyBatisUtil.getSession();try{StudentMappermapper=session.getMapper(StudentMapper.class);Studentstudent=mapper.selectStudentById(20221002);System.out.println(student);//輸出查詢到的學(xué)生信息}finally{mit();session.close();}}一對多關(guān)聯(lián)映射15.3.2一對多關(guān)聯(lián)最常見,例如一名教師(Tutor)可講授多門課程(Course)就是典型的一對多聯(lián)系,如圖15-9所示。下面以教師和課程為例說明如何進(jìn)行一對多關(guān)聯(lián)的映射。一對多關(guān)聯(lián)映射15.3.2MyBatis在處理一對多關(guān)聯(lián)時使用<resultMap>的<collection>子元素。<collection>子元素的大部分屬性與<association>元素的屬性相同,但其還包含一個名為ofType的特殊屬性。ofType屬性與javaType屬性對應(yīng),它用于指定持久化對象中集合類屬性所包含的元素類型。<collection>元素的使用也非常簡單,同樣可以參考如下兩個示例進(jìn)行配置,具體代碼如下。<!--方式一:嵌套查詢--><collectionproperty="courses"ofType="com.boda.domain.Course"select="com.boda.mapper.TutorMapper.selectTutorById"><!--方式二:嵌套結(jié)果--><collectionproperty="courses"ofType="com.boda.domain.Course"><idproperty="tutorId"column="tutor_id"/><resultproperty="name"column="name"/><resultproperty="title"column="title"/><resultproperty="email"column="email"/></collection>一對多關(guān)聯(lián)映射15.3.2(1)在數(shù)據(jù)庫中創(chuàng)建兩個表,分別為tutors和courses,用于存儲教師和課程數(shù)據(jù),同時在表中插入幾條數(shù)據(jù),執(zhí)行的SQL語句如下。清單15.9創(chuàng)建tutors表和courses表及插入數(shù)據(jù)。CREATETABLEtutors(tutor_idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(10),titleVARCHAR(10),emailVARCHAR(20));#創(chuàng)建名為courses課程表CREATETABLEcourses(course_idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(20),start_dateDATE,end_dateDATE,tutor_idINTREFERENCEStutors(tutor_id));一對多關(guān)聯(lián)映射15.3.2(2)在com.boda.domain包中,創(chuàng)建Course和Tutor類,代碼如清單15.10和15.11所示。清單15.10Course.java清單15.11Tutor.javapublicclassTutor{privateIntegertutorId;privateStringname;privateStringtitle;privateStringemail;privateList<Course>courses;//教師講授的課程列表一對多關(guān)聯(lián)映射15.3.2(3)在com.boda.mapper包中,創(chuàng)建Tutor類的映射文件TutorMapper.xml,并在文件中編寫一對多關(guān)聯(lián)映射查詢的配置,代碼如清單15.12所示。本例采用嵌套結(jié)果的方式進(jìn)行映射。清單15.12TutorMapper.xml一對多關(guān)聯(lián)映射15.3.2(4)將映射文件TutorMapper.xml添加到核心配置文件mybatis-config.xml中,其代碼如下所示。<mapperresource="com/boda/mapper/TutorMapper.xml"/>(5)在com.boda.mapper包中,創(chuàng)建Tutor類的Mapper映射器接口,代碼如下所示。清單15.13TutorMapper.javapublicinterfaceTutorMapper{//根據(jù)tutorId查詢Tutor對象TutorselectTutorById(inttutorId);}一對多關(guān)聯(lián)映射15.3.2(6)在測試類com.boda.test.MyBatisTest中編寫測試方法selectTutorByIdTest(),代碼如下所示。@TestpublicvoidselectTutorByIdTest(){SqlSessionsession=MyBatisUtil.getSession();TutorMappermapper=session.getMapper(TutorMapper.class);try{Tutortutor=mapper.selectTutorById(2); //輸出指定教師的任課信息System.out.println(tutor); System.out.println(tutor.getCourses()); }finally{mit(); session.close();}}動態(tài)SQL15.4MyBatis允許在映射SQL語句中使用動態(tài)功能,它是通過標(biāo)簽元素實(shí)現(xiàn)的。如果用戶使用過JSTL,這些動態(tài)SQL語句標(biāo)簽就很容易理解,常用元素如表15-8所示。元素說明<if>判斷語句,用于單條件分支判斷<choose>、<when>和<otherwise>用于多條件分支判斷。相當(dāng)于Java的switch…case結(jié)構(gòu)<where>、<set>和<trim>用于指定SQL的條件以及UPDATE語句的SET以及特殊字符問題<foreach>循環(huán)語句,常用于in語句等列舉條件中<bind>從OGNL表達(dá)式中創(chuàng)建一個變量,并將其綁定到上下文,常用于模糊查詢的語句<if>元素15.4.1在動態(tài)SQL中最常見的情況就是在SQL的WHERE子句中有條件地包含一部分內(nèi)容,例如:<selectid="findActiveEmployee"resultType="Employee">SELECT*FROMemployeeWHEREstate=’ACTIVE’<iftest="title!=null">ANDtitleLIKE#{title}</if></select><if>元素15.4.1也可以使用<if>提供多個條件,如下所示:<selectid="findActiveEmployee"resultType="Employee">SELECT*FROMemployeeWHEREstate=’ACTIVE’<iftest="title!=null">ANDtitleLIKE#{title}</if><iftest="salary!=null">ANDsalary>#{salary}</if></select><if>元素15.4.1下面通過實(shí)例說明動態(tài)SQL語句的使用。按下列步驟創(chuàng)建項(xiàng)目及有關(guān)文件。(1)首先在數(shù)據(jù)庫中創(chuàng)建employees表,并向表中插入若干記錄,代碼如下。CREATETABLEemployees(

idINTPRIMARYKEYAUTO_INCREMENT,--員工id

nameVARCHAR(10),--姓名

titleVARCHAR(10),--職務(wù)

ageINT,--年齡

salaryDECIMAL(8,2),--工資

statusVARCHAR(10)--狀態(tài));<if>元素15.4.1(2)在com.boda.domain包中創(chuàng)建Employee實(shí)體類,代碼如下。清單15.14Employee.javapublicclassEmployee{privateIntegerid;privateStringname;privateStringtitle;privateintage;privatedoublesalary;privateStringstatus;}<if>元素15.4.1(3)在com.boda.mapper包中,創(chuàng)建EmployeeMapper.xml映射文件,使用<if>元素定義一個SQL查詢語句,如下所示。<mappernamespace="com.boda.mapper.EmployeeMapper"><selectid="findActiveEmployee"resultType="com.boda.domain.Employee">SELECT*FROMemployeesWHEREstatus='ACTIVE'<iftest="title!=null">ANDtitleLIKE#{title}</if><iftest="salary!=null">ANDsalary>#{salary}</if></select></mapper><if>元素15.4.1(4)將映射文件EmployeeMapper.xml路徑添加到配置文件mybatis-config.xml中。<mapperresource="com/boda/mapper/EmployeeMapper.xml"/>(5)在com.boda.mapper包中,創(chuàng)建EmployeeMapper.java映射器接口,其中定義selectEmployeeOnCondition()方法。清單15.15EmployeeMapper.javaimportcom.boda.domain.Employee;publicinterfaceEmployeeMapper{//根據(jù)條件查詢員工信息 publicList<Employee>findActiveEmployee(Objectparam);}<if>元素15.4.1在測試類MyBatisTest中,編寫測試方法findActiveEmployeeOTest(),代碼如下所示。@TestpublicvoidfindActiveEmployeeTest(){SqlSessionsession=MyBatisUtil.getSession();Map<String,String>param=newHashMap<>();

param.put("status","ACTIVE");try{ EmployeeMappermapper=session.getMapper(EmployeeMapper.class); List<Employee>employee

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論