mybatis技術總結


一、框架概述

day1

1.什么是框架
框架是系統的可重用設計,是對J2EE底層技術的封裝(JDBC,IO流,多線程,Servlet,Socket)。

2.框架解決了哪些問題?
1.解決了技術整合問題
在JavaEE體系中,有着各式各樣的技術,不同的軟件企業,根據自身的業務需求選擇不同的技術,容易造成應用依賴技術,增加了項目開發 的復雜性和技術風險性。企業項目中應該將應用的設計與實現技術解耦。
2.解決提升開發效率的問題
企業項目中使用框架,程序員不再需要重復造輪子,只需要專注實現業務需求,使用框架的方便性,提高開發效率
3.解決了穩定性的問題
一個成熟的框架,經過了眾多企業項目的驗證使用,穩定性有保證
3.J2EE項目的分層:
web層(表現層)-業務層(service)-持久層(dao)

 

二、總結jdbc開發的問題

1.jdbc開發步驟:
加載驅動
創建數據庫連接對象
定義sql語句
創建Statement語句對象
設置參數
執行
處理結果集
釋放資源

2.jdbc案例程序
第一步:創建項目
第二步:配置pom.xml,導入數據庫驅動包
第三步:編寫案例代碼

 1 public class JdbcTest01 {
 2 
 3 public static void main(String[] args) {
 4 Connection connection=null;
 5 PreparedStatement statement=null;
 6 ResultSet resultSet=null;
 7 //1.創建jdbc驅動
 8 try {
 9 Class.forName("com.mysql.jdbc.Driver");
10 //2.新建連接
11 connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mybatistest", "root", "root");
12 // //3.書寫sql
13 String sql="SELECT * FROM USER WHERE id =?";
14 //4.創建預處理對象
15 statement = connection.prepareStatement(sql);
16 //5.獲得結果集對象,設置參數
17 statement.setInt(1,1);
18 //6.執行查詢
19 resultSet = statement.executeQuery();
20 
21 while (resultSet.next()){
22 System.out.println("用戶的id為:"+resultSet.getInt("id")+"用戶名:"+resultSet.getString("username"));
23 
24 }
25 } catch (Exception e) {
26 e.printStackTrace();
27 }finally {
28 //7.關閉對象
29 try {
30 
31 if (resultSet!=null) resultSet.close();
32 
33 if (statement!=null) statement.close();
34 if (connection!=null) connection.close();
35 }catch (Exception e){
36 e.printStackTrace();
37 }
38 }
39 
40 }
41 }

 

3.總結jdbc開發的問題
1.頻繁創建數據庫連接對象和釋放,容易造成系統資源的浪費,從而影響系統的性能,在企業中,可以通過使用連接池技術解決這個問題,但是使用jdbc需要我們自己來實現連接池,mybatis內部提供連接池
2.sql語句的定義,參數設計,結果集處理存在硬編碼,在企業中sql語句因為需求的變化,所以變化頻繁,一但發生變化,需要修改java代碼,系統需要重新編譯,重新發布,不好維護
3.結果集處理存在重復代碼,每次都要遍歷resultset結果集,獲取一行數據,封裝為對象處理麻煩,如果可以自動把行數據封裝為java對象這樣就方便多了


三、mybatis框架快速入門

1.入門程序實現步驟分析:
第一步:創建Maven項目
第二步:配置pom.xml,導入依賴包

mysql驅動包
mybatis框架包
log4j日志包

第三步:編寫主配置文件(sqlMapConfig.xml)

第四步:編寫用戶實體類
第五步:編寫用戶dao接口
第六步:編寫用戶dao接口的映射文件(建立java對象與sql語句的對應關系)

第七步:在主配置文件sqlMapConfig.xml中,加載接口配置文件


