您好,登錄后才能下訂單哦!
簡單查詢-resultType
數據準備
字段 | 注釋 |
---|---|
SNO | 學號 |
SNAME | 學生名字 |
SSEX | 性別 |
SBIRITHDAY | 生日 |
CLASS | 班級 |
<!--建表語句:--> create table TEST.STUDENT ( SNO varchar(3) not null, SNAME varchar(4) not null, SSEX varchar(2) not null, SBIRTHDAY datetime null, CLASS varchar(5) null )
<!--Bean 文件--> public class Student { private String SNO; private String SNAME; private String SSEX; private Date SBIRTHDAY; private String CLASS; <!--get 和 set 方法--> ... }
例子
按照返回數據類型大致分為基礎數據類型,JavaBean 和 Map。其中雖然返回的結果行數有單條也有多條,對應的接口返回類型是集合或者單個對象,但是在 xml 映射文件中,resultType 的值是相同的。
1、指定字段-基礎數據類型
接口類:
<!--單條結果集--> String querySingleStudent(); <!--多條結果集--> List<String> queryAllStudent();
Mapper 文件:
<!--單條結果集--> <select id="querySingleStudent" resultType="string"> SELECT SNAME FROM TEST.STUDENT LIMIT 1 </select> <!--多條結果集--> <select id="queryAllStudent" resultType="string"> SELECT SNAME FROM TEST.STUDENT </select>
2、Map,一般為 hashMap
接口類:
<!--單條結果集--> Map<String, Object> queryStudentMap(); <!--多條結果集--> List<Map<String, Object>> queryAllStudentMap(); 復制代碼Mapper 文件: <!--單條結果集--> <select id="queryStudentMap" resultType="hashmap"> SELECT SNAME FROM TEST.STUDENT LIMIT 1 </select> <!--多條結果集--> <select id="queryAllStudentMap" resultType="hashmap"> SELECT SNAME FROM TEST.STUDENT </select>
其中:
3、JavaBean
接口類:
<!--單條結果集--> Student querySingleStudentBean(); <!--多條結果集--> List<Student> queryAllStudentBean();
Mapper 文件:
<!--單條結果集--> <select id="queryStudentMap" resultType="student"> SELECT SNAME FROM TEST.STUDENT LIMIT 1 </select> <!--多條結果集--> <select id="queryAllStudentMap" resultType="student"> SELECT SNAME FROM TEST.STUDENT </select>
resultType="student" 為 Student.java 的別名,也可以是全限定名。別名在 mybatis-config.xml 配置文件中設置:
<typeAliases> <typeAlias type="com.bean.Student" alias="student"/> ... </typeAliases>
但是如果 JavaBean 文件很多,不想一個個指定,也可以使用 package 標簽 設置mybatis自動掃描,別名即為類名的小寫。
<typeAliases> <package name="包名"/> </typeAliases>
復雜查詢 resultMap
對于一般的查詢語句,resultType 足夠了。對于多表查詢等情況,就要請出 resultMap 了。
數據庫字段和 java 數據類型映射關系
數據庫字段類型 jdbcType 和 java 數據類型 并不是一一對應的關系,而且不同數據庫類型也不盡相同。而 mybatis 將 TypeHandler 作為兩者之間的映射關系。大部分情況下都是沒有問題的,但是并非能覆蓋所有的情況,特殊情況下可以使用 resultMap 自定義這種映射關系。
舉個例子,數據庫 LongVarchar 字段類型對應 java 中的 String 類型。但是在 DB2 數據庫中,查詢的 LongVarchar 類型的字段,在 mybatis 中被識別成 jdbcType 為 BLOB。有兩種解決方法,第一種是在 SQL 中對該字段使用 CAST 轉換為 VARCHAR(長度)類型。另一種是使用 resultMap:
<resultMap id="resultMapDemo" type="" autoMapping="true"> <result property="" column="" jdbcType="VARCHAR" /> </resultMap> <select id="demoID" resultMap="resultMapDemo"> ... <select>
1、<select>標簽中使用 resultMap 指定返回集合。注意 resultMap 和 resultType 不能同時使用
2、<resultMap> 標簽
3、<result> 標簽
id
字段的映射關系的標簽即有,也有,在 mybatis 文檔中指出不使用id,會造成性能下降,因此將主鍵字段使用 id 標簽是推薦的做法。但是如果不存在主鍵呢,當你在 ResultMap 只提供了部分字段而不是全部字段,即使使用了 autoMapping 屬性,那么 mybatis 會按照你提供的字段名進行去重。那么在使用 resultMap 的時候,最優選擇是:
多表關聯查詢
在 resultType 的例子中都只涉及到一張表,如果涉及多張表關聯查詢呢。我們可以簡單的將所有列映射到 hashmap 的鍵值上。
但是 HashMap 不是一個很好的領域模型。 你的程序更可能會使用 JavaBean 或 POJO(Plain Old Java Objects,普通 Java 對象)作為領域模型。
因此這里均采用 JavaBean 作為領域模型。增加一個成績表 Score
字段 | 注釋 |
---|---|
SNO | 學號 |
CNO | 課程編號 |
DEGREE | 成績 |
<!--建表語句--> create table SCORE ( SNO varchar(3) not null, CNO varchar(5) not null, DEGREE decimal(10, 1) not null )
<!--Bean 文件--> public class Score { private String SNO; private String CNO; private Double DEGREE; <!--get 和 set 方法--> ... }
一對一關系
這里的一對多關系是兩個表字段一一對應,一個學生的某門課的成績是唯一確定的。 在一一對應的情況下要在 resultMap 中使用 標簽。
在 Student.java 中增加字段 Score
<!--Student.java--> private Score score; public Score getScore() { return score; } public void setScore(Score score) { this.score = score; }
有兩種使用情況,第一種為嵌套查詢,即前一個 SQL 查詢結果集中的字段作為參數傳遞給下一個 SQL。第二種情況為嵌套結果集,即兩個表做關聯查詢,將結果集映射到多個 JavaBean 文件。
嵌套查詢
<resultMap id="allstudentResultMap" type="student"> <!--指定第二個 SELECT 語句,和傳遞的字段--> <association property="score" column="sno" select="queryScore" /> </resultMap> <!--第一個 SQL --> <select id="queryAllStudent" resultMap="allstudentResultMap"> select SNO,SNAME from test.STUDENT </select> <!--第二個 SQL--> <select id="queryScore" resultType="score"> select degree from test.SCORE where sno = #{sno} </select>
在標簽中
另外需要注意的是這種嵌套查詢對于大型結果集和列名并友好,存在 N+1 的問題,因為下一條 SQL 會執行 N 次去循環查詢,使用關聯查詢更合適。再者也可以開啟 mybatis 的懶查詢功能,嵌套的 SQL 不是一口氣順序執行完,而是在使用的時候才會執行下一條 SQL。例如執行student.getScore().getSNO()才會執行queryScore的 SQL。默認情況下沒有開啟,需要在配置文件中設置
設置參數 | 描述 | 默認值 |
---|---|---|
lazyLoadingEnabled | 延遲加載的全局開關,特定關聯關系中可通過設置 fetchType 屬性來覆蓋該項的開關狀態 | false |
aggressiveLazyLoading | 當開啟時,任何方法的調用都會加載該對象的所有屬性。否則,每個屬性會按需加載 | false (true in ≤3.4.1) |
<!--mybatis-config.xml--> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/>
也可以在標簽中設置 fetchType = “lazy” 開啟懶加載,會覆蓋全局的參數設置。
嵌套結果集
對于多表關聯查詢,一般在 SQL 中使用別名來避免字段名的重復。mybatis 要做的是將別名正確的映射到 JavaBean 屬性上。
<!--嵌套結果--> <resultMap id="associationDemoMap" type="student" autoMapping="true"> <association property="score" javaType="score"> <result property="SNO" column="SC_SNO"/> </association> </resultMap> <select id="queryStudentScore" resultMap="associationDemoMap"> SELECT SNAME, SSEX, CLASS, ST.SNO, SC.SNO AS SC_SNO FROM test.student st INNER JOIN test.score sc ON st.sno = sc.sno where CNO = '3-105'; </select>
通過設置標簽指定了表列名和屬性之間的映射關系。但這樣如果字段很多,會需要一一指定,標簽提供了columnPrefix屬性,指定別名的前綴,這樣可以重用resultMap
<resultMap id="associationDemoMap" type="student" autoMapping="true"> <!--columnPrefix 指定別名的前綴--> <association property="score" resultMap="anotherMap" columnPrefix="SC_" /> </resultMap> <!--方便重用--> <resultMap id="anotherMap" type="score" autoMapping="true"> </resultMap>
一對多關系
除了一對一的關系,還有一對多的關系,比如這里一個學生Student 對應多門課的成績。 一對多對應的情況下要在 resultMap 中使用 標簽。首先需要調整 JavaBean 文件中兩個表之間的關系。
<!--Student.java--> private List<Score> score; public List<Score> getScore() { return score; } public void setScore(List<Score> score) { this.score = score; }
以嵌套結果集為例
<resultMap id="collectionDemoMap" type="student" autoMapping="true"> <!--多出了 ofType 屬性--> <collection property="score" ofType="score"> <result property="SNO" column="SC_SNO"/> </collection> </resultMap> <select id="queryStudentScore" resultMap="collectionDemoMap"> SELECT SNAME,SSEX,CLASS,ST.SNO,SC.SNO AS SC_SNO FROM test.student st INNER JOIN test.score sc ON st.sno = sc.sno </select>
注意到相比 association 多了一個屬性ofType,是用來表示 List 集合中的類型的。其他屬性的用法同 association 是一樣的。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。