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之代理开发模式的更多相关文章

  1. MyBatis 动态代理开发

    MyBatis 动态代理开发 §  Mapper.xml文件中的namespace与mapper接口的类路径相同. §  Mapper接口方法名和Mapper.xml中定义的每个statement的i ...

  2. mybatis入门基础(二)----原始dao的开发和mapper代理开发

    承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...

  3. Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...

  4. 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发

    使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...

  5. java框架之MyBatis(1)-入门&动态代理开发

    前言 学MyBatis的原因 1.目前最主流的持久层框架为 Hibernate 与 MyBatis,而且国内公司目前使用 Mybatis 的要比 Hibernate 要多. 2.Hibernate 学 ...

  6. Mybatis框架三:DAO层开发、Mapper动态代理开发

    这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...

  7. Mybatis学习总结(二)——Mapper代理开发

    一.概要 1.原始DAO开发中存在的问题:(1)DAO实现方法体中存在很多过程性代码.(2)调用SqlSession的方法(select/insert/update)需要指定Statement的id, ...

  8. mybatis学习 九 代理开发

    1.作用: 实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql. 2.实现步骤: 2.1 创建一个接口 (1) ...

  9. 【转】Mybatis学习---MyBatis知识、原始Dao开发和mapper代理开发

    [原文]https://www.toutiao.com/i6594610137560777223/ 一.什么是MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及 ...

随机推荐

  1. spark

    http://www.cnblogs.com/shishanyuan/p/4723604.html?utm_source=tuicool spark presto2.0计算引擎 http://blog ...

  2. MSP430G2333下位机乘法运算需要注意的一个问题

    背景: 最近负责为主板管理电源的电源管理模块编写软体,使用的MCU为MSP430G2333.功能上很简单,即通过板子上的硬件拨码设定,或者通过IIC与主板通信,由主板的BIOS决定开机及关机的延时供电 ...

  3. 关联规则之Aprior算法(购物篮分析)

    0.支持度与置信度 <mahout实战>与<机器学习实战>一起该买的记录数占所有商品记录总数的比例——支持度(整体) 买了<mahout实战>与<机器学习实战 ...

  4. 学习javascript系列之变量

    在javascript全局变量中,未加var声明的全局变量和加上var声明的全局变量是不同的,虽然都是window对象的属性. ; window.a //1 delete a //false; 通过v ...

  5. Javascript高级程序设计——BOM(浏览器对象模型)

    BOM(浏览器对象模型),它提供了独立于内容而与浏览器窗口进行交互的对象.BOM由一系列相关的对象构成.一.window对象      window对象表示整个浏览器窗口,但不必表示其中包含的内容.W ...

  6. BZOJ1861——book

    就是给你一摞书,然后又询问第k大,编号为x的书是第几大,然后修改书的位置 splay模板题...然而我还是不会,,,又遇到lrj的书的坑了,rj的书里没有father,顿时弄得我ask不会搞了 注意合 ...

  7. php预定义常量$_SERVER

    1.需求 了解预定义常量$_SERVER 2.属性 $_SERVER['REQUEST_URI'] //URI 用来指定要访问的页面.例如 "/index.html" $_SERV ...

  8. 在c或c+程序里打印调用栈。转

    在C/C++程序里打印调用栈信息 我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如 ...

  9. [codevs2181]田忌赛马

    [codevs2181]田忌赛马 试题描述 中国古代的历史故事"田忌赛马"是为大家所熟知的.话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金 ...

  10. oracle with as 用法

    http://blog.itpub.net/28371090/viewspace-1190141/