1 mybatis-Dao的代理開發模式
Dao:數據訪問對象
原來:定義dao接口,在定義dao的實現類
dao的代理開發模式
只需要定義dao接口,由mybatis產生dao接口的實現類。
1.1定義Mapper接口
1 package org.guangsoft.mapper; 2
3 import java.util.List; 4
5 import org.guangsoft.entity.Dept; 6 import org.guangsoft.vo.DeptVo; 7
8 public interface DeptMapper 9 { 10 public List<DeptVo> getDeptPost(); 11 public void saveDept(Dept dept); 12 }
1.2定義Mapper.xml文件
定義Mapper接口中方法對應的操作
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="org.guangsoft.mapper.DeptMapper">
4 <!-- 使用dao的代理開發模式的時候 5 1,namespace必須和map接口的完全限定名完全一樣 6 2.對應的數據庫庫擦操作id必須和接口中抽象放安防名一致 7 3,parameterType必須和抽閑接口的抽象方法參數類型一致 8 4,resultType必須和接口抽象方法的返回類型一樣 9 -->
10 <select id="getDeptPost" resultType="org.guangsoft.vo.DeptVo">
11 select dept.did,dname,pname from dept inner join post on dept.did=post.did 12 </select>
13 <insert id="saveDept" parameterType="org.guangsoft.entity.Dept">
14 insert into dept values(null,#{dname}) 15 </insert>
16 </mapper>
1.3通過session產生Mapper接口的代理對象
1 public class TestDeptMapper 2 { 3 SqlSessionFactory ssf = null; 4 @Before 5 public void before() 6 { 7 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder(); 8 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml")); 9 } 10
11 @Test 12 public void testGetDeptPost() 13 { 14 SqlSession sqlSession = ssf.openSession(); 15 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); 16 List<DeptVo> deptVoList = deptMapper.getDeptPost(); 17 for(DeptVo deptVo : deptVoList) 18 { 19 System.out.println(deptVo); 20 } 21 sqlSession.close(); 22 } 23
24 @Test 25 public void testSaveDept() 26 { 27 SqlSession sqlSession = ssf.openSession(); 28 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); 29 Dept dept = new Dept(); 30 dept.setDname("danme"); 31 deptMapper.saveDept(dept); 32 sqlSession.commit(); 33 sqlSession.close(); 34 } 35 }
2 mybatis的關聯查詢
Mybatis多表查詢。
2.1 one-to-one 查詢
需求:查詢某個訂單和訂單對應的用戶信息
訂單編號 用戶名 時間 金額 描述
2.1.1建立數據庫模型
用戶表,訂單表。
1 /*
2 Navicat MySQL Data Transfer 3
4 Source Server : MySQL 5 Source Server Version : 50715 6 Source Host : localhost:3306 7 Source Database : test 8
9 Target Server Type : MYSQL 10 Target Server Version : 50715 11 File Encoding : 65001 12
13 Date: 2016-12-14 20:47:27 14 */
15
16 SET FOREIGN_KEY_CHECKS=0; 17
18 -- ----------------------------
19 -- Table structure for orders
20 -- ----------------------------
21 DROP TABLE IF EXISTS `orders`; 22 CREATE TABLE `orders` ( 23 `oid` int(11) NOT NULL AUTO_INCREMENT, 24 `odate` datetime DEFAULT NULL, 25 `ototal` double DEFAULT NULL, 26 `odesc` varchar(255) DEFAULT NULL, 27 `uid` int(11) DEFAULT NULL, 28 PRIMARY KEY (`oid`), 29 KEY `fk_uid` (`uid`), 30 CONSTRAINT `fk_uid` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) 31 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 32
33 -- ----------------------------
34 -- Table structure for user
35 -- ----------------------------
36 DROP TABLE IF EXISTS `user`; 37 CREATE TABLE `user` ( 38 `uid` int(11) NOT NULL AUTO_INCREMENT, 39 `username` varchar(255) DEFAULT NULL, 40 `password` varchar(255) DEFAULT NULL, 41 PRIMARY KEY (`uid`) 42 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
2.1.2產生java實體模型
1 package org.guangsoft.entity; 2
3 import java.util.Set; 4
5 public class User 6 { 7 private Integer uid; 8 private String username; 9 private String password; 10 private Set<Orders> orders; 11 public Integer getUid() 12 { 13 return uid; 14 } 15 public void setUid(Integer uid) 16 { 17 this.uid = uid; 18 } 19 public String getUsername() 20 { 21 return username; 22 } 23 public void setUsername(String username) 24 { 25 this.username = username; 26 } 27 public String getPassword() 28 { 29 return password; 30 } 31 public void setPassword(String password) 32 { 33 this.password = password; 34 } 35 public Set<Orders> getOrders() 36 { 37 return orders; 38 } 39 public void setOrders(Set<Orders> orders) 40 { 41 this.orders = orders; 42 } 43
44 }
1 package org.guangsoft.entity; 2
3 import java.util.Date; 4 import java.util.Set; 5
6
7 public class Orders 8 { 9 private Integer oid; 10 private Date odate; 11 private Double ototal; 12 private String odesc; 13 private User user; 14 //關聯訂單下的明細
15 private Set<Detail> details; 16 public Integer getOid() 17 { 18 return oid; 19 } 20 public void setOid(Integer oid) 21 { 22 this.oid = oid; 23 } 24 public Date getOdate() 25 { 26 return odate; 27 } 28 public void setOdate(Date odate) 29 { 30 this.odate = odate; 31 } 32 public Double getOtotal() 33 { 34 return ototal; 35 } 36 public void setOtotal(Double ototal) 37 { 38 this.ototal = ototal; 39 } 40 public String getOdesc() 41 { 42 return odesc; 43 } 44 public void setOdesc(String odesc) 45 { 46 this.odesc = odesc; 47 } 48 public User getUser() 49 { 50 return user; 51 } 52 public void setUser(User user) 53 { 54 this.user = user; 55 } 56 public Set<Detail> getDetails() 57 { 58 return details; 59 } 60 public void setDetails(Set<Detail> details) 61 { 62 this.details = details; 63 } 64
65 }
2.1.3定義Mapper接口
1 package org.guangsoft.mapper; 2
3 import org.guangsoft.entity.Orders; 4
5 public interface OrdersMapper 6 { 7 public Orders loadOrdersUser(Integer oid); 8 }
2.1.4定義Mapper.xml
描述接口中方法對應的操作。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="org.guangsoft.mapper.OrdersMapper">
4 <resultMap type="org.guangsoft.entity.Orders" id="ordersUser">
5 <id column="oid" property="oid" />
6 <result column="odate" property="odate" />
7 <result column="odesc" property="odesc" />
8 <result column="ototal" property="ototal" />
9 <association property="user" javaType="org.guangsoft.entity.User">
10 <id column="uid" property="uid" />
11 <result column="username" property="username" />
12 <result column="password" property="password" />
13 </association>
14 </resultMap>
15 <select id="loadOrdersUser" parameterType="java.lang.Integer" resultMap="ordersUser">
16 select oid ,odate,ototal,odesc,username 17 from orders inner join user 18 on orders.uid = user.uid where orders.oid = #{oid} 19 </select>
20 </mapper>
2.1.5獲得Mapper接口代理對象
1 public class TestDeptMapper 2 { 3 SqlSessionFactory ssf = null; 4 @Before 5 public void before() 6 { 7 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder(); 8 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml")); 9 } 10
11 @Test 12 public void testGetDeptPost() 13 { 14 SqlSession sqlSession = ssf.openSession(); 15 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); 16 List<DeptVo> deptVoList = deptMapper.getDeptPost(); 17 for(DeptVo deptVo : deptVoList) 18 { 19 System.out.println(deptVo); 20 } 21 sqlSession.close(); 22 } 23 }
2.2one-to-many查詢
對表關聯查詢
給Users加入orders的集合屬性
2.2.1定義Mapper接口
1 package org.guangsoft.mapper; 2
3 import java.util.List; 4
5 import org.guangsoft.entity.User; 6
7 public interface UserMapper 8 { 9 public User loadUserOrders(Integer uid); 10 public List<User> loadUserOrdersDetail(); 11 public List<User> loadUserOrdersDetail2(); 12 }
2.2.2定義Mapper文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="org.guangsoft.mapper.UserMapper">
4 <resultMap type="org.guangsoft.entity.User" id="userOrders">
5 <id column="uid" property="uid" />
6 <result column="username" property="username"></result>
7 <collection property="orders" ofType="org.guangsoft.entity.Orders">
8 <id column="oid" property="oid" />
9 <result column="odate" property="odate" />
10 <result column="odesc" property="odesc" />
11 <result column="ototal" property="ototal" />
12 </collection>
13 </resultMap>
14 <select id="loadUserOrders" parameterType="java.lang.Integer" resultMap="userOrders">
15 select user.uid ,oid ,odate,ototal,odesc,username 16 from orders inner join user 17 on orders.uid = user.uid where user.uid = #{uid} 18 </select>
19 <resultMap type="org.guangsoft.entity.User" id="userOrdersDetail">
20 <id column="uid" property="uid" />
21 <result column="username" property="username" />
22 <collection property="orders" ofType="org.guangsoft.entity.Orders">
23 <id column="oid" property="oid" ></id>
24 <result column="odate" property="odate" ></result>
25 <collection property="details" ofType="org.guangsoft.entity.Detail">
26 <id column="did" property="did"></id>
27 <result column="price" property="price"></result>
28 <result column="pname" property="pname"></result>
29 <result column="cts" property="cts"></result>
30 </collection>
31 </collection>
32 </resultMap>
33 <select id="loadUserOrdersDetail" resultMap="userOrdersDetail">
34 select user.uid,orders.oid,username,odate,pname,price,cts 35 from user left join orders on user.uid=orders.uid 36 left join detail on orders.oid = detail.oid 37 </select>
38
39 <select id="loadUserOrdersDetail2" resultMap="userOrdersDetail">
40 select user.uid,username from user 41 </select>
42 <select id="loadOrders" parameterType="java.lang.Integer" resultType="org.guangsoft.entity.Orders">
43 select oid,odate from orders where orders.uid=#{uid} 44 </select>
45 <select id="loadDetail" parameterType="java.lang.Integer" resultType="org.guangsoft.entity.Detail">
46 select pname,price,cts,odid from detail where detail.oid=#{oid} 47 </select>
48 </mapper>
2.2.3獲得Mapper接口的代理對象
代碼見上
2.3many-to-many查詢(代碼見上)
查詢所有用戶的所有訂單信息和訂單明細
訂單號 ,用戶名,日期,商品名稱,單價,數量,小計
2.3.1建立訂單明細表
訂單明細表和訂單表之間存在者主外鍵.
多個用戶對應者多個訂單,多個訂單對應多個明細
2.3.2定義Mapper接口
2.3.3定義Mapper.xml文件
2.3.4獲得Mapper接口代理對象
3 mybatis的懶加載
將多表關聯查詢的sql語句,分開執行
3.1開啟懶加載
1 <!-- 開啟mybatis的懶加載 -->
2 <setting name="lazyLoadingEnabled" value="true"/>
3 <setting name="aggressiveLazyLoading" value="false"/>
3.2Mapper接口中添加方法
3.3拆分sql語句
3.4獲得Mapper代理對象
4 mybatis的動態sql
更具業務需要,可以對sql完成動態的構造。
4.1 if標簽
需求:查詢訂單明細,可以根據訂單的編號,商品的名稱,商品數量,商品的單價查詢。
問題:select * from ordersdetails where (?)
4.1.1定義Mapper接口
1 package org.guangsoft.mapper; 2
3 import java.util.List; 4
5 import org.guangsoft.entity.Detail; 6
7 public interface DetailMapper 8 { 9 /**
10 * 按照訂單的編號,商品的名稱,商品的數量,商品單價查詢訂單信息 11 * @return
12 */
13 public List<Detail> loadDetail(Detail detail); 14 public void deleteDetails(Integer dids[]); 15 }
4.1.2定義Mapper.xml文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="org.guangsoft.mapper.DetailMapper">
4 <sql id="cond">
5 <where>
6 <if test="pname != null"><!-- 商品名稱 -->
7 and pname = #{pname} 8 </if>
9 <if test="price != null"><!-- 商品價格 -->
10 and price = #{price} 11 </if>
12 <if test="cts != null"><!-- 商品 -->
13 and cts = #{cts} 14 </if>
15 </where>
16 </sql>
17 <select id="loadDetail" resultType="org.guangsoft.entity.Detail">
18 select * from detail 19 <!-- 動態關聯where關鍵字 -->
20 <include refid="cond"></include>
21 </select>
22 <delete id="deleteDetails" parameterType="org.guangsoft.entity.Detail">
23 delete from detail 24 <!--
25 collection需要遍歷的集合 26 item集合匯總的每個元素 27 open第一次遍歷 28 close最后一次遍歷 29 separator將遍歷的元素使用什么隔開 30 -->
31 <foreach collection="dids" item="did" open="where did in (" close=")"
32 separator=","></foreach>
33 </delete>
34 <insert id="saveDept" parameterType="org.guangsoft.entity.Dept">
35 insert into dept values(null,#{dname}) 36 </insert>
37 </mapper>
4.1.3獲得Mapper代理對象
1 package org.guangsoft.test; 2
3 import java.util.List; 4 import java.util.Set; 5
6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 9 import org.guangsoft.entity.Dept; 10 import org.guangsoft.entity.Detail; 11 import org.guangsoft.entity.Orders; 12 import org.guangsoft.entity.User; 13 import org.guangsoft.mapper.DeptMapper; 14 import org.guangsoft.mapper.DetailMapper; 15 import org.guangsoft.mapper.OrdersMapper; 16 import org.guangsoft.mapper.UserMapper; 17 import org.guangsoft.vo.DeptVo; 18 import org.junit.Before; 19 import org.junit.Test; 20
21 public class TestDeptMapper 22 { 23 SqlSessionFactory ssf = null; 24 @Before 25 public void before() 26 { 27 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder(); 28 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml")); 29 } 30
31 @Test 32 public void testGetDeptPost() 33 { 34 SqlSession sqlSession = ssf.openSession(); 35 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); 36 List<DeptVo> deptVoList = deptMapper.getDeptPost(); 37 for(DeptVo deptVo : deptVoList) 38 { 39 System.out.println(deptVo); 40 } 41 sqlSession.close(); 42 } 43
44 @Test 45 public void testSaveDept() 46 { 47 SqlSession sqlSession = ssf.openSession(); 48 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); 49 Dept dept = new Dept(); 50 dept.setDname("danme"); 51 deptMapper.saveDept(dept); 52 sqlSession.commit(); 53 sqlSession.close(); 54 } 55
56 @Test 57 public void testGetUserOrders() 58 { 59 SqlSession sqlSession = ssf.openSession(); 60 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 61 User user = userMapper.loadUserOrders(1); 62 Set<Orders> ordersSet = user.getOrders(); 63 for(Orders orders : ordersSet) 64 { 65 System.out.println(orders); 66 } 67 } 68
69 @Test 70 public void testGetOrdersUser() 71 { 72 SqlSession sqlSession = ssf.openSession(); 73 OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class); 74 Orders orders = ordersMapper.loadOrdersUser(1); 75 System.out.println(orders.getUser().getUsername()); 76 sqlSession.close(); 77 } 78
79 @Test 80 public void testDetail() 81 { 82 SqlSession sqlSession = ssf.openSession(); 83 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 84 List<User> ulist = userMapper.loadUserOrdersDetail(); 85 for(User user : ulist) 86 { 87 Set<Orders> orders = user.getOrders(); 88 if(orders != null) 89 { 90 for(Orders o : orders) 91 { 92 Set<Detail> details = o.getDetails(); 93 for(Detail d : details) 94 { 95 System.out.println(d.getPname()); 96 } 97 } 98 } 99 } 100 } 101
102 @Test 103 public void testDetail2() 104 { 105 SqlSession sqlSession = ssf.openSession(); 106 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 107 OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class); 108 List<User> userList = userMapper.loadUserOrdersDetail2(); 109 for(User user : userList) 110 { 111 System.out.println(user.getUsername()); 112 Set<Orders> orders = user.getOrders(); 113 if(orders != null) 114 { 115 for(Orders o : orders) 116 { 117 Set<Detail> details = o.getDetails(); 118 for(Detail d : details) 119 { 120 System.out.println(d.getPname()); 121 } 122 } 123 } 124 } 125 } 126 }
4.2foreach標簽
完成訂單明細的批量刪除
Delete from ordersdetails where odid in (1,3,4,5)
4.2.1定義Mapper接口
4.2.2定義Mapper.xml
4.2.3獲得Mapper代理對象
5定義sql片段
使用sql標簽定義sql片段,
提高sql語句復用性.
使用include標簽引用sql片段
6mybatis的緩存機制
查詢緩存:只有在做查詢操作的時候,將數據進行緩存
6.1 mybaits的一級緩存
Session級別的緩存,不同的客戶端訪問數據庫,緩存是獨立的。
在進行查詢操作的時候,數據自動放入一級緩存。
緩存數據消失:
提交事務的時候。
關閉數據庫會話。
數據進行緩存的key:namespace+id+params+limit(緩存的界定,通過namespace+id+查詢參數+結果集的限定),產生本次查詢緩存對應的key
6.2二級緩存
二級sessionFactory級別的緩存(共享緩存)
開啟二級緩存
加入緩存插件包(二級緩存為外部緩存插件)
配置緩存策略,在需要進行緩存的Mapper.xml
1 <cache readOnly="true" type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
提供ehcache的配置文件