第八步:編寫測試代碼

 1 public class MybatisDemo {
 2 
 3 public static void main(String[] args) {
 4 
 5 SqlSession session=null;
 6 InputStream inputStream =null;
 7 try {
 8 //1.加載讀取主配置文件
 9 inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
10 //2.構建新建sqlsessionfatory的必要條件
11 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
12 //根據配置文件創建sqlsessionfatory
13 SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
14 //3.根據sqlsessionfactory創建session
15 session = sqlSessionFactory.openSession();
16 
17 //4.根據session創建dao代理對象
18 UserDao userDao = session.getMapper(UserDao.class);
19 // System.out.println(userDao.getClass());
20 
21 //5.通過dao代理對象執行sql操作數據庫數據
22 List<User> userList = userDao.selectAllUser();
23 for (User user:userList){
24 System.out.println(user);
25 }
26 
27 
28 } catch (IOException e) {
29 e.printStackTrace();
30 }finally {
31 try {
32 //6.釋放資源
33 session.close();
34 inputStream.close();
35 } catch (IOException e) {
36 e.printStackTrace();
37 }
38 }
39 }
40 }

 

四、mybatis框架介紹
mybatis是Apache軟件基金會下的一個開源項目,前身是Ibatis框架。2010年這個項目由apache 軟件基金會遷移到google code下,改名為mybatis。2013年11月又遷移到了github(https://github.com/mybatis/mybatis-3/releases)。
mybatis是一個持久層的框架,是對jdbc操作數據庫的封裝,使開發者只需要關注業務本身,不需要花費精力去處理加載驅動、創建數據庫連接對象、創建statement語句對象、參數設置、結果集處理等一系列繁雜的過程代碼。
mybatis框架通過xml或注解進行配置,將java對象與sql語句中的參數自動映射生成最終執行的sql語句,並將sql語句執行結果自動映射成java對象。

三句話概括介紹:
1. mybatis框架早期版本叫做Ibatis,目前源代碼托管在github
2. mybatis框架是對jdbc操作數據庫的封裝,是一個持久層的框架
3. mybatis框架通過xml或者注解進行配置,實現java對象與sql語句的自動對應關系(orm映射)

 


五、自定義mybatis框架

1.解析配置文件
1.1.編寫Mapper類:namespace名稱空間,id屬性值,resultType返回值,執行的sql語句
1.2.編寫Configuraton類型:連接數據庫的四個基本要素,數據源對象(c3p0),接口映射文件


線程安全:
SqlSessionFactory:線程安全,因為它是只讀的
SqlSession:線程不安全
兩個用戶:
用戶一:SqlSession新增用戶記錄,操作時間很久。。。。。

用戶二:SqlSession新增訂單記錄,很快就執行完,並且提交事務。

 

day2

一、mybatis框架實現CRUD操作

1.搭建mybatis框架環境:
第一步:創建maven項目
第二步:配置pom.xml,導入依賴包
mybatis框架包
mysql數據庫驅動包
junit測試包
log4j日志包
第三步:編寫配置文件(sqlMapConfig.xml)
sqlMapConfig.xml
dao接口映射文件
log4j.properties
加載dao接口映射文件
2.實現根據用戶id查詢用戶:
第一步:編寫用戶實體類
第二步:編寫用戶dao(mapper)接口
第三步:編寫用戶dao(mapper)接口映射文件

第四步:在sqlMapConfig.xml,加載dao接口映射文件

根據用戶Id查詢用戶,說明:
3.實現根據用戶名稱模糊查詢用戶:
第一步:聲明mapper接口方法
第二步:配置mapper映射文件
第三步:測試

4.新增用戶:
4.1.事務(增刪改):事務的四個基本特性(ACID)
原子性,一致性,隔離性,持久性

4.2.事務提交方式:
手動提交
自動提交
4.3.注冊成為一個網站的用戶
用戶id是自動增長,不需要傳遞
網站要給我分配權限,需要使用用戶id
要不要查詢出這個id值?答案是要

4.4如何獲取數據庫維護的主鍵值?

5.根據用戶id修改用戶:
第一步:聲明mapper接口方法
第二步:配置mapper映射文件
第三步:測試

6.根據用戶id刪除用戶:
第一步:聲明mapper接口方法
第二步:配置mapper映射文件
第三步:測試

 

二、mybatis框架輸入輸出映射

1.ParameterType輸入映射(參數)
java簡單類型
pojo類型

pojo包裝類型:就是在pojo中包含了其它的pojo,通常用於接收綜合查詢條件

第一步:編寫pojo包裝類型實體類
第二步:聲明mapper接口方法
第三步:配置mapper映射文件
第四步:測試

2.ResultType返回值輸出

3.ResultMap返回值輸出

需求:查詢全部訂單表數據
需求實現:
編寫訂單實體類
編寫訂單mapper接口
編寫訂單mapper映射文件

在sqlMapConfig.xml加載訂單mapper映射文件

 

三、mybatis框架持久層開發的兩種方法

1.mapper代理開發方法【重點掌握-記住開發的原則】

2.傳統的dao開發方法【了解】
第一步:編寫mapper映射文件
第二步:編寫dao接口
第三步:編寫dao接口實現類

第四步:測試


四、mybatis框架注意事項
1.占位符#{}與字符串拼接符${}區別【重點】
(1).占位符 #{}
當參數傳遞的是java簡單類型(八種基本類型+字符串String)的時候,花括號中的內容可以是任意字符串
(2).字符串拼接符${}
當參數傳遞的是java簡單類型(八種基本類型+字符串String)的時候,花括號中的內容只能是value
(3).#{}、${}當參數傳遞的pojo類型的時候,花括號中的內容都是pojo的屬性

2.
id:唯一標識名稱,與接口方法名稱一致
parameterType:輸入參數類型,與接口方法形參類型一致
resultType:
返回值類型(暫時注意:它是po類的全限定名稱),與接口方法返回值類型一致,如果是List<User>,這種返回形式,則直接返回User
#{id}:占位符,相當於jdbc中的問號

獲取數據庫維護的主鍵值
selectKey:
作用:查詢數據庫維護的主鍵值
屬性:
keyColumn:主鍵字段
keyProperty:實體類中的屬性(與主鍵字段對應)
resultType:主鍵數據類型
resultMap:用於配置實體類屬性與數據庫表字段一一對應的
type:要映射的java對象類型
id:唯一標識名稱,通過id引用該resultMap

order:在insert語句執行前,還是執行后獲取主鍵值。BEFORE:在insert執行前;AFTER:在insert語句執行后
說明:直接在insert標簽中增加屬性的方式,只適合於支持自動增長主鍵類型的數據庫,比如mysql。
3.注意事項:java程序代碼執行成功,但是數據庫中並沒有新增記錄。原因是沒有提交事務,在對數據庫的更新操作中(增、刪、改)要求提交事務。
自動提交的特點,只要操作一完成,立即提交。如果在同一個方法中,有多個數據庫操作,需要使用手動提交的方式。
(方式一)創建SqlSession,指定自動提交事務。true:自動提交;false:不提交。默認是false

 1 SqlSession sqlSession = sqlSessionFactory.openSession(true); 
(方式二)手動提交事務
sqlSession.commit();
4 mapper代理開發方法【掌握】
從入門程序開始,一直使用的方式,即mapper代理開發的方法。特點:
1. 在開發的時候,只需要編寫持久層的接口,和持久層接口映射文件(mapper映射文件)。
2. 在執行的時候,mybatis框架通過動態代理生成接口的代理對象。
3. 總結mapper代理開發原則【記住】
1. mapper映射文件中namespace屬性值,必須是mapper接口的全限定名稱
2. mapper映射文件中sql語句標簽的聲明,與mapper接口中接口方法聲明一致
2.1.sql語句標簽中resultType屬性指定的返回值類型,與mapper接口方法返回值類型一致。(如果接口方法返回的是集合list,則resultType指定的是list中存放的類型)
2.2.sql語句標簽中的id屬性值,與mapper接口方法名稱一致
2.3.sql語句標簽中的parameterType屬性指定的類型,與mapper接口方法的形參類型一致

 

 day3

一、mybaits連接池
1.JNDI:java的名稱服務,用於從容器中獲取數據庫的連接(tomcat)
2.POOLED:使用連接池技術
3.UNPOOLED:不使用連接池技術(相當於原生的jdbc操作)


二、mybatis事務控制

1.手動提交
2.自動提交

3.mybatis框架的事務,底層都還是jdbc的事務操作

三、mybatis動態sql

1.動態sql案例(需求:根據用戶名稱和性別查詢用戶)
1.聲明mapper接口方法
2.配置mapper映射文件

2.if標簽
作用:判斷傳入的參數情況,拼裝sql語句片段

 1 <!--根據用戶名稱和性別查詢用戶-->
 2 <select id="findUserByNameAndSex"parameterType="user"resultType="user">
 3 select * from `user`
 4 where <!--username like #{username} and sex=#{sex}-->
 5 <!--if:判斷用戶名稱不為空,且不為空字符串,則作為查詢條件-->
 6 <if test="username !=null and username !=''">
 7 username like #{username}
 8 </if>
 9 <!--if:判斷用戶性別不為空,且不為空字符串,則作為查詢條件-->
10 <if test="sex !=null and sex !=''">
11 and sex=#{sex}
12 </if>
13 </select>

 

3.where標簽
作用:
1.相當於sql語句中的where關鍵字
2.根據傳入的參數情況,智能的去掉多余的and,or關鍵字
3.根據傳入的參數情況,智能的去掉多余的where關鍵字

 1 <!--根據用戶名稱和性別查詢用戶-->
 2 <select id="findUserByNameAndSex"parameterType="user"resultType="user">
 3 select * from `user`
 4 <!-- where username like #{username} and sex=#{sex}-->
 5 <where>
 6 <!--if:判斷用戶名稱不為空,且不為空字符串,則作為查詢條件-->
 7 <if test="username !=null and username !=''">
 8 username like #{username}
 9 </if>
10 <!--if:判斷用戶性別不為空,且不為空字符串,則作為查詢條件-->
11 <if test="sex !=null and sex !=''">
12 and sex=#{sex}
13 </if>
14 </where>
15 
16 </select>

 

4.set標簽:
作用:
1.相當於sql語句中的set關鍵字
2.根據傳入的參數情況,智能的去掉最后一個多余的逗號

 1 <!-- 動態修改用戶數據 -->
 2 <update id="dynamicUpdateUser"parameterType="user">
 3 update `user`
 4 <!-- set username='小李飛刀',sex='2' where id=2 -->
 5 <set>
 6 <if test="username != null and username !=''">
 7 username=#{username},
 8 </if>
 9 <if test="sex != null and sex !=''">
10 sex=#{sex},
11 </if>
12 </set>
13 
14 <where>
15 id=#{id}
16 </where>
17 </update>

5.sql(include)標簽:

作用:
1.提取公共的sql語句片段

 1 <!--sql:提取公共的sql語句片段,說明:
 2 id:唯一標識名稱,通過id引用該sql片段
 3 -->
 4 <sql id="select_orders_list">
 5 o.id,o.user_id,o.number,o.createtime,o.note
 6 </sql>
 7 
 8 <!--查詢全部訂單數據,使用resultType實現-->
 9 <select id="findAllOrders"resultType="cn.itheima.po.Orders">
10 <!--include:引用sql語句片段,說明:
11 refid:sql語句片段的id屬性值
12 -->
13 select <include refid="select_orders_list"></include> from orders o
14 </select>

6.foreach標簽:

作用:
1.循環處理參數集合(list,數組)

 1 <!-- 批量新增用戶-->
 2 <insert id="batchAddUsers"parameterType="list">
 3 insert into `user`(username,birthday,sex,address)
 4 values
 5 <!-- foreach:循環處理參數集合
 6 collection:參數集合,這里是list(固定寫法)
 7 item:當前遍歷的對象
 8 separator:指定分割符
 9 -->
10 <foreach collection="list"item="u"separator=",">
11 (#{u.username},#{u.birthday},#{u.sex},#{u.address})
12 </foreach>
13 <!-- ('用戶1','2018-07-08','1','地址1'),('用戶2','2018-07-08','1','地址2') -->
14 </insert>

四、mybatis關聯查詢

1.關聯關系分類:
一對一關聯關系:人和身份證關系,【雙向的】一對一關系
一對多關聯關系:用戶和訂單的關系
多對多關聯關系:用戶和角色

2.分析用戶訂單數據模型:
第一步:先確定單表有什么字段
第二步:找出關聯字段
第三步:結合業務需求確定表的關系

3.一對一關聯查詢:
實現思路:
第一步:編寫sql語句
第二步:聲明mapper接口方法
第三步:配置mapper映射文件

通過ResultType實現:
關鍵步驟:編寫一個實體類,包含sql語句中的字段對應屬性

 

通過ResultMap實現(<association/>):
關鍵步驟:在實體類之間建立關系,建立訂單到用戶的一對一關系

<!-- 配置訂單到用戶的一對一關聯關系,說明:
type:要映射的類型
id:唯一標識名稱,通過id引用該resultMap
-->
<resultMap type="orders"id="ordersUsersResultMap">
<!-- 配置訂單主鍵字段對應關系 -->
<id column="id"property="id"/>
<!-- 配置訂單的普通字段對應關系 -->
<result column="user_id"property="userId"/>
<result column="number"property="number"/>
<result column="createtime"property="createtime"/>
<result column="note"property="note"/>

<!-- association:配置一對一關聯關系,說明:
property:要映射的屬性名稱
javaType:要映射的屬性類型(必須要指定)
-->
<association property="user"javaType="User">
<!-- 配置用戶的主鍵字段對應關系 -->
<id column="user_id"property="id"/>
<!-- 配置用戶的普通字段對應關系 -->
<result column="username"property="username"/>
<result column="address"property="address"/>
</association>

</resultMap>

<!-- 查詢全部訂單數據,並且關聯查詢訂單所屬的用戶數據(resultMap)-->
<select id="findAllOrdersAndUserResultMap"resultMap="ordersUsersResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
LEFT JOIN `user` u ON o.user_id = u.id
</select>

 

4.一對多關聯查詢:
實現思路:
第一步:編寫sql語句
第二步:聲明mapper接口方法
第三步:配置mapper映射文件

思考題:一對多能不能使用ResultType實現? 不能使用ResultType實現

使用ResultMap實現(<collection/>):
關鍵步驟:在實體類之間建立關系,建立用戶到訂單的一對多關系

<!-- 配置用戶到訂單的一對多關聯關系,說明:
type:要映射的類型
id:唯一標識名稱,通過id引用該resultMap
-->
<resultMap type="user"id="usersOrdersResultMap">
<!-- 配置用戶的主鍵字段對應關系 -->
<id column="id"property="id"/>
<!-- 配置用戶的普通字段對應關系 -->
<result column="username"property="username"/>
<result column="birthday"property="birthday"/>
<result column="sex"property="sex"/>
<result column="address"property="address"/>

<!-- collection:配置一對多關聯關系,說明:
property:要映射的屬性名稱
javaType:要映射的屬性類型(可以指定,可以不指定,建議都指定)
ofType:指定集合中存放的類型(必須要指定)
-->
<collection property="ordersList"javaType="List"ofType="Orders">
<!-- 配置訂單的主鍵對應關系 -->
<id column="oid"property="id"/>
<!-- 配置訂單普通字段對應關系 -->
<result column="number"property="number"/>
<result column="createtime"property="createtime"/>
</collection>

</resultMap>

<!-- 查詢全部用戶數據,並且關聯查詢出用戶的所有訂單數據 -->
<select id="findAllUsersAndOrders"resultMap="usersOrdersResultMap">
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.id oid,
o.number,
o.createtime
FROM
`user` u
LEFT JOIN orders o ON u.id = o.user_id
</select>

 

5.多對多關聯查詢:通過中間表看成兩個一對多關聯關系

需求:查詢用戶數據,並且關聯查詢出用戶的角色數據

實現思路:
第一步:編寫sql語句
第二步:聲明mapper接口方法
第三步:配置mapper映射文件

關鍵步驟:在實體類之間建立關系,建立用戶到角色的一對多關系

<!-- 配置用戶到角色的一對多關聯關系,說明:
type:要映射的類型
id:唯一標識名稱,通過id引用該resultMap
-->
<resultMap type="user"id="usersRolesResultMap">
<!-- 配置用戶的主鍵字段對應關系 -->
<id column="id"property="id"/>
<!-- 配置用戶的普通字段對應關系 -->
<result column="username"property="username"/>
<result column="birthday"property="birthday"/>
<result column="sex"property="sex"/>
<result column="address"property="address"/>

<!-- collection:配置一對多關聯關系,說明:
property:要映射的屬性名稱
javaType:要映射的屬性類型(可以指定,可以不指定,建議都指定)
ofType:指定集合中存放的類型(必須要指定)
-->
<collection property="roleList"javaType="List"ofType="Role">
<!-- 配置訂單的主鍵對應關系 -->
<id column="role_id"property="roleId"/>
<!-- 配置訂單普通字段對應關系 -->
<result column="role_name"property="roleName"/>
</collection>

</resultMap>

<!-- 查詢用戶數據,並且關聯查詢用戶的所有角色數據-->
<select id="findUsersAndRoles"resultMap="usersRolesResultMap">
SELECT
u.id,
u.username,
u.birthday,
u.sex,
u.address,
r.role_id,
r.role_name
FROM
`user` u
INNER JOIN user_role ur ON u.id = ur.user_id
INNER JOIN role r ON ur.role_id = r.role_id
</select>

day4


一、mybatis延遲加載

1.什么是延遲加載?
延遲加載,叫做懶加載,按需加載。
它的特點關聯查詢中,分步驟實現查詢(每一步都是單表操作)

2.延遲加載案例演示:
查詢訂單數據,並且關聯查詢出訂單所屬的用戶數據。采用延遲加載的方式實現。
實現步驟:
第一步:只從訂單表查詢訂單數據
第二步:在需要的時候,在查詢用戶表的數據
第三步:配置mybatis框架,開啟延遲加載


延遲加載的注意事項:toString方法和debug調試模式看不到延遲加載的效果

3.一對多關聯查詢的延遲加載方式實現:
第一步:單表查詢用戶數據
第二步:在需要的時候,再查詢訂單表的數據
第三步:配置mybatis框架,開啟延遲加載


二、mybatis緩存

1.一級緩存:sqlSession范圍的緩存,一級緩存本身就已經存在,不需要關心

2.二級緩存:mapper級別級別,在多個sqlSession之間可以共享數據
第一步:需要配置sqlMapConfig.xml,開啟二級緩存
第二步:序列化Seriallizable,實體類對象需要實現序列化
第三步:在mapper映射文件,還需要明確是否使用緩存

說明:mybatis的二級緩存只做了解,在企業項目中不推薦使用。原因是mybatis的緩存
不能實現【細粒度】的控制。實際項目中我們會考慮使用像redis中間件


三、mybatis注解開發【了解】

1.注解基本操作(CRUD操作):
查詢:@Select
修改:@Update
刪除:@Delete
新增:@Insert

獲取數據庫維護的主鍵值:
@SelectKey

 

2.注解高級操作(關聯查詢):
@Results注解:相當於xml文件中的<ResultMap/>標簽
@Result注解:相當於<ResultMap/>的子標簽<id/>和<result/>
@One注解:配置一對一關聯關系,相當於xml中的<association/>,可以實現延遲加載
@Many注解:配置一對多關聯關系,相當於xml中的<collection/>標簽,可以實現延遲加載

延遲加載方式實現:一對一關聯查詢的方式:
實現步驟:
第一步:只從訂單表查詢數據
第二步:在需要的時候,查詢用戶表數據
第三步:在sqlMapConfig.xml中,配置延遲加載

 

延遲加載方式實現:一對多關聯查詢:
需求:查詢全部用戶數據,並且關聯查詢出用戶的全部訂單數據。采用延遲加載的方式實現
實現步驟:
第一步:只查詢用戶表數據
第二步:在需要的時候,查詢訂單表的數據
第三步:在sqlMapConfig.xml中,配置延遲加載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM