Mybatis学习笔记

再次学习Mybatis,日后,有时间会把这个文档更新,改的越来越好,然后,改成新手老手通用的文档

1、我的认识

Mybatis 是一个持久层框架,(之前 我虽然学了这个mybatis但一直 没有深入的学习,只是达到会用的程度,没有写过什么笔记,后来转jpa+hibernate和tk.mybatis),用jpa用久了之后,需要用到mybatis时候才来用的mybatis

  • mybatis永不过时
  • 经常听说人家说mybatis效率不高,可是 这几天重学mybatis我发现,mybatis对于某些细节上做的是非常不错的,虽然,这些在jpa内都可以使用注解 来做,但是,对于快捷的持久层框架来说,灵活又强大,才能使一个框架走的越远
  • 动态SQL的细节,是我最喜欢mybatis的地方,因为,使用mybatis的动态sql标签,你可以做很多,“骚操作”例如使用那些动态sql标签来简化的你的业务的冗余代码===我目前发现,框架好像都在做一件事解耦

下面是maven坐标

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

2、一个Mybatis的开始

官网其实很详细: https://mybatis.org/mybatis-3/zh/configuration.html

不过我要做的是更简单化的复习mybatis框架

package com.pipihao.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; import java.io.Serializable;
import java.util.Date; @Data
@NoArgsConstructor
@AllArgsConstructor
public class Blog implements Serializable {
private String id;
private String title;
private String author;
private Date createTime;
private int view;
}

首先是mybatis-config.xml配置文件,这个文件主要是用的配置mybatis的一些操作,例如:扫描一个xxx.xxx.mapper的包

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--对应下面 development配置信息-->
<properties resource="db.properties" />
<settings>
<!--配置日志应用-->
<setting name="logImpl" value="LOG4J"/>
<!--开启自动的大小写转换-->
<!--官网的解释:开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启缓存,默认是开启的-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!--扫描当前包下的 所有java bean 然后取成别名 Text => text 类似这样的别名,使用的时候也要可以使用text作为别名-->
<typeAliases>
<package name="com.pipihao.pojo"/>
</typeAliases>
<!--基本配置信息不作解释-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 配置mapper类,用的这个package是扫描mapper包下所有的mapper类-->
<mappers>
<package name="com.pipihao.mapper"/>
</mappers>
</configuration>

3、一个例子

首先我们得写一个XxxMapper类,下面我以BlogMapper为例

package com.pipihao.mapper;

import com.pipihao.pojo.Blog;
import org.apache.ibatis.annotations.Param; import java.util.List;
import java.util.Map; public interface BlogMapper { Blog findBlogById(int id);
}

在这个类目录的下面要配置一个BlogMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pipihao.mapper.BlogMapper">
<!--就是这一个标签二级缓存-->
<cache/>
<!--
这个resutlType指定返回值的类型,使用的是类的别名,因为我们在上面的mybatis-config.xml中配置了自动扫描
resultMap 是使用指定返回值的映射配置 id,这个在后面会讲,
!!且 resultType和resultMap不能混用,不然会报错
parameterType 是指定参数在官网表内指定了这个参数的
-->
<select id="findBlogById" resultType="blog" parameterType="int">
select * from blog where id = #{id}
</select>
</mapper>

4、配置配置解析

其实我个人觉得这个配置文件,的太多细节在这个官方文档内,而我目前主要是记录下一些 常用的

  • [ ] db.properties配置文件:properties文件的优先级大于mybatis-config.xml内 的properties的property的优先级,不过一般多是在db.properties配置好,然后在mybatis-config.xml中引入直接使用

configuration(配置)

5、配置映射

如果你的字段名和mysql的字段名都是规范的对应命名

例如: JavaBean的命名createTime ,mysql的字段命名create_time

这样则大多数不需要配置映射,只需要开在mybatis-config.xml中的setting中开启一个值即可

<settings>
<!--开启自动的大小写转换-->
<!--官网的解释:开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

希望你是使用的规范命名,不然你的代码会显得很low

