Day2 Mybatis初识(二)
mapper接口开发
传统dao的开发问题(ibatis)
方法调用:字符串易错,硬编码
mapper代理开发
a) 编写全局配置
b) 编写接口(自动根据接口和映射文件创建实现类)
c) 编写映射文件
规范:
A. 映射文件和mapper接口同包同名(批量加载映射文件)
B. 接口的全限定名称必须和mapper映射文件的namespace保持一致
C. 接口中方法名称和mapper中的标签id保持一致
D. 方法的参数类型和mapper的paramerType保持一致
E. 方法的返回值类型和mapper的resultType和resultMap保持一致
<mapper namespace="mapper.BookMapper">
<select id="queryAll" resultType="book">
select * from book
</select>
</mapper>
d) 测试
SqlSession session = MybatisUtils.getSession();
//根据mapper接口生成实现类对象
BookMapper mapper = session.getMapper(BookMapper.class);
System.out.println(mapper.queryAll());
MybatisUtils.closeSession(); //junit:单元测试
//1.加入junit的jar
//2.使用junit实现测试(@test:作为单元直接运行 @before/@after:在test之前运行 )
输入参数和输出结果
输出结果
a) resultType:
如果结果集中所有的字段和对象中属性名称一一对应则映射成功;
如果结果集中字段的名称和属性名称部分一致,则一致的部分映射成功。
如果结果集中字段的名称和属性名称都不一致,则不会创建对象。
b) 字段和属性不一致实现封装
A. 起别名
B. resultMap(实现字段和属性之间的映射)
<!-- 实现结果集和对象的映射
id:唯一标识
type:封装的对象类型
-->
<resultMap type="book" id="bookMap">
<!-- id:描述主键字段和属性之间的映射关系
column:字段
property:属性
-->
<id column="bi" property="bid"/>
<!-- result:非主键字段的映射 -->
<result column="bnam" property="bname"/>
<result column="autho" property="author"/>
<result column="pric" property="price"/>
</resultMap> <select id="queryAll" resultMap="bookMap">
select * from book
</select>
动态sql
if:
<select id="queryCombo" parameterType="book" resultType="book">
select * from book where 1 = 1
<if test="bid != 0">
and bid = #{bid}
</if>
<if test="bname != null">
and bname = #{bname}
</if>
</select> choose:
<choose>
<when test="bid != 0">
and bid = #{bid}
</when>
<otherwise>
and bname = #{bname}
</otherwise>
</choose> where
<where>
<if test="bid != 0">
and bid = #{bid}
</if>
<if test="bname != null">
and bname = #{bname}
</if>
</where> foreach:
select * from book where bid in
<!-- collection:遍历的集合
item:每一项值
open:开始
close:结束
separator:分隔符
-->
<foreach collection="list" item="bid" open="(" close=")" separator=",">
#{bid}
</foreach>
高级结果映射
1) 查询的结果集分布于多张表
2) 一对多:Role和User(查询role级联查询所有的员工信息)
<resultMap type="role" id="RoleMap">
<id column="rid" property="rid"/>
<result column="rname" property="rname"/>
<!-- collection:将结果集数据封装到集合中
property:属性
ofType:单个对象的类型
column:关联的键
-->
<collection property="users" ofType="user" column="rid">
<id column="uid" property="uid"/>
<result column="uname" property="uname"/>
<result column="rid" property="rid"/>
</collection>
</resultMap>
<select id="queryRoleAndUser" resultMap="RoleMap">
select * from role r left join `user` u on r.rid = u.rid
</select> Rolemapper.xml
<resultMap type="role" id="RoleMap2">
<id column="rid" property="rid"/>
<result column="rname" property="rname"/>
<!-- collection:将结果集数据封装到集合中
property:属性
ofType:单个对象的类型
column:关联的键
-->
<collection property="users" ofType="user" column="rid"
select="mapper.UserMapper.selectUser">
</collection>
</resultMap>
<select id="queryRoleAndUser2" resultMap="RoleMap2">
select * from role
</select>
UserMapper.xml
<select id="selectUser" resultType="user">
select * from user where rid = #{rid}
</select>
3) 一对一:查询user及其角色(user)
<resultMap type="user" id="userMap">
<id column="uid" property="uid"/>
<result column="uname" property="uname"/>
<!-- 将结果集数据封装到对象中
property:对象的属性名称
column:外键
javaType:对象的类型
-->
<association property="role" column="rid" javaType="role">
<id column="rid" property="rid"/>
<result column="rname" property="rname"/>
</association>
</resultMap>
<select id="queryUserAndRole" resultMap="userMap">
select * from user u
left join role r
on u.rid = r.rid;
</select> UserMapper:
<resultMap type="user" id="userMap2">
<id column="uid" property="uid"/>
<result column="uname" property="uname"/>
<!-- 将结果集数据封装到对象中
property:对象的属性名称
column:外键
javaType:对象的类型
-->
<association property="role" column="rid" javaType="role"
select="mapper.RoleMapper.selectRole">
</association>
</resultMap>
<select id="queryUserAndRole2" resultMap="userMap2">
select * from user
</select> RoleMapper
<select id="selectRole" resultType="role">
select * from role where rid = #{rid}
</select>
延迟加载
1) 延迟加载:按需加载(懒加载),只加载主查询,需要用到子查询信息时才去查询。
2) <collection><association>都具有延迟加载功能。但是默认关闭。
3) 需要打开延迟加载:
<settings>
<!-- 延迟加载全局开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 3.4.1以上为false,否则为true -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
缓存
一级缓存
Mybatis中的一级缓存时默认开启的。
在内存中一块区域,以类似于map方式进行数据管理。
当用户第一次查询时,会根据sql,参数,rowbounds以及statement的id生成cacheKey,先从二级缓存中获取数据,如果为空,将从一级缓存中根据生成key获取value值,如果也为空,就从数据库进行查询,然后将key和查询的结果放置到一级缓存中。
当用户再次查询时,仍旧生成cacheKey,通过key从一级缓存中获取值,如果有值此时将直接返回不再查询数据库。
一级缓存是session级别的缓存。
如果执行增删改会清空一级缓存。
二级缓存
在内存中一块区域,以类似于map方式进行数据管理。
当用户第一次查询时,会根据sql,参数,rowbounds以及statement的id生成cacheKey,先从二级缓存中获取数据,如果为空,将从一级缓存中根据生成key获取value值,如果也为空,就从数据库进行查询,然后将key和查询的结果放置到一级缓存中。
当用户再次查询时,仍旧生成cacheKey,通过key从一级缓存中获取值,如果有值此时将直接返回不再查询数据库。
如果执行增删改会清空二级缓存
二级缓存是跨session的缓存。
默认二级缓存关闭。
实体类必须序列化。
<cache>
//读取配置文件转换为流
InputStream is = Resources.getResourceAsStream("Mybatis.xml");
//创建ssf对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is); SqlSession session = ssf.openSession(true);
SqlSession session2 = ssf.openSession(true);
SqlSession session3 = ssf.openSession(true); //根据mapper接口生成实现类对象
BookMapper mapper = session.getMapper(BookMapper.class);
BookMapper mapper2 = session2.getMapper(BookMapper.class);
BookMapper mapper3 = session3.getMapper(BookMapper.class); System.out.println(mapper.queryAll());
session.close(); System.out.println(mapper2.queryAll());
session2.close(); System.out.println(mapper3.queryAll());
session3.close();
Day2 Mybatis初识(二)的更多相关文章
- MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致
MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致 使用ResultMap节点配置信息 在映射文件中 ...
- MyBatis笔记二:配置
MyBatis笔记二:配置 1.全局配置 1.properites 这个配置主要是引入我们的 properites 配置文件的: <properties resource="db.pr ...
- python day2:python 初识(二)
大纲: 一.运算符 1.算数运算符 notice: 除法运算在python2.7和python3.x 的不同 2.比较运算符 3.赋值运算符 4.逻辑运算符 5.成员运算符 二.基本数据类型和方法介绍 ...
- Day2 Spring初识(二)
Bean的实例化 bean实例化方式有3种:默认构造.静态工厂.实例工厂 默认构造 调用无参构造, 属性+setter User.java package entity; public class U ...
- (原创)mybatis学习二,spring和mybatis的融合
mybatis学习一夯实基础 上文介绍了mybatis的相关知识,这一节主要来介绍mybaits和spring的融合 一,环境搭建 1,jar包下载,下载路径为jar包 2,将包导入到java工程中 ...
- 33、mybatis(二)
第十六章回顾SQL99中的连接查询 1)内连接 2)外连接 3)自连接 第十七章回顾hibernate多表开发 1)一对一 2)一对多 3)多对多 第十八章 mybatis一对一映射[学生与身份证] ...
- mybatis(二)接口编程 、动态sql 、批量删除 、动态更新、连表查询
原理等不在赘述,这里主要通过代码展现. 在mybatis(一)基础上,新建一个dao包,并在里面编写接口,然后再在xml文件中引入接口路径,其他不变,在运用阶段将比原始方法更节约时间,因为不用再去手动 ...
- MyBatis之二:简单增删改查
这一篇在上一篇的基础上简单讲解如何进行增删改查操作. 一.在mybatis的配置文件conf.xml中注册xml与注解映射 <!-- 注册映射文件 --> <mappers> ...
- Java框架之Mybatis(二)
本文主要介绍 Mybatis(一)之后剩下的内容: 1 mybatis 中 log4j的配置 2 dao层的开发(使用mapper代理的方式) 3 mybatis的配置详解 4 输入输出映射对应的类型 ...
随机推荐
- 使用crontab调度任务
复杂的.分布式的.工作流式的调度可以通过azkaban来进行调度,除了执行调度任务之外,它还能进行定时调度.而对于简单的服务器任务,如执行一个小脚本,发送邮件等,可以使用crontab命令直接进行,在 ...
- spring事务注解失效问题
问题描述: 由于工作需要,需要在spring中配置两个数据源,有一天突然发现@Transactional注解失效 环境框架: springmvc+spring+spring jdbcTemplate ...
- C# SpinWait
其实SpinWait的code 非常简单,以前看过很多遍,但是从来都没有整理过,整理也是再次学习吧. 我们先看看SpinWait的一些评论或者注意点吧:如果等待某个条件满足需要的时间很短,而且不希望发 ...
- element-ui中使用font-awesome字体图标
element-ui提供的字体图标是很少的,所以我们需要集成其它图标来使用,nodejs的集成官方有说明,这里说明一下非nodejs开发集成图标 首先下载fontawesome,需要更改里面图标前缀, ...
- java.lang.NoSuchMethodError 报500
1. 概述 mvc项目 接口报500 localhost 错误日志 07-Jan-2019 17:12:43.664 SEVERE [catalina-exec-21] org.apache.cata ...
- UOJ#410. 【IOI2018】会议
传送门 首先可以设 \(f[l][r]\) 表示 \([l,r]\) 的答案 设 \(x\) 为区间 \([l,r]\) 的最大值的位置,那么 \(f[l][r] = min(f[l][x-1]+h[ ...
- JS中Date.parse()和Date.UTC()返回值不一致
Date.parse() 方法解析一个表示某个日期的字符串,并返回从1970-1-1 00:00:00 UTC 到该日期对象(该日期对象的UTC时间)的毫秒数,如果该字符串无法识别,或者一些情况下,包 ...
- 一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)
概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间总结一下是值得的! 本文内容脑图如下: top 命令 top 命令我想大家都挺熟悉吧! ...
- Java中的Number和Math类简单介绍
Java Number类 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等. 实例: int a = 5000; float b = 13.65 ...
- 如何查看Ext自带的API和示例
Ext是一款富客户端开发框架,它基于JavaScript.HTML和CSS开发而成,无须安装任何插件即可在常用浏览器中创建出绚丽的页面效果. 1.下载地址http://www.sencha.com/p ...