日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入学习Mybatis框架(二)- 进阶

發布時間:2023/12/2 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入学习Mybatis框架(二)- 进阶 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.動態SQL

1.1 什么是動態SQL?

  動態SQL就是通過傳入的參數不一樣,可以組成不同結構的SQL語句。 這種可以根據參數的條件而改變SQL結構的SQL語句,我們稱為動態SQL語句。使用動態SQL可以提高代碼重用性。

1.2 XML方式的實現

  1.2.1 需要使用到的標簽

<if> 用于判斷,類似java的if(){}
<foreach>一般用戶批量處理的SQL語句,類似java的foreach循環,
<trim> :切割標簽,主要用于切割關鍵字的頭和尾的字符.新版的Mybatis使用的幾率很少.
<set>:使用 set標簽就是SQL語言的set關鍵字,可以在update 的時候set 關鍵字后面的,逗號可以自動忽略
<where>:使用where標簽作為SQL語言的where關鍵字,好處如果where后面的條件都不成立,忽略where關鍵字.
<choose> <when> <otherwise> : java的swithc case
<sql> 用于聲明公有的SQL語句塊.,在操作標簽中使用<include>調用 [一般不建議用]

不建議的原因,會導致代碼難以維護。

  1.2.2 使用示例

  條件查詢:(where)

public List<User> selectByCondition(User user); <!-- 條件查詢 --><select id="selectByCondition" parameterType="com.gjs.pojo.User" resultType="com.gjs.pojo.User">select * from user<where><!-- if標簽:條件判斷標簽 --><if test="name!=null">name = #{name}<!--或者使用模糊查詢: name like concat('%',#{name},'%') --></if><if test="age != null">and age = #{age}</if></where> </select>

?

  修改:(set)

public int updateByNotNull(User user); <update id="updateByNotNull" parameterType="com.gjs.pojo.User">update user <!-- set --><set><if test="name != null">name=#{name},</if><if test="password != null">password=#{password},</if><if test="age != null">age=#{age}</if></set>where id=#{id} </update>

?

  根據條件統計個數(trim )