如何配置映射

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pipihao.mapper.TeacherMapper"> <select id="getTeacherByid" resultMap="testName">
select * from blog where id = #{id}
</select> <!--这个id就是一个别名,用来 使用这个映射的名字而已,id的名字可以自定义,且resultMap 则可以通过这个id来使用这个映射
type是指定一个映射的严刑,目前是使用的是在mapper中配置扫描的pojo类的别名
如果为id可以使用<id>标签
property是对应类的属性名,column是对应数据库表的字段名
private String id;
private String title;
private String author;
private Date createTime;
private int view;
-->
<resultMap id="testName" type="blogs">
<id property="id" column="id"/>
<result property="author" column="author"/>
<result property="title" column="title"/>
<!--mysql建议使用规范命名-->
<result property="createTime" column="create_time"/>
<result property="view" column="view"/>
</resultMap>
</mapper>

6、日志

  • 主要是log4j 还有 配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--
这里配置的是LOG4J的名字,且setting的name不能出错,不然,很难查错
字段内更不能出现这个空格
-->
<setting name="logImpl" value="LOG4J"/>
</settings>
</configuration>

7、分页

mybatis提供了一个rowBunds分页,不过仔细看了之后,发现还不如使用mysql的分页,缺点是增加了代码量,然后该做还是要做,并没有省什么操作(这里我建议,要么使用PageHelper,要么自己做原生的分页查询)

原生分页

<select id="findBlogById" >
select * from blog where id = #{tid} limit #{page},#{rows}
</select>

RowBunds

<select id="findBlogById" >
select * from blog
</select>
RowBounds rowBounds = new RowBounds(0,2);
List<Role> rolesByrowBounds = mapper.getRolesByrowBounds(rowBounds);
System.out.println(rolesByrowBounds.size());

8、使用注解开发

主要是注解开发也可以达到跟xml配置一样的 效果,所以在以后 的开发之中,大多数使用的是注解开发,但不过,xml,永不过时

@Select @Insert @Update @Delete

public interface StudentMapper {
@Select("select * from student where id = #{sid}")
Students getStudentById(@Param("sid")int sid);
}

这个再提一下@Results 注解,这个是可以在注解实现和resultMap一样功能的注解,也可以设置id,可以复用

下面这个 是复制网上,大概知道这个有这个东西就可以了

@Results(id="groupWithUsers",
value = {
@Result(property = "groupId", column = "group_id", id = true),
@Result(property = "name", column = "name"),
@Result(property = "accountId", column = "account_id"),
@Result(property = "deleteFlag", column = "delete_Flag"),
@Result(property = "parentId", column = "parent_Id"),
@Result(property = "userList", javaType=List.class, many =@Many(select="selectUsersByGroupId"), column = "group_id")})
//查询
@Select({"select * from group where account_id=#{accountId} and delete_flag=0"})
List<Group> selectGroupWithUsers(@Param("accountId") String accountId);

9、多对一处理

<mapper namespace="com.pipihao.mapper.StudentMapper">
<select id="getStudentById" resultType="students">
select * from student where tid = #{sid}
</select>
<resultMap id="stuteac" type="students">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="teacher" select="com.pipihao.mapper.TeacherMapper.getTeacherById">
</association>
</resultMap>
</mapper>

10、一对多处理

主要还是看怎么用

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pipihao.mapper.TeacherMapper">
<select id="getTeacherById" resultMap="teacherStudent">
select * from teacher where id = #{tid}
</select> <resultMap id="teacherStudent" type="teacher">
<result column="id" property="id"/>
<result column="name" property="name"/>
<collection property="studentsList"
javaType="ArrayList"
column="id"
ofType="students" select="com.pipihao.mapper.StudentMapper.getStudentById">
</collection>
</resultMap> <select id="getTeacherByid" resultMap="teacherP">
SELECT s.id sid,s.name sname,s.tid tid,t.name tname
FROM teacher t,student s
WHERE s.tid = t.id
AND t.id = #{tid}
</select>
<resultMap id="teacherP" type="teacher">
<id property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="studentsList" ofType="students">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
</mapper>

小结:

  1. 关联-association [多对一]
  2. 集合-collection [一对多]
  3. javaType & ofType
    1. javaType 用来指定实体类中属性的类型
    2. ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
  • 注意点:

    1. 保证 Sql的可读性,尽量保证通俗易懂
    2. 注意一对多和我对一中,属性我和字段的问题
    3. 如果问题不好排查错误,可以使用日志 ,建议使用Log4j
  • 以后 要学 Mysql引擎,InnoDB底层原理, 索引 ,索引优化

