MyBatis之代理开发模式
1 mybatis-Dao的代理开发模式
Dao:数据访问对象
原来:定义dao接口,在定义dao的实现类
dao的代理开发模式
只需要定义dao接口,由mybatis产生dao接口的实现类。
1.1定义Mapper接口
package org.guangsoft.mapper; import java.util.List; import org.guangsoft.entity.Dept;
import org.guangsoft.vo.DeptVo; public interface DeptMapper
{
public List<DeptVo> getDeptPost();
public void saveDept(Dept dept);
}
1.2定义Mapper.xml文件
定义Mapper接口中方法对应的操作
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.guangsoft.mapper.DeptMapper">
<!-- 使用dao的代理开发模式的时候
1,namespace必须和map接口的完全限定名完全一样
2.对应的数据库库擦操作id必须和接口中抽象放安防名一致
3,parameterType必须和抽闲接口的抽象方法参数类型一致
4,resultType必须和接口抽象方法的返回类型一样
-->
<select id="getDeptPost" resultType="org.guangsoft.vo.DeptVo">
select dept.did,dname,pname from dept inner join post on dept.did=post.did
</select>
<insert id="saveDept" parameterType="org.guangsoft.entity.Dept">
insert into dept values(null,#{dname})
</insert>
</mapper>
1.3通过session产生Mapper接口的代理对象
public class TestDeptMapper
{
SqlSessionFactory ssf = null;
@Before
public void before()
{
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));
} @Test
public void testGetDeptPost()
{
SqlSession sqlSession = ssf.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<DeptVo> deptVoList = deptMapper.getDeptPost();
for(DeptVo deptVo : deptVoList)
{
System.out.println(deptVo);
}
sqlSession.close();
} @Test
public void testSaveDept()
{
SqlSession sqlSession = ssf.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDname("danme");
deptMapper.saveDept(dept);
sqlSession.commit();
sqlSession.close();
}
}
2 mybatis的关联查询
Mybatis多表查询。
2.1 one-to-one 查询
需求:查询某个订单和订单对应的用户信息
订单编号 用户名 时间 金额 描述
2.1.1建立数据库模型
用户表,订单表。
/*
Navicat MySQL Data Transfer Source Server : MySQL
Source Server Version : 50715
Source Host : localhost:3306
Source Database : test Target Server Type : MYSQL
Target Server Version : 50715
File Encoding : 65001 Date: 2016-12-14 20:47:27
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for orders
-- ----------------------------
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
`oid` int(11) NOT NULL AUTO_INCREMENT,
`odate` datetime DEFAULT NULL,
`ototal` double DEFAULT NULL,
`odesc` varchar(255) DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `fk_uid` (`uid`),
CONSTRAINT `fk_uid` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
2.1.2产生java实体模型
package org.guangsoft.entity; import java.util.Set; public class User
{
private Integer uid;
private String username;
private String password;
private Set<Orders> orders;
public Integer getUid()
{
return uid;
}
public void setUid(Integer uid)
{
this.uid = uid;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public Set<Orders> getOrders()
{
return orders;
}
public void setOrders(Set<Orders> orders)
{
this.orders = orders;
} }
package org.guangsoft.entity; import java.util.Date;
import java.util.Set; public class Orders
{
private Integer oid;
private Date odate;
private Double ototal;
private String odesc;
private User user;
//关联订单下的明细
private Set<Detail> details;
public Integer getOid()
{
return oid;
}
public void setOid(Integer oid)
{
this.oid = oid;
}
public Date getOdate()
{
return odate;
}
public void setOdate(Date odate)
{
this.odate = odate;
}
public Double getOtotal()
{
return ototal;
}
public void setOtotal(Double ototal)
{
this.ototal = ototal;
}
public String getOdesc()
{
return odesc;
}
public void setOdesc(String odesc)
{
this.odesc = odesc;
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public Set<Detail> getDetails()
{
return details;
}
public void setDetails(Set<Detail> details)
{
this.details = details;
} }
2.1.3定义Mapper接口
package org.guangsoft.mapper; import org.guangsoft.entity.Orders; public interface OrdersMapper
{
public Orders loadOrdersUser(Integer oid);
}
2.1.4定义Mapper.xml
描述接口中方法对应的操作。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.guangsoft.mapper.OrdersMapper">
<resultMap type="org.guangsoft.entity.Orders" id="ordersUser">
<id column="oid" property="oid" />
<result column="odate" property="odate" />
<result column="odesc" property="odesc" />
<result column="ototal" property="ototal" />
<association property="user" javaType="org.guangsoft.entity.User">
<id column="uid" property="uid" />
<result column="username" property="username" />
<result column="password" property="password" />
</association>
</resultMap>
<select id="loadOrdersUser" parameterType="java.lang.Integer" resultMap="ordersUser">
select oid ,odate,ototal,odesc,username
from orders inner join user
on orders.uid = user.uid where orders.oid = #{oid}
</select>
</mapper>
2.1.5获得Mapper接口代理对象
public class TestDeptMapper
{
SqlSessionFactory ssf = null;
@Before
public void before()
{
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));
} @Test
public void testGetDeptPost()
{
SqlSession sqlSession = ssf.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<DeptVo> deptVoList = deptMapper.getDeptPost();
for(DeptVo deptVo : deptVoList)
{
System.out.println(deptVo);
}
sqlSession.close();
}
}
2.2one-to-many查询
对表关联查询
给Users加入orders的集合属性
2.2.1定义Mapper接口
package org.guangsoft.mapper; import java.util.List; import org.guangsoft.entity.User; public interface UserMapper
{
public User loadUserOrders(Integer uid);
public List<User> loadUserOrdersDetail();
public List<User> loadUserOrdersDetail2();
}
2.2.2定义Mapper文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.guangsoft.mapper.UserMapper">
<resultMap type="org.guangsoft.entity.User" id="userOrders">
<id column="uid" property="uid" />
<result column="username" property="username"></result>
<collection property="orders" ofType="org.guangsoft.entity.Orders">
<id column="oid" property="oid" />
<result column="odate" property="odate" />
<result column="odesc" property="odesc" />
<result column="ototal" property="ototal" />
</collection>
</resultMap>
<select id="loadUserOrders" parameterType="java.lang.Integer" resultMap="userOrders">
select user.uid ,oid ,odate,ototal,odesc,username
from orders inner join user
on orders.uid = user.uid where user.uid = #{uid}
</select>
<resultMap type="org.guangsoft.entity.User" id="userOrdersDetail">
<id column="uid" property="uid" />
<result column="username" property="username" />
<collection property="orders" ofType="org.guangsoft.entity.Orders">
<id column="oid" property="oid" ></id>
<result column="odate" property="odate" ></result>
<collection property="details" ofType="org.guangsoft.entity.Detail">
<id column="did" property="did"></id>
<result column="price" property="price"></result>
<result column="pname" property="pname"></result>
<result column="cts" property="cts"></result>
</collection>
</collection>
</resultMap>
<select id="loadUserOrdersDetail" resultMap="userOrdersDetail">
select user.uid,orders.oid,username,odate,pname,price,cts
from user left join orders on user.uid=orders.uid
left join detail on orders.oid = detail.oid
</select> <select id="loadUserOrdersDetail2" resultMap="userOrdersDetail">
select user.uid,username from user
</select>
<select id="loadOrders" parameterType="java.lang.Integer" resultType="org.guangsoft.entity.Orders">
select oid,odate from orders where orders.uid=#{uid}
</select>
<select id="loadDetail" parameterType="java.lang.Integer" resultType="org.guangsoft.entity.Detail">
select pname,price,cts,odid from detail where detail.oid=#{oid}
</select>
</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开启懒加载
<!-- 开启mybatis的懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<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接口
package org.guangsoft.mapper; import java.util.List; import org.guangsoft.entity.Detail; public interface DetailMapper
{
/**
* 按照订单的编号,商品的名称,商品的数量,商品单价查询订单信息
* @return
*/
public List<Detail> loadDetail(Detail detail);
public void deleteDetails(Integer dids[]);
}
4.1.2定义Mapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.guangsoft.mapper.DetailMapper">
<sql id="cond">
<where>
<if test="pname != null"><!-- 商品名称 -->
and pname = #{pname}
</if>
<if test="price != null"><!-- 商品价格 -->
and price = #{price}
</if>
<if test="cts != null"><!-- 商品 -->
and cts = #{cts}
</if>
</where>
</sql>
<select id="loadDetail" resultType="org.guangsoft.entity.Detail">
select * from detail
<!-- 动态关联where关键字 -->
<include refid="cond"></include>
</select>
<delete id="deleteDetails" parameterType="org.guangsoft.entity.Detail">
delete from detail
<!--
collection需要遍历的集合
item集合汇总的每个元素
open第一次遍历
close最后一次遍历
separator将遍历的元素使用什么隔开
-->
<foreach collection="dids" item="did" open="where did in (" close=")"
separator=","></foreach>
</delete>
<insert id="saveDept" parameterType="org.guangsoft.entity.Dept">
insert into dept values(null,#{dname})
</insert>
</mapper>
4.1.3获得Mapper代理对象
package org.guangsoft.test; import java.util.List;
import java.util.Set; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.guangsoft.entity.Dept;
import org.guangsoft.entity.Detail;
import org.guangsoft.entity.Orders;
import org.guangsoft.entity.User;
import org.guangsoft.mapper.DeptMapper;
import org.guangsoft.mapper.DetailMapper;
import org.guangsoft.mapper.OrdersMapper;
import org.guangsoft.mapper.UserMapper;
import org.guangsoft.vo.DeptVo;
import org.junit.Before;
import org.junit.Test; public class TestDeptMapper
{
SqlSessionFactory ssf = null;
@Before
public void before()
{
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
ssf = ssfb.build(this.getClass().getClassLoader().getResourceAsStream("MyBatis.xml"));
} @Test
public void testGetDeptPost()
{
SqlSession sqlSession = ssf.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<DeptVo> deptVoList = deptMapper.getDeptPost();
for(DeptVo deptVo : deptVoList)
{
System.out.println(deptVo);
}
sqlSession.close();
} @Test
public void testSaveDept()
{
SqlSession sqlSession = ssf.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDname("danme");
deptMapper.saveDept(dept);
sqlSession.commit();
sqlSession.close();
} @Test
public void testGetUserOrders()
{
SqlSession sqlSession = ssf.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.loadUserOrders(1);
Set<Orders> ordersSet = user.getOrders();
for(Orders orders : ordersSet)
{
System.out.println(orders);
}
} @Test
public void testGetOrdersUser()
{
SqlSession sqlSession = ssf.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders orders = ordersMapper.loadOrdersUser(1);
System.out.println(orders.getUser().getUsername());
sqlSession.close();
} @Test
public void testDetail()
{
SqlSession sqlSession = ssf.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> ulist = userMapper.loadUserOrdersDetail();
for(User user : ulist)
{
Set<Orders> orders = user.getOrders();
if(orders != null)
{
for(Orders o : orders)
{
Set<Detail> details = o.getDetails();
for(Detail d : details)
{
System.out.println(d.getPname());
}
}
}
}
} @Test
public void testDetail2()
{
SqlSession sqlSession = ssf.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<User> userList = userMapper.loadUserOrdersDetail2();
for(User user : userList)
{
System.out.println(user.getUsername());
Set<Orders> orders = user.getOrders();
if(orders != null)
{
for(Orders o : orders)
{
Set<Detail> details = o.getDetails();
for(Detail d : details)
{
System.out.println(d.getPname());
}
}
}
}
}
}
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
<cache readOnly="true" type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
提供ehcache的配置文件
MyBatis之代理开发模式的更多相关文章
- MyBatis 动态代理开发
MyBatis 动态代理开发 § Mapper.xml文件中的namespace与mapper接口的类路径相同. § Mapper接口方法名和Mapper.xml中定义的每个statement的i ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
- Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...
- 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...
- java框架之MyBatis(1)-入门&动态代理开发
前言 学MyBatis的原因 1.目前最主流的持久层框架为 Hibernate 与 MyBatis,而且国内公司目前使用 Mybatis 的要比 Hibernate 要多. 2.Hibernate 学 ...
- Mybatis框架三:DAO层开发、Mapper动态代理开发
这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...
- Mybatis学习总结(二)——Mapper代理开发
一.概要 1.原始DAO开发中存在的问题:(1)DAO实现方法体中存在很多过程性代码.(2)调用SqlSession的方法(select/insert/update)需要指定Statement的id, ...
- mybatis学习 九 代理开发
1.作用: 实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql. 2.实现步骤: 2.1 创建一个接口 (1) ...
- 【转】Mybatis学习---MyBatis知识、原始Dao开发和mapper代理开发
[原文]https://www.toutiao.com/i6594610137560777223/ 一.什么是MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及 ...
随机推荐
- spark
http://www.cnblogs.com/shishanyuan/p/4723604.html?utm_source=tuicool spark presto2.0计算引擎 http://blog ...
- MSP430G2333下位机乘法运算需要注意的一个问题
背景: 最近负责为主板管理电源的电源管理模块编写软体,使用的MCU为MSP430G2333.功能上很简单,即通过板子上的硬件拨码设定,或者通过IIC与主板通信,由主板的BIOS决定开机及关机的延时供电 ...
- 关联规则之Aprior算法(购物篮分析)
0.支持度与置信度 <mahout实战>与<机器学习实战>一起该买的记录数占所有商品记录总数的比例——支持度(整体) 买了<mahout实战>与<机器学习实战 ...
- 学习javascript系列之变量
在javascript全局变量中,未加var声明的全局变量和加上var声明的全局变量是不同的,虽然都是window对象的属性. ; window.a //1 delete a //false; 通过v ...
- Javascript高级程序设计——BOM(浏览器对象模型)
BOM(浏览器对象模型),它提供了独立于内容而与浏览器窗口进行交互的对象.BOM由一系列相关的对象构成.一.window对象 window对象表示整个浏览器窗口,但不必表示其中包含的内容.W ...
- BZOJ1861——book
就是给你一摞书,然后又询问第k大,编号为x的书是第几大,然后修改书的位置 splay模板题...然而我还是不会,,,又遇到lrj的书的坑了,rj的书里没有father,顿时弄得我ask不会搞了 注意合 ...
- php预定义常量$_SERVER
1.需求 了解预定义常量$_SERVER 2.属性 $_SERVER['REQUEST_URI'] //URI 用来指定要访问的页面.例如 "/index.html" $_SERV ...
- 在c或c+程序里打印调用栈。转
在C/C++程序里打印调用栈信息 我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如 ...
- [codevs2181]田忌赛马
[codevs2181]田忌赛马 试题描述 中国古代的历史故事"田忌赛马"是为大家所熟知的.话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金 ...
- oracle with as 用法
http://blog.itpub.net/28371090/viewspace-1190141/