Mybatis框架,mybatis從頭學到jio(二)

 2023-10-05 阅读 28 评论 0

摘要:前情回顧 mybatis從頭學到jio(一) 這里寫目錄標題前情回顧${} 與 #{}區別#{}${}typeAliases標簽動態SQLif標簽trim標簽where標簽foreach標簽模糊匹配直接傳入%s%使用concat方法使用bind標簽緩存機制一級緩存二級緩存高級映射一對一一對多延時加載注解selectupda

前情回顧

mybatis從頭學到jio(一)

這里寫目錄標題

    • 前情回顧
      • ${} 與 #{}區別
        • #{}
        • ${}
      • typeAliases標簽
    • 動態SQL
      • if標簽
      • trim標簽
      • where標簽
      • foreach標簽
      • 模糊匹配
        • 直接傳入%s%
        • 使用concat方法
        • 使用bind標簽
    • 緩存機制
      • 一級緩存
      • 二級緩存
    • 高級映射
      • 一對一
      • 一對多
    • 延時加載
    • 注解
      • select
      • update
      • insert
      • delete
      • 一對一映射

${} 與 #{}區別

#{}

@Select("select * from Student where SID=#{sid}")
public Student getStudentBySID(int sid);Preparing: select * from Student where SID=? 
Parameters: 2(Integer)

Mybatis框架。#{}處理方式類似于preparedStatement參數的操作將占位符替換為 ?,使用的參數必須提供了getter,將SQL語句和參數值分開傳到服務器.
優點:不存在SQL注入的問題

${}

	@Select("select * from Student where SID=${SID}")public Student getStudentBySID(Student student);Preparing: select * from Student where SID=1 Parameters:

${}類似于jdbc中statement直接將參數拼接到SQL語句之中
缺點:存在SQL注入的問題

typeAliases標簽

Tip:typeAliases在mybatis-config.xml中配置(主配置文件)

    <!--類型別名--><typeAliases><!--單個別名定義 type:pojo類的路徑(全限定名) alias:別名的名稱--><typeAlias type="com.tulun.MybatisDemo.Student" alias="student"/><!--批量的別名定義 name:指定的包名,將包下邊的所有pojo類取別名,別名為類名(首字母大小寫都行)--><package name="com.tulun.pojo"/></typeAliases>

業務場景:極大的簡化了配置文件的編寫,當工作量比較大的時候可以配置resultType和parameterType Windows中別名可以不關注大小寫。

動態SQL

if標簽

<select id="selectStudent" resultType="com.bean.student">select * from student where 1=1<if test="Sage != 0">and Sage = #{Sage}</if>
</select>

使用log4j.properties可以看見一下結果

假如傳兩個參數 :select * from Student where 1=1 and Sage = #{Sage} and Ssex = #{Ssex}
假如傳一個參數:select * from Student where 1=1 and Sage = #{Sage}
## debug 級別
log4j.rootLogger=DEBUG,Console  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.Target=System.out  
log4j.appender.Console.layout = org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH\:mm\:ss,SSS} [%t]  [%c] [%p] - %m%n  
log4j.logger.com.mybatis=DEBUG  /  ##輸出sql 語句
log4j.logger.java.sql.Connection=DEBUG  
log4j.logger.java.sql.Statement=DEBUG  
log4j.logger.java.sql.PreparedStatement=DEBUG 

trim標簽

trim標簽作用取出SQL中多余And關鍵字,逗號,使用在where或者set

<select id="updateStudent" resultType="com.conn.student">update student<trim prefix="set" suffixOverrides=","><if test="Sage != null">Sage = #{Sage},</if><if test="name != null">Sname = #{name},</if></trim>where SID = #{SID}
</select>
屬性描述
prefix給SQL拼接前綴
suffix給SQL拼接后綴
prefixOverrids剔除SQL語句前綴字符
suffixOverrids剔除SQL語句后綴字符

where標簽

<select id="findStudent1" resultType="com.bean.student">select * from student<where>Sname = #{name}         </where>
</select>

省去了多余的1 = 1的條件

foreach標簽

<select id="findStudent1" resultType="com.bean.student">select * from student<where><if test="list != null"><foreach collection="list" separator="," close=")" open="and SID in(" item="id">#{id}</foreach></if></where>
</select>
屬性描述
collection所要遍歷集合的名稱
separator集合之中分割符
close結束的字符
open開始的字符
item集合之中的單個字符名稱

collection可以使用與List、Map、數組等等

模糊匹配

模糊匹配一共有三種方式

直接傳入%s%

<select id="studentByName" resultType="com.conn.student">select *from student where Sname like #{name}
</select>

使用concat方法

<select id="studentByName" parameterType="java.lang.String" resultType="com.conn.student">select *from student where Sname like concat('%',concat(#{name},'%'))
</select>

使用bind標簽

<select id="studentByName" resultType="com.conn.student"><bind name="s" value="'%'+name+'%'"/>select *from student where Sname like #{s}
</select>

緩存機制

一級緩存

mybatis中一級緩存是不需要任何的配置,是sqlsession級別的查詢
執行同一個SQL語句第一次查詢對應的信息,當第二次查詢的時候優先去緩存區查詢對應的結果
在這里插入圖片描述

這個圖片可以看到第一次進行了SQL查詢,第二次直接在緩存區查詢

在這里插入圖片描述
這里可以看出當對對應的數據庫字段做出改變是,緩存區立馬被清空,第二次查詢只能繼續訪問數據庫

在這里插入圖片描述
不同session執行緩存不共享

二級緩存

二級緩存是mapper級別的,默認的是關閉的需要手動的開啟
主配置文件配置

    <settings><!--開啟二級緩存的開關--><setting name="cacheEnabled" value="true"/></settings>

映射文件配置

    <!--開啟本Mapper的二級緩存--><cache></cache>

同一個mapper不同SQLSession下的查詢可以看出共享緩存
在這里插入圖片描述

高級映射

一對一

association:用于映射關聯查詢單個對象的信息

<mapper namespace="com.dao.ordersDao"><resultMap id="OrderUserResultMap" type="com.bean.orders" ><!--property:關聯查詢映射到對應的自定義的對象的屬性javaType:映射的Java屬性的全限定名columnPrefix:給數據庫字段添加前綴--><id column="id" property="id"/><result column="user_id" property="user_id"/><result column="number" property="number"/><result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/><result column="note" property="note"/><association property="user" columnPrefix="u_" javaType="com.bean.user"><!--user配置--><result column="id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/></association></resultMap><select id="findAll" resultMap="OrderUserResultMap">select o.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.user_id = u.id</select>
</mapper>

這里需要注意當SQL語句太長換行的時候在前一段末尾或下一段前面加一個空格因為在拼接字符串的時候會將兩個關鍵詞拼接在一起

使用extends關鍵詞簡化xml配置的編寫

	<resultMap id="orderResultMap" type="com.bean.orders"><!--orders配置--><id column="id" property="id"/><result column="user_id" property="user_id"/><result column="number" property="number"/><result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/><result column="note" property="note"/></resultMap><resultMap id="userResultMap" type="com.bean.user"><!--user配置--><result column="id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/></resultMap><resultMap id="OrderUserResultMap" type="com.bean.orders" extends="orderResultMap"><association property="user" columnPrefix="u_" javaType="com.bean.user" resultMap="userResultMap"></association></resultMap>

這里需要注意:當xml配置映射關系比較多的時候使用extends關鍵詞可以極大節省開發時間,也可以是代碼變得簡潔起來,通俗說哪里需要用到直接可以使用extends關鍵詞使用

一對多

使用collection可以將用戶一對多訂單映射到集合之中

	<resultMap id="userMap" type="com.bean.user" extends="userResultMap"><collection property="orders" columnPrefix="order_"  ofType="com.bean.orders" resultMap="orderResultMap"></collection></resultMap><!--這塊可以實現代碼的復用當下一次使用的時候直接可調用--><sql id="selectId">u.id,u.username,u.sex,u.address,o.id order_id,o.user_id order_user_id,o.number order_number,o.createtime order_createtime,o.note order_note</sql><select id="findStudentIds" parameterType="int" resultMap="userMap">select <include refid="selectId"/>from user u ,orders o where u.id=o.user_id and u.id=#{uid};</select>

延時加載

開啟延時加載

 <!-- 開啟延遲加載 -->
<settings><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="false"/>
</settings>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.ordersDao"><!-- 定義可以封裝帶有User的order的 resultMap --><resultMap id="orderWithUserMap" type="com.bean.orders" extends="orderResultMap"><!-- 關聯 User 對象 --><association property="user" javaType="com.bean.user" column="user_id" select="com.dao.userDao.findStudentIds"></association></resultMap><!-- 配置查詢所有訂單,延遲加載用戶信息 --><select id="findAll" resultMap="orderWithUserMap">SELECT * FROM orders</select>
</mapper>

這里需要注意select關聯查詢的已存在的方法的全路徑
association中的column是接口的參數

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.userDao"><!-- 查詢單個用戶 --><select id="findStudentIds" parameterType="java.lang.Integer" resultType="com.bean.user">SELECT * FROM user WHERE id = #{id}</select>
</mapper>
	<mappers><mapper resource="mappers/order.xml"></mapper><mapper resource="mappers/user.xml"></mapper></mappers>

這里一定需要注意在配置文件之中需要兩個映射文件都需要加載并且在同一個mappers標簽之下。我在這個錯誤浪費了好多的時間,還是自己不細心。
在這里插入圖片描述
圖中拿到user_id三天記錄兩個1一個10分成兩次去數據庫查找實現了懶加載。

注解

直接裝載在方法上面
優點:比較簡單
缺點:SQL語句的改變就需要重新編譯
注解 作用

在這里插入圖片描述

>標簽作用
@Intsert實現新增
@Update實現更新
@Delete實現刪除
@Select實現查詢
@Results實現結果集封裝
@ResultMap實現引用 @Results 定義的封裝
@One實現一對一結果集封裝
@Many實現一對多結果集封裝

select

public interface StudentMapper2 {@Select("select * from Student")public Student getStudentBySID();
}

update

@update("update student set Sname=#{name} where SID=#{SID}")
public void updateStudent(@Param("name") String Sname,@Param("SID") int SID)

insert

 @Insert("insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{name},#{Sage},#{Ssex})")public int insertStudent(Student student);

delete

    @Delete("delete form student where SID={SID}")public void deleteStudent(int SID);

一對一映射

@Results(id = "result",value = {@Result(column = "SID",property = "SID"),@Result(column = "Sname",property = "name"),@Result(column = "Sage",property = "Sage"),@Result(column = "Ssex",property = "Ssex"),@Result(column = "score",property = "SID",one = @One(select = "com.dao.studentDao.StudentScore",fetchType = FetchType.EAGER)})

需要注意的是one表示的是一對一,many表示一對多是使用,fetchtype加載類型,立即加載為EAGER

以上是我對mybatis的學習如果有錯誤的地方歡迎大佬指正

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/120685.html

发表评论:

猜你喜欢

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息