11、 动态SQL

mapUnderscoreToCamelCase	是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。	true | false	False

choose我没有设置了,因为 choose是类似于一个switch case一次只会选择一个条件语句进行执行

<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pipihao.mapper.BlogMapper"> <cache/>
<insert id="sendBlog" >
insert into blog (id,title,author,create_time,view) values (
#{id},#{title},#{author},#{createTime},#{view}
);
</insert> <select id="findBlogByMap" resultType="blog" parameterType="map">
select * from blog
<where>
<include refid="ifsql"></include>
</where>
</select>
<sql id="ifsql">
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author= #{author}
</if>
</sql> <update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">title=#{title}</if>
<if test="author != null">title=#{author}</if>
</set>
where id = #{id}
</update> <select id="findBlogByList" resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="and ( " separator="or" close=")">
id = #{id}
</foreach>
</where>
</select> </mapper>

,choose,when,otherwise 这个类似switch case一次只会执行一个条件,本命的不执行

<select id="findBlogByMap" resultType="blog" parameterType="map">
select * from blog
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="author != null">
and author= #{author}
</when>
<otherwise> <!--类似default-->
AND featured = 1
</otherwise>
</choose>
</select>

trim, 可以 给SQL语句加上前缀和后缀,然后,也可以去除某些前缀或后缀

<select id="selectUsersTrim" resultMap="resultListUsers" parameterType="Users">
select * from users
<trim prefix="where" prefixOverrides="and">
<if test="name!=null">
name=#{name}
</if>
<if test="address!=null">
and address=#{address}
</if>
</trim>
</select>

foreach,可以遍历拼接sql

<select id="findBlogByList"  resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="and ( " separator="or" close=")">
id = #{id}
</foreach>
</where>
</select>
List<Blog> findBlogByList(@Param("ids")List<String> ids);

include,sql 增加mybatis的xml配置的复用性

<select id="findBlogByMap" resultType="blog" parameterType="map">
select * from blog
<where>
<include refid="ifsql"></include>
</where>
</select>
<sql id="ifsql">
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author= #{author}
</if>
</sql>

where,if 和上面的代码意义相同,只是上面的代码,在业务复杂的情况下,耦合度更低

<select id="findBlogByMap" resultType="blog" parameterType="map">
select * from blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author= #{author}
</if>
</where>
</select>

建议:

  • 先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态 SQL实现通用即可!

12、缓存

这个在上面的配置文件配置了

一级缓存

默认开启的

小结:一极缓存黑夜是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!一级缓存就相当于一个Map

二级缓存

设置名 描述 有效值 默认值
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true | false true

小结:

  • 只要开启了二级缓存,在同一个Mapper下就有效
  • 所有的数据都会先放在一级缓存中
  • 只有当会话提交,或者的时候,才会提交到二级缓存中!

小结:

  1. Mybatis相比于JPA的各种无根报错, 我倒觉得mybatis更加好用,因为我之前是重度的JPA用户,使用Mybatis不仅可以 提升自己的SQL水平,而且通过动态SQL还可以增加自己的业务水平上限
  2. Mybatis的优点:快捷、易于学习、功能强大(虽然现在有REDIS这样的极限工具)但是,mybatis还是可以使用他自带的缓存,因为 一般的小项目可能大多数都可以使用他自带的二级缓存。
  3. 且Mybatis的还是有一定的插件生态的,pagehelper,mybatis plus都是经典,相对持久层而言,如果 项目 不是特别大,我个人而言还是会优先使用 mybatis
  4. JPA的熟练度也不高,只是达到那种CRUD的水平,难一点, 的优化我也不会,以后一定会的
  5. 加个油,有错误请大佬指出,谢谢

