mybatis详解 2017-01-05
MyBatis之代理开发模式1 mybatis-Dao的代理开发模式Dao:数据访问对象
原来:定义dao接口,在定义dao的实现类
dao的代理开发模式
只需要定义dao接口,由mybatis产生dao接口的实现类。
1.1定义Mapper接口1package org.guangsoft.mapper;23import java.util.List;45import org.guangsoft.entity.Dept;6import org.guangsoft.vo.DeptVo;78public interface DeptMapper9 {10 public ListgetDeptPost();11 public void saveDept(Dept dept);12 }
1.2定义Mapper.xml文件
定义Mapper接口中方法对应的操作
2 34 10 13 14 insert into dept values(null,#{dname})15 16
1.3通过session产生Mapper接口的代理对象
public class TestDeptMapper2{3 SqlSessionFactory ssf = null;4 @Before5 public void before()6 {7 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();8 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));9 }1011 @Test12 public void testGetDeptPost()13 {14 SqlSession sqlSession = ssf.openSession();15 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);16 ListdeptVoList = deptMapper.getDeptPost();17 for(DeptVo deptVo : deptVoList)18 {19 System.out.println(deptVo);20 }21 sqlSession.close();22 }2324 @Test25 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 Transfer34 Source Server : MySQL5 Source Server Version : 507156 Source Host : localhost:33067 Source Database : test89 Target Server Type : MYSQL10 Target Server Version : 5071511 File Encoding : 650011213 Date: 2016-12-14 20:47:2714 */1516 SET FOREIGN_KEY_CHECKS=0;1718 -- ----------------------------19 -- Table structure for orders20 -- ----------------------------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;3233 -- ----------------------------34 -- Table structure for user35 -- ----------------------------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实体模型
1package org.guangsoft.entity;23import java.util.Set;45public class User6{7 private Integer uid;8 private String username;9 private String password;10 private Setorders;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 getOrders()36 {37 return orders;38 }39 public void setOrders(Set orders)40 {41 this.orders = orders;42 }4344 }
1 package org.guangsoft.entity;23 import java.util.Date;4 import java.util.Set;567 public class Orders8 {9 private Integer oid;10 private Date odate;11 private Double ototal;12 private String odesc;13 private User user;14 //关联订单下的明细15 private Setdetails;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 getDetails()57 {58 return details;59 }60 public void setDetails(Set details)61 {62 this.details = details;63 }6465 }
2.1.3定义Mapper接口
1package org.guangsoft.mapper;23import org.guangsoft.entity.Orders;45public interface OrdersMapper6{7 public Orders loadOrdersUser(Integer oid);8 }
2.1.4定义Mapper.xml
描述接口中方法对应的操作。
1 2 34 5 15 206 7 8 9 10 1411 12 13
2.1.5获得Mapper接口代理对象
1 public class TestDeptMapper2 {3 SqlSessionFactory ssf = null;4 @Before5 public void before()6 {7 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();8 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));9 }1011 @Test12 public void testGetDeptPost()13 {14 SqlSession sqlSession = ssf.openSession();15 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);16 ListdeptVoList = deptMapper.getDeptPost();17 for(DeptVo deptVo : deptVoList)18 {19 System.out.println(deptVo);20 }21 sqlSession.close();22 }23 }
2.2 one-to-many查询
对表关联查询
给Users加入orders的集合属性
2.2.1定义Mapper接口
1 package org.guangsoft.mapper;23 import java.util.List;45 import org.guangsoft.entity.User;67 public interface UserMapper8 {9 public User loadUserOrders(Integer uid);10 public ListloadUserOrdersDetail();11 public List loadUserOrdersDetail2();12 }
2.2.2定义Mapper文件
1 2 34 5 14 196 7 8 139 10 11 12 20 33 3839 42 45 4821 22 23 3224 25 26 3127 28 29 30
2.2.3获得Mapper接口的代理对象
代码见上
2.3 many-to-many查询(代码见上)查询所有用户的所有订单信息和订单明细
订单号 ,用户名,日期,商品名称,单价,数量,小计
2.3.1建立订单明细表订单明细表和订单表之间存在者主外键.
多个用户对应者多个订单,多个订单对应多个明细
2.3.2 定义Mapper接口2.3.3 定义Mapper.xml文件2.3.4 获得Mapper接口代理对象 3 mybatis的懒加载将多表关联查询的sql语句,分开执行
3.1开启懒加载1 23
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;23 import java.util.List;45 import org.guangsoft.entity.Detail;67 public interface DetailMapper8 {9 /**10 * 按照订单的编号,商品的名称,商品的数量,商品单价查询订单信息11 * @return12 */13 public ListloadDetail(Detail detail);14 public void deleteDetails(Integer dids[]);15 }
4.1.2定义Mapper.xml文件
1 2 34 5 17 226 167 and pname = #{pname}8 910 and price = #{price}11 1213 and cts = #{cts}14 1523 delete from detail24 31 3433 35 insert into dept values(null,#{dname})36 37
4.1.3获得Mapper代理对象
1 package org.guangsoft.test;23 import java.util.List;4 import java.util.Set;56 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;2021 public class TestDeptMapper22 {23 SqlSessionFactory ssf = null;24 @Before25 public void before()26 {27 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();28 ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));29 }3031 @Test32 public void testGetDeptPost()33 {34 SqlSession sqlSession = ssf.openSession();35 DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);36 ListdeptVoList = deptMapper.getDeptPost();37 for(DeptVo deptVo : deptVoList)38 {39 System.out.println(deptVo);40 }41 sqlSession.close();42 }4344 @Test45 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 }5556 @Test57 public void testGetUserOrders()58 {59 SqlSession sqlSession = ssf.openSession();60 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);61 User user = userMapper.loadUserOrders(1);62 Set ordersSet = user.getOrders();63 for(Orders orders : ordersSet)64 {65 System.out.println(orders);66 }67 }6869 @Test70 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 }7879 @Test80 public void testDetail()81 {82 SqlSession sqlSession = ssf.openSession();83 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);84 List ulist = userMapper.loadUserOrdersDetail();85 for(User user : ulist)86 {87 Set orders = user.getOrders();88 if(orders != null)89 {90 for(Orders o : orders)91 {92 Set details = o.getDetails();93 for(Detail d : details)94 {95 System.out.println(d.getPname());96 }97 }98 }99 }100 }101102 @Test103 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 userList = userMapper.loadUserOrdersDetail2();109 for(User user : userList)110 {111 System.out.println(user.getUsername());112 Set orders = user.getOrders();113 if(orders != null)114 {115 for(Orders o : orders)116 {117 Set 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.xml4.2.3获得Mapper代理对象5定义sql片段使用sql标签定义sql片段,
提高sql语句复用性.
使用include标签引用sql片段
6 mybatis的缓存机制
查询缓存:只有在做查询操作的时候,将数据进行缓存
6.1 mybaits的一级缓存Session级别的缓存,不同的客户端访问数据库,缓存是独立的。
在进行查询操作的时候,数据自动放入一级缓存。
缓存数据消失:
提交事务的时候。
关闭数据库会话。
数据进行缓存的key:namespace+id+params+limit(缓存的界定,通过namespace+id+查询参数+结果集的限定),产生本次查询缓存对应的key
6.2二级缓存
二级sessionFactory级别的缓存(共享缓存)
开启二级缓存
加入缓存插件包(二级缓存为外部缓存插件)
配置缓存策略,在需要进行缓存的Mapper.xml
1
提供ehcache的配置文件
作者:little飞 出处:http://www.cnblogs.com/little-fly/ 欢迎转载 也请保留这段声明 谢谢!