mybatis從頭學到jio(一)
@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注入的問題
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中別名可以不關注大小寫。
<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標簽作用取出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語句后綴字符 |
<select id="findStudent1" resultType="com.bean.student">select * from student<where>Sname = #{name} </where>
</select>
省去了多余的1 = 1的條件
<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、數組等等
模糊匹配一共有三種方式
<select id="studentByName" resultType="com.conn.student">select *from student where Sname like #{name}
</select>
<select id="studentByName" parameterType="java.lang.String" resultType="com.conn.student">select *from student where Sname like concat('%',concat(#{name},'%'))
</select>
<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 | 實現一對多結果集封裝 |
public interface StudentMapper2 {@Select("select * from Student")public Student getStudentBySID();
}
@update("update student set Sname=#{name} where SID=#{SID}")
public void updateStudent(@Param("name") String Sname,@Param("SID") int SID)
@Insert("insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{name},#{Sage},#{Ssex})")public int insertStudent(Student student);
@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的學習如果有錯誤的地方歡迎大佬指正
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态