Mybatis老手复习文档的更多相关文章

  1. Mybatis笔记三:MyBatis的API文档

    mybatis文档:http://www.mybatis.org/mybatis-3/zh/getting-started.html mybatis-spring文档:http://www.mybat ...

  2. mybatis官网文档mybatis_doc

    在平时的学习中,我们可以去参考官网的文档来学习,这个文档有中文的,方便我们去阅读,而且这里的分类很详细. 官网文档链接:http://www.mybatis.org/mybatis-3/zh/inde ...

  3. SQLServer复习文档1(with C#)

    目录: 前言 SQL Server基础准备 1.新建数据库 2.在数据中添加表 3.向表中添加数据 SQL Server与C#基础准备 实例解析 1.C#连接数据库 2.查询特定列数据 3.使用列别名 ...

  4. java Web开发基础(一)工程项目文档结构

    2013年毕业后,在深圳工作开始是用.NET ASP.NET MVC做的项目,后来公司用java来做.于是就从.NET转java了.从.NET转java不是那么的难.今天刚好是清明节放假三天,整理了j ...

  5. spring整合mybatis错误:Caused by: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 62; 文档根元素 "mapper" 必须匹配 DOCTYPE 根 "configuration"。

    运行环境:jdk1.7.0_17+tomcat 7 + spring:3.2.0 +mybatis:3.2.7+ eclipse 错误:Caused by: org.xml.sax.SAXParseE ...

  6. SpringBoot+rest接口+swagger2生成API文档+validator+mybatis+aop+国际化

    代码地址:JillWen_SpringBootDemo mybatis 1. 添加依赖: <dependency> <groupId>org.mybatis.spring.bo ...

  7. Mybatis 框架文档 超具体笔记

    1      Mybatis入门 1.1    单独使用jdbc编程问题总结 1.1.1  jdbc程序 Public static void main(String[] args) { Connec ...

  8. 基于Mybatis的Mysql数据库文档生成工具,支持生成docx(原创)

    今天不写android--也写写数据库相关的东西 -------------------- 今日老夫闲来无事,设计了一款数据库文档生成工具 眼下仅仅支持mysql 主要是生成docx的 下载链接:下载 ...

  9. MyBatis 文档 完整版

    框架技术 1.框架技术 01.是一个应用程序的半成品 02.提供可重用的公共结构 03.按一定规则组织的一组组件 2.分析优势 01.不用再考虑公共问题 02.专心的业务实现上 03.结构统一,易于学 ...

随机推荐

  1. Java实现内嵌浏览器

    创建项目 ---->   导入需要的jar ---->  代码实现 需要的jar: https://pan.baidu.com/s/1MEZ1S0LnKSMGQm24QWgmCw 代码: ...

  2. UEFI+MBR

    前言 传统情况下装系统的两种方案bios + mbr 或 uef i+ gpt but一直有一个疑问! 是否可以使用uefi + mbr 名词解释 硬盘格式 MBR分区:全称"Master ...

  3. java多版本管理

    背景 java版本的升级也比较频繁, 每年一个版本或更多 虽然java环境变量的配置无技术性可言, 但对于频繁切换也是比较枯燥的 java版本管理工具 sdkman: https://sdkman.i ...

  4. cmd运行SpringBoot的jar中文乱码

    问题: 通过以下命令启动springBoot项目后,在项目中查看日志,发现中文乱码 java -jar projectName.jar 解决 启动时添加参数-Dfile.encoding=UTF-8即 ...

  5. 初等函数——指数函数(Exponential Function)

    一般地,函数叫做指数函数,其中x是自变量,函数的定义域是R.

  6. 部署cobbler服务器

    部署cobbler服务器 1.准备环境使用nat或者仅主机模式,不要使用桥接模式,方式获取的IP不是自己的 2. 配置yum源[epel]name=epelenabled=1gpgcheck=0bas ...

  7. 重磅来袭 Vue 3.0 One Piece 正式发布

    代号为One Piece 的Vue3.0 在9月19日凌晨正式发布!! 此次vue3.0 为用户提供了全新的 composition-api 以及更小的包大小,和更好的 TypeScript 支持. ...

  8. rest_framework五大模块

    面向对象封装 面向对象封装导入 # 1.将子类共有的方法抽离形成父类方法 # 2.子类使用共有方法,使用的是父类方法 # 3.共有方法中的资源,在子类使用方法时,获取的是子类资源 class MyCl ...

  9. java面试题(一)

    1.面向对象的特征有哪些方面? - 1 - 2.访问修饰符public,private,protected,以及不写(默认)时的区别? - 1 - 3.String 是最基本的数据类型吗? - 1 - ...

  10. Nginx 配置 HTTPS 完整过程(阿里云申请免费版一年ssl证书)

    1. nginx 的 ssl 模块安装 查看 nginx 是否安装 http_ssl_module 模块. $ /usr/local/nginx/sbin/nginx -V 如果出现 configur ...