Mybatis學習筆記

SqlSessionFactoryBuilder ->SqlSessionFactory->SqlSession->SQL Mapper

SqlSessionFactoryBuilder :根據配置生成SqlSessionFactory , 構建完所有SqlSessionFactory

SqlSessionFactory:依靠工廠生成SqlSession ,單例,整個生命週期

SqlSession:可以發送SQL執行並返回結果,也可以獲取Mapper接口 及時關閉

SQL Mapper:java interface+XML 給出sql映射規則,發送SQL執行並返回結果 一個SqlSession事務方法中使用,然後廢棄

SqlMapConfig.xml 全局配置文件

properties(屬性)

settings(全局配置參數)
typeAliases(類型別名)
typeHandlers(類型處理器)
objectFactory(對象工廠)
plugins(插件)
environments(環境集合屬性對象)
–environment(環境子屬性對象)
----transactionManager(事務管理)
----dataSource(數據源)
----mappers(映射器)


db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

/*

其中 properties 配置分爲 1.xml中 2.db.properties 3.程序參數 ,優先級由低到高。

*/

相應的SqlMapConfig.xml

​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​

typeAliases 不區分大小寫

<typeAliases>
​	<!-- 單個別名定義 -->
​	<typeAlias alias="user" type="com.pojo.User"/>
​	<!-- 批量別名定義,掃描整個包下的類,別名爲類名(首字母大小寫都可以) -->
​	<package name="com.pojo"/>  //配合 @Alias("user")  爲空則 首字母變小寫 如:UserType  -> userType
</typeAliases>

typeHandlers 負責javatype與數據庫類型轉換 ,可自定義,如枚舉類型轉化,性別 0 men 1 weman

environments 數據源配置

<environments default="1">

​	<environment id="1">

​		<transactionManager type="JDBC">

​			<property  name="autoCommit" value="false"/>			

​		</transactionManager>

​		<dataSource type="POLLED">   //POLLED  UNPOLLED  JNDI  也可自定義  type="   替換即可  "

​			</property>   // name pwd....

​		</dataSource>

​	</environment>

​	<environment id="2">

​	</environment>

</environments>

select詳解

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="對應DAO接口">
<select id="對應DAO接口方法名" parameterType=“Integer” resultType="org.chench.test.mybatis.model.Test">
select * from test where id = #{id}
</select>
</mapper>
/*                          可以開啓駝峯命名自動映射 mapUnderscoreToCamelCase=true
namespace="對應DAO接口"
id="對應DAO接口方法名"
parameterType 類全名、別名,方法參數類型
resultType 查詢返回值類型
resultMap  定義數據庫表字段與POJO一一對應

*/
傳遞多個參數
<select id="對應DAO接口方法名" parameterType="map"  resultMap="xxx">
select * from test where id = #{id}
</select>


public List<Role> getList(Map<String,String> params);
其中  params.put("name","xxx");
​    params.put("sex","xxx");
<select id="對應DAO接口方法名" parameterType=“map” resultMap="xxx">
select * from test where name = #{name} and sex=#{sex} 
</select>


public List<Role> getList(@Param("userName")String username);
<select id="對應DAO接口方法名"  resultMap="xxx">
select * from test where name = #{userName} 
</select>
 //userName ...與Role屬性一致
public List<Role> getList(Role role);
<select id="對應DAO接口方法名" parameterType="org.chench.test.mybatis.model.Role" resultMap="xxx">
select * from test where name = #{userName} and sex=#{sex} 
</select> 
​    
<resultMap id="唯一" type="對應pojo全限定名">
​    <id property="id" column="id"></id>
​    <result property="userName" column="user_name"></result>
</resultMap>
id:標識主鍵

插入值,並返回插入的主鍵值 給 傳入的對象的對應屬性 表設計應該設置爲自增

