Mybatis公司开发常用!
Mybatis核心
- 本文重点:注解开发,mybatis多表操作,动态SQL(WHERE,SET,IF,SQL—ID减少复用)
- 代码地址--https://gitee.com/zhangjzm/my-batis.git1
面向接口编程
- 真正的开发中,很多时候我们会选择面向接口编程
- 根本原因 : 解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好
关于接口的理解
- 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
- 接口的本身反映了系统设计人员对系统的抽象理解。
- 接口应有两类:
- 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
- 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
- 一个体有可能有多个抽象面。抽象体与抽象面是有区别的
三个面向区别
- 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法 .
- 面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现 .
- 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题.更多的体现就是对系统整体的架构
Mybatis详细执行流程
- 设置事务自动提交
- 虽说可以自动提交,但是有些时候出错了,他也会提交了。。。
- 工具类中
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true); // true 意味着开始事务自动提交,不写的话需手动提交
}
注解开发
所有注解底层都是通过反射机制来运行的
mybatis最初配置信息是基于 XML ,映射语句(SQL)也是定义在 XML 中的。而到MyBatis 3提供了
新的基于注解的配置。不幸的是,Java 注解的的表达力和灵活性十分有限。最强大的 MyBatis 映
射并不能用注解来构建。多表的时候。。。sql 类型主要分成 :
- @select ()
- @update ()
- @Insert ()
- @delete ()
【注意】利用注解开发就不需要resource mapper.xml映射文件了.但是需要配置class。。
注解CRUD
地址 Mybatis-05
1.使用注解开发需要改·
mybatis-config.xml
<!--绑定接口-->
`《mappers》`
`《mapper class="com.zjz.dao.UserMapper"/》`
`《/mappers》`
2.Mapper代码
入参为User时,测试时直接方法(new User(XX,XX,XX));
@Select("select * from user")
List<User> GetUsers(); // 方法存在多个参数,所有参数前面必须加@Param("X")注解
@Select("select * from user where id =#{id} AND name = #{name}")
List<User> getUserByIdName(@Param("id")int id,@Param("name")String name); @Insert("insert into user(id,name,password) values(#{id},#{name},#{password})")
int addUser(User user);
// 测试时的送参:mapper.updateUser(new User(4,"zjz4","123456")); @Update("update user set name=#{name},password=#{password} where id=#{id}")
int updateUser(User user); // 测试时的送参: mapper.updateUser(new User(4,"zjz4","123456")); @Delete("delete from user where id=#{id}")
int deleteUser(@Param("id")int id);查看
@param
源码
映射(mapper)---特别重要,不要忘记了
resource class 两种映射方式
普通方法--一个个xml绑定。
<mapper resource="com/zjz/dao/UserMapper.xml"/>
使用注解开发就需要专门绑定接口了
<mapper class="com.zjz.dao.UserMapper"/>
- 遇到的问题,resultType的pojo没解析出来
Cause: org.apache.ibatis.builder.BuilderException: Error resolving class.
Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'Student'.
Cause: java.lang.ClassNotFoundException: Cannot find class: Student
<!--起别名-->
<typeAliases>
<typeAlias type="com.zjz.pojo.BEAN" alias="BEAN"/>
</typeAliases>
或者resultType直接com.zjz.pojo.BEAN
多表连接查询
- 地址 Mybatis-06,7
多对一,一对多--怎么区分:
一种是看结果要什么?(设计思想)---要一个老师手下有多个学生? 还是要多个学生,后面有个备注(教师:---)
关键:编码的主体(因为一对多反过来就是多对一,所以主体要分清) --外键(联系)
- 核心涉及:
- 复杂的属性,我们需要单独处理 对象:association 集合:collection
- 对象用来多对一(每个人都对应这个师傅(对象)) 集合用来一对多 (一个人有多个徒弟(集合))
- 类型获取:
- 对象中 javaType="" 指定的属性类型---对象
- 集合中的泛型信息。使用ofType获取--对象
resultMap(重中之重,。)
主要作用:实现多表查询
体系图
多表连接查询——多对一
重点 association resultMap property column javaType
- association 对象
- javaType="" 指定的属性!!类型(对象)
多个学生对应一个老师 主要是看主体,外键 使用学生时多个学生的外键相同,映射一个老师
思想:子查询,联表查询
引入Teacher对象查询--毕竟每个学生后面都映射着老师
- 区别:
《association property="teacher" javaType="Teacher"》 《result property="name" column="tname"/》 《/association》
《association property="teacher" column="tid" javaType="com.pojo.Teacher" select="getTeacher"/》
--类似子查询
- pojo(此时便区分出,多个学生属于一个老师)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
private Teacher teacher; // 引入老师对象(每个学生都有老师的id)
}
public class Teacher {
private int id;
private String name;
}
- mybatis-config
《mappers》
《mapper class="com.dao.TeacherMapper"/》
《mapper class="com.dao.StudentMapper"/》
《/mappers》 - StudentMapper (查每个学生)
// 查询所有的学生信息,以及对应的老师的信息
public List<Student> getStudentList();
- StudentMapper.xml
<!--子查询 -->
《select id="getStudentList" resultMap="StudentTeacher"》
select * from student
《/select》
《resultMap id="StudentTeacher" type="com.pojo.Student"》
《result property="id" column="id"/》
《result property="name" column="name"/》
<!--
复杂的属性,我们需要单独处理 对象:association 集合:collection
javaType="" 指定的属性!!类型(对象)
-->
《association property="teacher" column="tid" javaType="com.pojo.Teacher" select="getTeacher"/》
《/resultMap》
《select id="getTeacher" resultType="com.pojo.Teacher"》
select * from teacher where id = #{id}
《/select》
类似嵌套查询 推荐使用::
- mapper.xml
<!--按照结果嵌套查询-->
《select id="getStudentList2" resultMap="StudentTeacher2"》
select s.id sid,s.name sname,t.name tname
from student s ,teacher t
where s.tid = t.id;
《/select》
<!--resultType Aliases 已经配置Student Teacher -->
《resultMap id="StudentTeacher2" type="Student"》
《result property="id" column="sid"/》
《result property="name" column="sname"/》
《association property="teacher" javaType="Teacher"》
《result property="name" column="tname"/》
《association》
《/resultMap》
结果:多对一
发现每个学生后面写的个老师,说明学生为主体。每个后面有一个老师
[Student(id=1, name=小明, teacher=Teacher(id=0, name=zjzTeacher)), Student(id=2, name=小红, teacher=Teacher(id=0, name=zjzTeacher)), Student(id=3, name=小黄, teacher=Teacher(id=0, name=zjzTeacher)), Student(id=4, name=小蓝, teacher=Teacher(id=0, name=zjzTeacher)), Student(id=5, name=小白, teacher=Teacher(id=0, name=zjzTeacher))]
总体构造及使用:
多表连接查询——多对一的查询方式
嵌套查询(链表查询)
pojo
// student的属性
public class Student {
private int id;
private String name;
private int tid;
} public class Teacher {
private int id;
private String name; // 一个老师对应多个学生
public List<Student> studentList;
}
dao
Teacher getTeacherS(@Param("tid")int id);
TeacherMapper.xml
<!--按结果嵌套查询-->
《select id="getTeacherS" resultMap="TeacherS"》
select t.name tname,t.id tid,s.id sid,s.name sname
from student s ,teacher t
where s.tid = t.id and t.id = #{tid}
《/select》
<!--typeAliases 已经配置好 Teacher Student-->
《resultMap id="TeacherS" type="Teacher"》
《result property="id" column="tid"/》
《result property="name" column="tname"/》
<!--
复杂的属性,我们需要单独处理 对象:association 集合:collection
javaType="" 指定的属性!!类型
集合中的泛型信息。使用ofType获取
-->
《collection property="studentList" ofType="Student"》
《result property="id" column="sid"/》
《result property="name" column="sname"/》
《result property="tid" column="tid"/》
《/collection》
《/resultMap》
子查询
- TeacherMapper
Teacher getTeacherS1(@Param("id")int id);
- TeacherMapper.xml
<!-- 子查询-->
《select id="getTeacherS1" resultMap="TeacherS1"》
select * from teacher where id = #{id};
《/select>
《resultMap id="TeacherS1" type="Teacher"》
<!--Teacher底下的属性,此时加id,普通查询不出来了-->
<result property="id" column="id"/》
<collection property="studentList" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/》
《/resultMap》
《select id="getStudentByTeacherId" resultType="Student" 》
select * from student where tid = #{id}
《/select》
- 结果:一个老师的集合下有5个学生
Teacher(id=1, name=zjzTeacher, studentList=[
Student(id=1, name=小明, tid=1),
Student(id=2, name=小红, tid=1),
Student(id=3, name=小黄, tid=1),
Student(id=4, name=小蓝, tid=1),
Student(id=5, name=小白, tid=1)])
- 核心体系图
关于多表总结
- 1.三个图 resultMap 多对一 一对多
- 2.保证sql的可读性
- 3.属性名(property),字段(column)
- 4.日志要用好,好找问题
- 5.复杂的多表要注意速率---慢SQL 1000s,快 1s SQL优化,引擎,InnoDB底层原理,索引,索引优化
动态SQL
定义:所谓动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
作用:非常方便的进行SQL语句拼接
关键:逻辑代码怎么操作
- 动态SQL,根据不同的条件生成不同的SQL(以前JDBC时的SQL拼接)
介绍
- 动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。
在 MyBatis 之前的版本中,有很多元素需要花时间了解。
MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。
MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
where标签
在SQL语句之下编写
<where>中间写IF啥的</where>
作用:如果没有前置元素,它会自动去掉语句中的and或or,然后作为前置元素,如果什么属性都不传,自动清除where
如果不加的话会是这样的运行,肯定报错,所以它的作用就是去掉and
select * from blog where and author = #{author}
if操作(常用)
- 代码在:mybatis-08
操作
XXXMapper中
// 查询博客IF
List<Blog> QueryBlogIF(Map map);XXXMapper.xml
《select id="QueryBlogIF" parameterType="map" resultType="Blog"》
select * from blog
《where》
《if test="title != null"》
and title = #{title}
《/if》 《if test="author != null"》
and author = #{author}
《/if》
《/where》
《/select》Test中
@Test
public void Test3(){
SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
logger.info("QueryBlogIF开始"); HashMap map = new HashMap(); map.put("title","MYTitle1"); List《Blog》 blogs = mapper.QueryBlogIF(map); for (Blog blog : blogs) {
System.out.print(blog); }
System.out.println(); logger.info("QueryBlogIF结束");
sqlSession.close();
}
choose
choose 类似于switch 比起if 它是从上到下进行的,执行一个后停止后面的
适用于优先级查询,比如VIP来了,优先买了,后来再看有没有
when---otherwise 两个小标签
当然少不了where标签
Mapper接口
// 查询博客Choose
List《Blog》 QueryBlogChoose(Map map);Mapper.xml
《select id="QueryBlogChoose" parameterType="map" resultType="Blog"》
select * from blog
《where》
《choose》
《when test="title != null"》
title = #{title}
《/when》
《when test="author != null"》
and author = #{author}
《/when》
《otherwise》
and views 》 #{views}
《/otherwise》
《/choose》
《/where》
《/select》
SET
目的:update中用啊
作用:前置SET关键字 同时删掉无关的逗号
- 注:SET中如果没,逗号是会报错的
使用
Mapper接口
// 更新博客
int updateBlog(Map map);Mapper.xml
《update id="updateBlog" parameterType="map"》
update blog
《set》
《if test="title != null"》
title = #{title},
《/if》
《if test="author != null"》
author = #{author},
《/if》
《/set》
where id = #{id}
《/update》
trim
prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。
会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。prefixOverrides 除去前面的 suffixOverrides 除去后面的
trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为
《trim prefix="WHERE" prefixOverrides="AND |OR "》
...
《/trim》《trim prefix="SET" suffixOverrides=","》
...
《/trim》
SQL片段
目的:实现代码的复用,减少重复性操作
存值的地方----
《sql id="ID"》代码《/sql》
怎么使用? ----
《include refid="ID"》《/include》
使用SQL标签抽取公共部分,
在需要使用的地方使用include标签引用即可
注意事项,最好基于单表来定义SQL片段
SQL-ID不要有WEHER标签
最好就if test-----
代码
《sql id="if-title-author"》
《if test="title != null"》
and title = #{title}
《/if》
《if test="author != null"》
and author = #{author}
《/if》
《/sql》
《select id="QueryBlogIF" parameterType="map" resultType="Blog"》
select * from blog
《where》
《include refid="if-title-author"》《/include》
《/where》
《/select》
foreach
目的:遍历一些操作,如(id=1 or id=2 or id=3)
使用:
关键字:collection item open close separator
- collection 集合名字
- item 集合中的子元素的名字
- open 以什么东西开始
- close 以什么东西结束
- separate 每执行一个item中间加什么操作--
Mapper.xml
《!--
SQL语句:select * from blog where 1=1 and (id=1 or id=2 or id=3) 我们现在传递一个万能的map,这个map中可以传递=一个集合= open close 中要注意空格的使用,如果连起来,会被视为一个整体
--》 《select id="QueryBlogForeach" parameterType="map" resultType="Blog"》
select * from blog
《where》
《foreach collection="ids" item="id" open="and (" close=")" separator="or"》
id = #{id}
《/foreach》 《/where》 《/select》测试:
@Test
public void TestQueryBlogForeach(){
SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
logger.info("QueryBlogForeach开始"); HashMap map = new HashMap(); List《Integer》 ids = new ArrayList《》(); ids.add(1);
ids.add(2);
map.put("ids",ids); List《Blog》 blogs = mapper.QueryBlogForeach(map); System.out.println(blogs.toString()); logger.info("QueryBlogForeach结束");
sqlSession.close();
}
总体构造及使用:
Mybatis公司开发常用!的更多相关文章
- java开发常用jar包介绍(转载)
jta.jar 标准JTA API必要 commons-collections.jar 集合类 必要 antlr.jar ANother Tool for Language Recognition ...
- web前端开发常用的10个高端CSS UI开源框架
web前端开发常用的10个高端CSS UI开源框架 随着人们对体验的极致追求,web页面设计也面临着新的挑战,不仅需要更人性化的设计理念,还需要设计出更酷炫的页面.作为web前端开发人员,运用开源 ...
- QQ 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件
QQ 编辑 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件.腾讯QQ支持在线聊天.视频通话.点对点断点续传文件.共享文件.网络硬盘.自定义面板.QQ邮箱等多种功 ...
- J2EE开发常用开源框架技术(转)
主要就我所了解的J2EE开发的框架或开源项目做个介绍,可以根据需求选用适当的开源组件进行开发.主要还是以Spring为核心,也总结了一些以前web开发常用的开源工具和开源类库 1持久层:1)Hiber ...
- Atitit mybatis快速开发 的sql api接口
Atitit mybatis快速开发 的sql api接口 1.1. sql模式 开发速度大大快与 映射模式1 1.2. MyBatis Mapper1 1.2.1. 代码2 1.2.2. 原理2 1 ...
- CDN公共库、前端开发常用插件一览表(VendorPluginLib)
=======================================================================================前端CDN公共库===== ...
- iOS开发-常用第三方开源框架介绍
iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...
- 设计模式之美学习(九):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
我们都知道,很多业务系统都是基于 MVC 三层架构来开发的.实际上,更确切点讲,这是一种基于贫血模型的 MVC 三层架构开发模式. 虽然这种开发模式已经成为标准的 Web 项目的开发模式,但它却违反了 ...
- Java后端开发常用工具
Java后端开发常用工具推荐: 俗话说,工欲善其事,必先利其器.不过初学时候不大建议过度依赖IDE等过多工具,这会让自己的编程基础功变得很差,比如各种语法的不熟悉,各种关键字比如synchronize ...
随机推荐
- 花1个月时间准备 面试华为,薪资和定级都谈好了却被拒,HR竟说......
说在前面,千万不要频繁跳槽. 本来华为很想去的,面试前花了一个月的时间准备,面试过程挺顺利的,也拒绝了其他的所有面试邀请,而我拒绝其他面试邀请的底气,则是之前面试过程中的良好表现,薪资和定级都谈好了. ...
- 【NLP学习其五】模型保存与载入的注意事项(记问题No module named 'model')
这是一次由于路径问题(找不到模型)引出模型保存问题的记录 最近,我试着把使用GPU训练完成的模型部署至预发布环境时出现了一个错误,以下是log节选 unpickler.load() ModuleNot ...
- 物理机安装ESXi并优化部署虚拟机
物理机配置 CPU,BIOS中启用虚拟化(VT-X) 内存和硬盘,内存尽量大.硬盘最好SSD,内存的大小和硬盘的速度直接决定了虚拟机运行的快慢 网络,至少一块千兆网卡(vSphere7.0版本以后支持 ...
- .jsp文件的使用和理解以及一些小练习和Listener监听器
什么是 jsp,它有什么用? jsp 的全换是 java server pages.Java 的服务器页面.jsp 的主要作用是代替 Servlet 程序回传 html 页面的数据.因为 Servle ...
- 003 PCI Express体系结构(三)
一.PCI总线的存储器读写总线事务 总线的基本任务是实现数据传送,将一组数据从一个设备传送到另一个设备,当然总线也可以将一个设备的数据广播到多个设备.在处理器系统中,这些数据传送都要依赖一定的规则,P ...
- 一文搞懂RPC原理
RPC原理解析 什么是RPC RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.R ...
- 计算文件的MD5值和sha256值
1.计算文件的MD5值. 1)linux系统计算 MD5值:md5sum+文件名 sha256值:sha256su+文件名 2)windows系统计算 MD5值:利用Notepad++工具计算 sha ...
- @ControllerAdvice注解(全局异常捕获)
背景 @ControllerAdvice 注解 通常用于定义@ExceptionHandler, @InitBinder和@ModelAttribute 适用于所有@RequestMapping方法的 ...
- Spring Boot Mybatis注解:@Mapper和@MapperScan
使用@Mapper注解 添加了@Mapper注解之后这个接口在编译时会生成相应的实现类,让其他的类进行引用 @Mapper public interface EmpMapper { public Li ...
- CSS定位(慕课网学习笔记)
定位模型 static自然模型 relative相对定位模型 absolute绝对定位模型 fixed固定定位模型 sticky磁铁定位模型 possition之static(默认的设置)(静态定位. ...