public Long selectTotalByCondition(User user); <!-- 動態SQL語句trim標簽 perfix : 動態sql語句的前綴 (WHERE,SET)prefixOverrides : 自動截取掉或者替換條(WHERE 多余后面 關鍵字 :AND-OR)--><select id="selectTotalByCondition" parameterType="com.gjs.pojo.User" resultType="long" >select count(*) from user<trim prefix="WHERE" prefixOverrides="AND|OR"><if test="name!=null">name like concat('%',#{name},'%')</if><if test="age != null">and age = #{age}</if></trim></select><!-- set操作: <trim prefix="SET" suffixOverrides=","> -->

?

  批量刪除:(foreach)

public int deleteByIds(@Param("ids")List<Integer> ids); <delete id="deleteByIds" parameterType="Integer">delete from user where id in<!-- 動態sql語句 foreach 循環標簽 <foreach collection="" open="" close="" item="" separator=""></foreach>collection : 要循環集合或者數組 open :開始位置符號 前小括號 (close : 開始位置符號 后小括號 )item : 每次循環的數據separator : 分隔符 逗號 ,--><foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></delete>

<sql>的使用:

<sql id="condition_sql"><where><if test="name !=null"><!-- name like '%${name}%' -->name like concat('%',#{name},'%')</if><if test="age !=null">and age = #{age}</if> </where></sql><select id="selectByCondition" parameterType="com.gjs.pojo.User" resultType="com.gjs.pojo.User">select * from user<!-- 引入sql片段. refid :被引入sql片段的id --><include refid="condition_sql_by_trim"/</select>

?

1.3 注解方式實現

動態sql除了支持xml方式以外,還是支持使用純注解的方式
主要一下四個注解+對應動態sql語句的類文件

1.@SelectProvider 動態查詢SQL語句對應注解
2.@InsertProvider 動態插入SQL語句對應注解
3.@UpdateProvider 動態修改SQL語句對應注解
4.@DeleteProvider 動態刪除SQL語句對應注解

  

示例:
Usermapper

package com.gjs.mapper;import java.util.List;import org.apache.ibatis.annotations.DeleteProvider; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.annotations.UpdateProvider;import com.gjs.pojo.User; import com.gjs.pojo.UserProvider;public interface UserMapper {/** 條件查詢* type : 編寫動態sql語句的類對應的字節碼* method : 編寫動態sql語句類對應的方法名稱* 此方法返回的是一個String字符串,字符串就是用于注解方法查詢的sql語句*/@SelectProvider(type= UserProvider.class,method="selectByCondition")public List<User> selectByCondition(User user);//根據條件統計總數@SelectProvider(type= UserProvider.class,method="selectTotalByCondition")public Long selectTotalByCondition(User user);//修改@UpdateProvider(type= UserProvider.class,method="updateByNotNull")public int updateByNotNull(User user);//批量刪除@DeleteProvider(type=UserProvider.class,method="deleteByIds")public int deleteByIds(@Param("ids")List<Integer> ids); }

  UserProvider
  構建方法參數規則:
    1.非數組、集合的參數,調用方法是什么,構建SQL語句的方法就是什么
    2.是數組、集合的參數,構建的方法需要包一層Map。如:調用方法為:String[] ids ,構建方法格式為Map<String,String[]> ids

package com.gjs.pojo;import java.util.List;import org.apache.ibatis.annotations.Param;public class UserProvider {public String selectByCondition(User user) {StringBuilder sb = new StringBuilder();sb.append("select * from user where 1=1 ");if(user.getName()!=null) {//由于最后字符串還是返回給Mybatis執行的所有這里需要使用OGNL表達式來獲取對象屬性的值sb.append("and name like concat('%',#{name},'%') ");}if(user.getAge()!=null) {sb.append("and age = #{age}");}return sb.toString();}public String selectTotalByCondition(User user) {StringBuilder sb = new StringBuilder();sb.append("select count(1) from user where 1=1 ");if(user.getName()!=null) {sb.append("and name like concat('%',#{name},'%') ");}if(user.getAge()!=null) {sb.append("and age = #{age}");}return sb.toString();}public String updateByNotNull(User user) {StringBuilder sb = new StringBuilder();sb.append("update user set ");if(user.getName()!=null) {sb.append("name = #{name},");}if(user.getPassword()!=null) {sb.append("password = #{password},");}if(user.getAge()!=null) {sb.append("age = #{age},");}sb.deleteCharAt(sb.length()-1);//刪除末尾多余的逗號","sb.append("where id = #{id}");return sb.toString();}public String deleteByIds(@Param("ids")List<Integer> ids) {StringBuilder sb = new StringBuilder();sb.append("delete from user where id in(");for (int i = 0; i < ids.size(); i++) {sb.append("#{ids["+i+"]},");}sb.deleteCharAt(sb.length()-1);//刪除末尾多余的逗號","sb.append(")");return sb.toString();} }

2.緩存

  在Mybatis里面,所謂的緩存就是將已經查詢過的記錄放在內存的緩沖區或文件上,這樣如果再次查詢,可以通過配置的策略,命中已經查詢過的記錄.從而提高查詢的效率。
Mybatis的緩存分為一級緩存和二級緩存

  2.1 一級緩存

   所謂的一級緩存就是會話(SqlSesion對象)級別的緩存,就是同一個會話,如果已經查詢過的數據會保存一份在內存中,如果會話沒有關閉,再次調用同樣的方法查詢,不會再查詢數據庫,而是直接從緩存中取出之前查詢的數據。一級緩存默認是打開的,而且是關閉不了的。
  以下幾種情況一級緩存會被清空:
    1.關閉會話.close()
    2.進行了操作(增刪改),提交了commit();
    3.手工清除緩存clearCache()

  2.2 二級緩存

二級緩存是 SqlSessionFactory級別,在整個應用都有效,可以在多個會話有效
MyBatis本身并沒有實現二級緩存,二級緩存需要第三方緩存提供商的支持
Ehcache:
下載地址:https://github.com/mybatis/ehcache-cache/releases
學習地址:http://www.mybatis.org/ehcache-cache/

?

3.MyBatis的對象關系映射

  在實際開發中,一個業務可能涉及到多個數據表的查詢,那么多表查詢就涉及連接查詢(等值連接), 等值連接 表與表之間有一個外鍵關鍵。
  但是程序中最終獲取的表封裝的對象, 對象與對象之間是沒有外鍵關系的,對象和對象之間只有依賴關系

  對象之間關系主要是四種(什么關系應該看從哪個對象的角度)

一對一 關系
  一個人對應身份證號
一對多 關系
  一個部門對應多個員工
多對一 關系
  多個員工對應一個部門
多對多 關系
  多個學生對應多個老師,多個學生對應多個課程

  MyBatis框架支持多表查詢封裝對象之間關系:
    <collection>標簽: 一對多查詢
    <association>標簽:多對一和一對一查詢
  注:<collection>和<association>為<resultMap>的子標簽

?

3.1 多對一查詢(<association>聯合查詢標簽)(N+1)

  例:以員工為中心來查詢關聯部門(多對一關系,多個員工對應一個部門)

?

?數據庫表

員工表 CREATE TABLE `employee` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,`dept_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; 部門表 CREATE TABLE `department` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

部門類

package com.gjs.pojo;public class Department {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Department(Integer id, String name) {super();this.id = id;this.name = name;}public Department() {super();}@Overridepublic String toString() {return "Department [id=" + id + ", name=" + name + "]";}}

員工類(Employee)

package com.gjs.pojo;public class Employee {private Integer id;private String name;//以員工為中心來關聯部門,多對一關系,多個員工對應一個部門 : many2oneprivate Department dept;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Department getDept() {return dept;}public void setDept(Department dept) {this.dept = dept;}@Overridepublic String toString() {return "Employee [id=" + id + ", name=" + name + ", dept=" + dept + "]";} }

接口

package com.gjs.mapper;import com.gjs.pojo.Employee;public interface Many2OneMapper {/*** 根據與員工的編碼查詢出員工對應的所有信息(包含部門)* @param id* @return*/public Employee selectByEmpId(Integer id); }

?接口映射配置文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 配置映射 namespace : 命名空間(通俗說法: 給當前映射文件的唯一標識:起一個唯一的名字) --> <mapper namespace="com.gjs.mapper.Many2OneMapper"><!-- 由于查詢出來的結果于com.gjs.pojo.Employee中的屬性不一致(Department dept),所以不能自動映射 --><select id="selectByEmpId" resultMap="emp_map" parameterType="int">select * from employee where id = #{id}</select><resultMap type="com.gjs.pojo.Employee" id="emp_map"><id property="id" column="id"/><result property="name" column="name"/><!-- 問題:private Department dept; 對象如何映射?解決方案: 使用聯合查詢標簽<association property="" column="" select=""></association>property : 需要映射額屬性 deptcolumn : 已知的部門外檢列 dept_idselect : 調用查詢通過部門id查詢出對應部門對象的功能的id值規則 : 映射文件的命名空間 + 點兒(.) + 功能id如果是在同一個命名空間,可以省略命名空間和點--><association property="dept" column="dept_id" select="selectByDeptId"/></resultMap><select id="selectByDeptId" parameterType="int" resultType="com.gjs.pojo.Department">select * from department where id = #{id}</select> </mapper>

?

3.2 多對一查詢(<collection>集合映射標簽)(N+1)

例:以部門為中心查詢部門的所有信息(包括員工),一個部門對應多個員工
部門類

package com.gjs.pojo;import java.util.List;public class Department {private Integer id;private String name;//以部門為中心查詢部門的所有信息(包含員工)//一個部門有多個員工 一對多關系:one2many// 部門的元員工使用 list集合包裝private List<Employee> emps;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Employee> getEmps() {return emps;}public void setEmps(List<Employee> emps) {this.emps = emps;}public Department(Integer id, String name) {super();this.id = id;this.name = name;}public Department() {super();}@Overridepublic String toString() {return "Department [id=" + id + ", name=" + name + ", emps=" + emps + "]";}}

員工類

package com.gjs.pojo;public class Employee {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Employee [id=" + id + ", name=" + name + "]";}}

接口

package com.gjs.mapper;import com.gjs.pojo.Department;public interface One2ManyMapper {/*** 根據與部門的編碼查詢出部門對應的所有信息(包含所有員工)* @param id* @return*/public Department selectByDeptId(Integer id); }

接口對應的映射配置文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 配置映射 namespace : 命名空間(通俗說法: 給當前映射文件的唯一標識:起一個唯一的名字) --> <mapper namespace="com.gjs.mapper.One2ManyMapper"><select id="selectByDeptId" parameterType="int" resultMap="dept_map">select * from department where id = #{id}</select><resultMap type="com.gjs.pojo.Department" id="dept_map"><id property="id" column="id"/><result property="name" column="name"/><!-- 問題 :List<Employee> emps; 集合如何映射?解決方案: 使用 <collection>集合映射<collection property="" column="" select=""/>property :需要映射的屬性 emps 對應的list集合column : 部門本身的主鍵 idselect : 關聯查詢的功能id規則 : 命名空間+點+功能id。 如果同一個命名空間下面直接 功能id即可--><collection property="emps" column="id" select="selectEmpsByDeptId"/></resultMap><select id="selectEmpsByDeptId" resultType="com.gjs.pojo.Employee" parameterType="int">select * from employee where id = #{dept_id}</select> </mapper>

3.3 等值連接方式查詢

  以上都是用N+1的方式。MyBatis的對象關系映射還有一種等值連接方式。
  以一對多為例:


pojo類和接口皆與3.2的相同

映射配置文件:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 配置映射 namespace : 命名空間(通俗說法: 給當前映射文件的唯一標識:起一個唯一的名字) --> <mapper namespace="com.gjs.mapper.One2ManyMapper"><select id="selectByDeptId" parameterType="int" resultMap="dept_map">select e.id e_id ,e.name e_name,d.id d_id,d.name d_namefrom department d JOIN employee e ON d.id = e.dept_id WHERE d.id = #{id};</select><resultMap type="com.gjs.pojo.Department" id="dept_map"><id property="id" column="d_id"/><result property="name" column="d_name"/><!--<collection property="emps" ofType="">在標簽內部屬性進行手動映射</collection>property : 要映射的屬性ofType: 要映射集合泛型的類型 --><collection property="emps" ofType="com.gjs.pojo.Employee"><id property="id" column="e_id"/><result property="name" column="e_name"/></collection></resultMap> </mapper>

4.MyBatis的逆向工程

  MyBatis的逆向工程能自動幫開發者生成數據庫表對應的 pojo實體文件,自動生成映射文件
  自定生成表的各種(CRUD)的sql語句, 但是只能做單表操作,聯合查詢還得開發者自己編寫

  4.1逆向工程的插件安裝步驟

    使用逆向工程得先在Eclipse安裝逆向工程的插件

  ?

  

  

?

  ?

  判斷是否安裝成功

  

  4.2 逆向工程創建步驟

    4.2.1.新建一個項目,導入mybatis.jar包和數據庫驅動包

    4.2.2 創建生成配置文件

  generatorConfig.xml:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration><context id="context1"><!-- 注釋構建 --><commentGenerator><!-- 去掉所有的注釋 --><property name="suppressAllComments" value="true"/><property name="suppressDate" value="true"/></commentGenerator><!-- 數據庫四要素 --><jdbcConnection connectionURL="jdbc:mysql://localhost:3306/mybatis" driverClass="com.mysql.jdbc.Driver" userId="root" password="1234"/><!-- 實體類 : pojotargetPackage : 實體類生成后存放的包targetProject : 存放的目錄一般都放在 src下面--><javaModelGenerator targetPackage="com.gjs.pojo" targetProject="mybatis-generator/src" /><!-- 映射文件 --><sqlMapGenerator targetPackage="com.gjs.mapper" targetProject="mybatis-generator/src" /><!-- 操作接口 type 生成映射的形式ANNOTATEDMAPPER : 純注解的,沒有xml映射XMLMAPPER : 生成的有xml映射文件--><javaClientGenerator targetPackage="com.gjs.mapper" targetProject="mybatis-generator/src" type="XMLMAPPER" /><!-- 要生成對應表的配置tableName : 數據庫表名//如果下面全部是true,mybatis直接可以使用純面向對象開發 enableCountByExample : 是否生成查詢總數的 Example enableDeleteByExample : 是否生成刪除的 Example enableSelectByExample : 是否生成查詢集合的 Example enableUpdateByExample : 是否生成修改的 Example --><table tableName="user" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="true" enableUpdateByExample="false"></table><table tableName="employee" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="true" enableUpdateByExample="false"></table><table tableName="department" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="true" enableUpdateByExample="false"></table></context> </generatorConfiguration>

主要是數據庫四要素、實體類、映射文件、操作接口的配置視情況進行修改

    4.2.3 開始逆向工程

  選中generatorConfig.xml文件右擊運行

  

  4.3.逆向功能的缺點

  逆向功能不能逆向多表操作,只能逆向單表操作,多表之間有外鍵對應java關聯關系沒辦法映射,需要開發者手動編寫對應代碼。

轉載于:https://www.cnblogs.com/gaojinshun/p/11145826.html

總結

以上是生活随笔為你收集整理的深入学习Mybatis框架(二)- 进阶的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。