SqlMapConfig.xml
1、配置內容
-properties(屬性)
????--property
-settings(全局配置參數)
????--setting
-typeAliases(類型別名)
????--typeAliase
????--package
-typeHandlers(類型處理器)
-objectFactory(對象工廠)
-plugins(插件)
-environments(環境集合屬性對象)
????--environment(環境子屬性對象)
????????---transactionManager(事務管理)
????????---dataSource(數據源)
-mappers(映射器)
????--mapper
????--package
2、properties屬性
1、第一種方式:配置properties屬性內容
<properties>
? ? <property name="driver" value="com.mysql.jdbc.Driver"/>
? ? <property name="url" value="jdbc:mysql://localhost:3306/db1"/>
? ? <property name="username" value="root"/>
? ? <property name="password" value="root"/>
</properties>
在dataSource(數據源)中使用時,可以在value字段直接使用別名進行引用:${driver}
2、第二種方式:引用配置文件
1)方式1:通過resource 屬性,指定 properties 配置文件的位置,要求配置文件必須在類路徑下(resources目錄)
<properties resource="jdbcConfig.properties">
</properties>
2)方式2:通過url 屬性
URL: Uniform Resource Locator 統一資源定位符
如:http://localhost:8080/web/myServlet?
?URL協議 主機? ? ? ? 端口 URI
URI:Uniform Resource Identifier 統一資源標識符 即:web/myServlet 部分,可以在 web 應用中唯一定位一個資源的路徑
示例:
<properties url="file:///C:/Users/Q/resources/jdbcConfig.properties"></properties>
mapper中的url也是這種定義方式
3、settings(全局配置參數)
1、延遲加載配置
? ? 1)lazyLoadingEnabled:延遲加載的全局開關。當開啟時,所有關聯對象都會延遲加載。 特定關聯關系中可通過設置?fetchType?屬性來覆蓋該項的開關狀態,默認false
? ? 2)aggressiveLazyLoading:開啟時,任一方法的調用都會加載該對象的所有延遲加載屬性,?否則,每個延遲加載屬性會按需加載,?3.4.1 版本后默認關閉(false)
2、二級緩存配置
cacheEnabled:全局性地開啟或關閉所有映射器配置文件中已配置的任何緩存,默認true
4、typeAliases(類型別名)
配置別名,只能配置domain中類的別名
當指定了別名就不再區分大小寫,在映射文件中即可使用別名
標簽:typeAlias?
<typeAliases>
? ? <typeAlias type="q.perter.domain.User" alias="user"></typeAlias>
</typeAliases>
type:用于指定實體類的全限定類名
alias:屬性指定別名
標簽:package?
<typeAliases>
????<package name="q.perter.domain"/>
</typeAliases>
name:指定要配置別名的包
當指定包之后,該包下的實體類都會注冊別名,并且類名就是別名,不再區分大小寫
5、typeHandlers(類型處理器)
6、objectFactory(對象工廠)
7、plugins(插件)
8、environments(環境集合屬性對象)
示例
<!-- 配置環境 -->
<environments default="mysql">
? ? <!-- 配置mysql的環境-->
? ? <environment id="mysql">
? ? ? ? <!-- 配置事務的類型-->
? ? ? ? <transactionManager type="JDBC"></transactionManager>
? ? ? ? <!-- 配置數據源(連接池) -->
? ? ? ? <dataSource type="POOLED">
? ? ? ? ? ? <!-- 配置連接數據庫的4個基本信息 -->
? ? ? ? ? ? <property name="driver" value="com.mysql.jdbc.Driver"/>
? ? ? ? ? ? <property name="url" value="jdbc:mysql://localhost:3306/db1"/>
? ? ? ? ? ? <property name="username" value="root"/>
? ? ? ? ? ? <property name="password" value="root"/>
? ? ? ? </dataSource>
? ? </environment>
</environments>
屬性分析
MyBatis 在初始化時,根據<dataSource>的 type 屬性來創建相應類型的的數據源 DataSource,即:
1)type=”POOLED”:MyBatis 會創建 PooledDataSource 實例,采用傳統的javax.sql.DataSource規范中的連接池,mybatis中有針對規范的實現
2)type=”UNPOOLED” : MyBatis 會創建 UnpooledDataSource 實例,采用傳統的獲取連接的方式,雖然也實現Javax.sql.DataSource接口,但是并沒有使用池的思想
3)type=”JNDI”:MyBatis 會從 JNDI 服務上查找 DataSource 實例,然后返回使用
采用服務器提供的JNDI技術實現,來獲取DataSource對象,不同的服務器所能拿到DataSource是不一樣
注意:如果不是web或者maven的war工程,是不能使用的,我們使用的tomcat服務器,采用連接池就是dbcp連接池
原理
連接池說明:
1)連接池是存儲連接的一個容器
2)容器其實是一個集合對象,該集合必須是線程安全的,不能兩個線程拿到同一個連接
3)該集合必須實現隊列的特性:先進先出
這里只考慮Mybatis中的POOLED類型的數據庫連接池
1)空閑池:如果空閑池中還有連接,直接獲取連接來使用
2)活動池:如果空閑池中沒有連接,則到活動池中是否已經達到最大數量
? ? a)沒有達到最大數量:創建一個新的連接返回
? ? b)達到最大數量:查找最先進來的一個活動連接,調整后將一個新的連接返回
9、mappers(映射器)
配置映射文件位置
標簽:mapper
方式1:通過配置文件方式
<mappers>
? ? <mapper resource="q/perter/dao/IUserDao.xml"></mapper>
</mappers>
指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件
方式2:通過注解的方式
<mappers>
? ? <mapper class="q.perter.dao.IUserDao"></mapper>
</mappers>
如果是用注解來配置的話,此處應該使用class屬性指定被注解的dao全限定類名
方式3:通過url的方式
<mappers>
? ? <mapper url="file:///C:/Users/Q/IUserDao.xml"></mapper>
</mappers>
通過url方式,參照properties標簽中的url
標簽:package
<mappers>
? ? <package name="q.perter.dao"/>
</mappers>
package標簽用于指定dao接口所在的包,當指定了包之后就不需要再寫mapper
映射文件解析
1、mapper
namespace標簽:dao接口的全限定類名
2、select
select語句對應的標簽
屬性:
1)id:當前dao下的唯一標識,和dao接口中的方法名一致
2)parameterType:查詢語句對應的參數
3)resultType:定義查詢結果的返回值類型
4)resultMap:定義查詢結果的返回值封裝類型
3、insert
insert語句對應標簽
<insert id="saveUser" parameterType="user">
? ? ? ? <!-- 配置插入操作后,獲取插入數據的id -->
? ? ? ? <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
? ? ? ? ? ? select last_insert_id();
? ? ? ? </selectKey>
? ? ? ? insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
</insert>
selectKey標簽:作用是在insert語句執行后,查詢剛剛插入數據的id,將id賦值給類中的主鍵,一般用于獲取新增對象的主鍵
? ? 1)keyProperty:實體類中定義的主鍵字段
? ? 2)keyColumn:數據庫中定義的主鍵字段
? ? 3)resultType:返回值類型,主鍵的數據類型
? ? 4)order:執行順序在insert語句執行前/后
4、update
update語句對應標簽
5、delete
delete語句對應標簽
6、sql
自定義Sql語句,簡化Sql片段
<sql id="defaultSql">
? ? select * from user
</sql>
<select id="findOne" resultType="q.perter.domain.User">
? ? <include refid="defaultSql"></include> where id = #{id}
</select>
7、resultMap
1、格式
<!-- 配置查詢結果的列名和實體類屬性名的對應關系 -->
<resultMap id="userMap" type="q.perter.domain.User">
? ? <!-- 主鍵字段對應 -->
? ? <id property="userId" column="id"></id>
? ? <!-- 非主鍵字段對應 -->
? ? <result property="userName" column="username"></result>
? ? <result property="userSex" column="sex"></result>
? ? <result property="userBirthday" column="birthday"></result>
? ? <result property="userAddress" column="address"></result>
</resultMap>
2、使用
在返回查詢結果時,不再使用resultType定義的全限定類名,而是使用resultMap屬性,如:
<select id="findAll" resultMap="userMap">
? ? select * from user
</select>
3、其他標簽
一對一標簽?association
1)association:一對一定義時使用association標簽
2)property:代表實體類中字段名字(區分大小寫),這里user
3)javaType:是指封裝對象的全限定類名,因為已經使用別名,可以直接用user
一對多標簽 collection
1)collection:一對多定義時使用collection標簽
2)property:代表實體類中字段名字(區分大小寫),這里roles
3)ofType:是指封裝對象的全限定類名,因為已經使用別名,可以直接用role
8、動態Sql標簽
1、<if>標簽
根據不同條件,使用不同的SQL語句進行查詢,如:
<select id="findUserByCondition" resultType="user" parameterType="user">
? ? select * from user where 1 = 1
? ? <if test="username != null and username != ''">
? ? ? ? and username = #{username}
? ? </if>
</select>
注意:
1)<if>標簽的 test 屬性中寫的是對象的屬性名,如果是包裝類的對象要使用 OGNL 表達式的寫法
2)<if>標簽的 test 屬性中對多個條件進行判斷,應該是用 and 進行連接
2、<where>標簽
類似sql語句中的where,可以簡化上面的語句
<select id="findUserByCondition" resultType="user" parameterType="user">
? ? select * from user
? ? <where>
? ? ? ? <if test="username != null and username != ''">
? ? ? ? ? ? and username = #{username}
? ? ? ? </if>
? ? </where>
</select>
3、<foreach>標簽
<foreach>標簽用于遍歷集合,它的屬性:
? ? collection:代表要遍歷的集合元素,注意編寫時不要寫#{}
? ? open:代表語句的開始部分
? ? close:代表結束部分
? ? item:代表遍歷集合的每個元素,生成的變量名
? ? sperator:代表分隔符
<select id="findByIds" parameterType="queryVo" resultType="user">
? ? select * from user
? ? <where>
? ? ? ? <if test="ids != null and ids.size() > 0">
? ? ? ? ? ? <foreach collection="ids" open=" id in (" close=")" item="uid" separator=",">
? ? ? ? ? ? ? ? #{uid}
? ? ? ? ? ? </foreach>
? ? ? ? </if>
? ? </where>
</select>
注意:foreach中的#{uid}必須和屬性item中的字段uid保持一致
9、其他
1、Mybatis的參數
參數parameterType輸入類型,有以下幾種類型:
1)簡單數據類型:如String、Integer等,不區分大小寫
2)傳遞pojo對象:就是我們常用的javabean(實體類對象),Mybatis使用ognl表達式解析對象的值,#{}或${}括號中的值為pojo屬性名稱
? ? ognl表達式:Object Graphic Navigation Language 對象 圖 導航 語言
? ? 通過對象的取值方法來獲取數據,在寫法上省略get
? ? 如獲取用戶名稱,在類中:user.getUserName();,在ognl表達式中:user.username
? ? 在parameterType中已經指定屬性所屬的類,所以在使用時不需要寫對象名,如:#{username}
3)傳遞pojo包裝對象:開發中通過 pojo 傳遞查詢條件 ,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其它的查詢條件,這時可以使用包裝對象傳遞輸入參數,即:Pojo 類中包含 pojo。
注意:在使用包裝對象時,參數parameterType類型為QueryVo,其中包含User對象屬性,User對象包含username屬性,使用格式為:#{user.username}
2、Mybatis的輸出結果封裝
輸出結果類型包括:
1)簡單數據類型,如:Integer
2)Pojo對象:如實體對象(查詢一個)
3)Pojo列表:如實體列表(查詢所有)
4)resultMap結果類型:詳見resultMap部分描述
要求:數據庫字段名與實體類字段名一致,如果不一致可以通過以下兩種方式解決:
1)查詢語句中將返回數據結果起別名(執行效率更快,但是每條語句都要修改)
2)使用resultMap來進行匹配(開發效率變快,但是要解析xml)
3、二級緩存
1)<cache></cache>:讓當前配置文件支持二級緩存
2)<select id="findOne" resultType="user" parameterType="Integer" useCache="true">:讓當前的操作支持二級緩存