​ ​ insert into t_tole(name,sex) values(#{roleName},#{sex})

​ int insertRole(Role role);
​ ​
​ Role r = new Role();
​ ​ r.setName();
​ ​ r.setSex();
​ myDao.insertRole®;
​ sout(r.getId()); //獲取插入的記錄的 主鍵id值

當然可以 自定義規則, 如當前表爲空則置爲1 ,否則當前基礎上+2 此時數據庫表的自增 關閉


​ ​
​ ​ select if(max(id) is null,1,max(id)+2) as newId from t_role
​ ​
​ ​ insert into t_tole(id,name,sex) values(#{id},#{roleName},#{sex})

定義參數屬性不允許換行

sql元素

<sql id  = "role_columns">
id,sex,phone
</sql>

<select parameterType="long" id = "getRole" resultMap="roleMap">
	select <include refid="role_columns"/> from role where id = #{id}
</select>


<sql id  = "role_columns">
	#{prefix}.id,#{prefix}.sex,#{prefix}.phone
</sql>

<select parameterType="string" id = "getRole" resultMap="roleMap">
	select 
	<include refid="role_columns">
		<property name="prefix" value="r"></property>
	</include>
	from role where id = #{id}
</select>


<sql id  = "some_include">
​	select * from <include  refid="${tableName}" />
</sql>

resultMap 作用 :定義映射規則、級聯更新、定製類型轉換器等

<resultMap>   //id="唯一" type="對應pojo全限定名"
	<constructor>   //配置構造方法     有的javabean不存在無參數構造器
		<idArg>   //注入同時  爲主鍵
		</idArg>
		<arg>
		</arg>
	</constructor>
	
	<id/>       //表明爲主鍵  <id property="id" column="id"></id>
	
	<result/>   //定義映射規則 property="javabean屬性" column="sql列名"  javaType 
	           // jdbcType    typeHandler自定義規則
	
	<association/>  //支持級聯的一部分 一對一、一對多、多對多  解決一對一
                    //property="javabean屬性"   column="傳給dao方法的參數"  select="指向一個dao方法"
                    //這個屬性在在 ProvienceDao中
                    //如:省份表 id 名字      別名表 id 別名   AliasDao  findById(Integer id)   
                    //javabean  id  名字  別名
                    //  property="別名"  column ="id"  select="com.qmylzx.base.dao.AliasDao"
                    //select*from provience where id = #{id}   select*from alias where id = #{id}
	<connection/>  //支持級聯的一部分 一對一、一對多、多對多  解決一對多
                 // property="cities" column="id" select="base.dao.findCityByPid"/>

	<discriminator> //鑑別器級聯 解決多對多
		<case/>
	</discriminator>
</resultMap>

public class Province {
​ private Long id;
​ private String name;
​ private Alias alias;
​ private List cities; //城市表中有一個pid字段,該字段表示這個城市是屬於哪個省份的
​ //省略getter/setter
}

public interface CityMapper {
List findCityByPid(Long id);
}

discriminator 定義多個resultMap extends 標記type的javabean繼承的父類

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.ProvinceMapper">
	<resultMap id="provinceResultMapper" type="org.sang.bean.Province">
		<id column="id" property="id"/>
		<discriminator javaType="int" column="area">  // javaType   column 以這個作爲區分
			<case value="1" resultMap="noodleResultMap"></case>
			<case value="2" resultMap="riceResultMap"></case>
		</discriminator>
	</resultMap>
	<resultMap id="noodleResultMap" type="org.sang.bean.Province" extends="provinceResultMapper">
		<collection property="foods" column="area" select="org.sang.db.NoodleMapper.findNoodleByArea"/>
	</resultMap>
	<resultMap id="riceResultMap" type="org.sang.bean.Province" extends="provinceResultMapper">
		<collection property="foods" column="area" select="org.sang.db.RiceMapper.findRiceByArea"/>
	</resultMap>
	<select id="getProvince" resultMap="provinceResultMapper">
	  SELECT * FROM province
	</select>

</mapper>

PS: 使用級聯 超過三層 複雜度上升、查詢到無用數據,造成性能下降, 爲了解決這個問題考慮延遲加載

全局延遲加載:setting中設置 lazyLoadingEnable = true aggressiveLazyLoading=ture

//僅開啓延遲加載還是會加載所有信息 , 開啓層級加載(aggressiveLazyLoading)後纔會只加載一部分,即使用的部分

局部延遲加載association 、connection 屬性fetchType eager、lazy

使用map存儲結果集 :一般而言,任何select語句都可用map

<select id = "findColorByNote" parameterType="string" resultType="map">
	select id color note from t_color where note like  concat('%',#{note},'%')
</select>

使用POJO

緩存

系統緩存(一級緩存、二級緩存):默認開啓一級緩存,即同一個SQLSession查詢後,若未聲明需要刷新或無緩存超時,則再次查詢,只會從緩存中獲取數據,而不會再次發送sql到數據庫(相同的mapper、參數和方法)

往往我們需要開啓二級緩存,使得在SQLSessionFactory層面上能夠提供給各個SQLSession對象共享,

開啓二級緩存:POJO需要可序列化(implements Serializable)、並在映射xml文件配置

PS:select語句會緩存、insert、update、delete會刷新緩存,系統使用默認的LRU算法來回收

根據時間表,如NO Flush Interval(無刷新間隔),緩存不會以任何時間順序來刷新

緩存會存儲列表集合或對象的1024個引用

緩存是可讀可寫的,即對象檢索不共享,而且可以安全的被調用者修改

cache 的屬性

eviction=“LRU” //回收策略 LRU、FIFO、SOFT軟引用(基於GC)、WEAK(這裏也是LRU,更積極基於GC)

flushInterva=" " //不配置默認sql執行才刷新緩存

size //引用數目,不適合太大,容易OOM

readOnly //默認爲false

type=“com.qmylzx.MyCache” //自定義緩存,如使用redis 只需要實現mybatis 提供的接口類

//以下,在MyCache中若有setHost(String host) 方法,則在初始化的時候會調用

動態SQL

if //單條件分支判定

select id,name,note from t_role where 1=1 and name like concat('%',#{roleName},'%')

choose(when、otherwise) //多條件

select id,name,note from t_role where 1=1 and id=#{roleId} and note is not null

trim(where、set) // 用於處理一些sql拼裝問題

   where
<select id="findRoles" parameterType="string"  resultMap="xxx">
    select id,name,note from t_role 
    <where>   //以上 if  choose where 1=1 沒有會報錯,這裏可以用 where標籤
        <if test="roleName!=null and roleName!=''">
                and name like concat('%',#{roleName},'%') 
        </if>
    </where>
</select>

   trim   去掉一些特殊字符串  prefixOverrides代表要去掉的字符串 prefix代表前綴
<select id="findRoles" parameterType="string"  resultMap="xxx">
    select id,name,note from t_role 
    <trim prefix="where" prefixOverrides="and"> 
        <if test="roleName!=null and roleName!=''">
                and name like concat('%',#{roleName},'%') 
        </if>
    </trim>
</select>


            set   防止更新某列導致的全部字段都要發送一次  ,節省帶寬
<update>
 update role 
    <set>
       <if test="roleName!=null and roleName!=''">
                roleName=#{roleName}
        </if>
           <if test="sex!=null and sex!=''">
                sex=#{sex}
        </if>
    </set>
    where roleId=#{roleId}
</update>  
//以上set 可以替換爲   <trim prefix="set" prefixOverrides=","> 

foreach // 在in語句等列舉條件常用

select * from t_user where sex in #{sex} //其中collection爲傳入參數名稱,可以是 數組、list、set等集合 //item是循環中當前元素,index當前元素在集合的下標

bind //用於 mybatis 自己的方式 實現自定義的函數語法,而不用關心數據庫實現 mysql 的concat與oracle的 ||

<select id="findRoles" parameterType="string"  resultMap="xxx">
<bind name="pattern_roleName" value="'%'+roleName+'%'"></bind>
<bind name="pattern_note" value="'%'+note+'%'"></bind>
    select id,name,note from t_role 
    where name like #{pattern_roleName}
and note like #{pattern_note}
</select>
public List<Role> findRole(@Param("roleName")String roleName ,@Param("note")String note);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章