MyBatis之代理开发模式


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的配置文件

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM