Mybatis入门:

​ Mybatis是一个非常优秀的持久层挂架(类似于Spring Data JPA).它内部封装了通过JDBC访问数据库的操作,支持定制化SQL,存储过程,高级映射

​ 在IDEA中搭建MyBatis环境:

​ 1.创建项目

​ 2.在maven中导入mybatis所依赖的jar包

<!--Mybatis依赖-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version>
</dependency>

​ 3.创建MyBatis的核心配置XML文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--在Mybatis的核心配置文件中是有先后顺序的-->
<configuration><!--指定数据库链接信息的位置--><properties resource="jdbc.properties" /><!--自定义别名--><typeAliases><!--typeAlias:定义单个别名package:自定义扫描包里面的pojo实体类,定义别名,默认别名(首字母小写)--><!--<typeAlias alias="Book" type="com.mybatis.pojo.Book"  />--><package name="com.mybatis.pojo" /></typeAliases><!--应用环境们 default默认--><environments default="development"><!--应用环境--><environment id="development"><!--事务管理器--><transactionManager type="JDBC"/><!--数据库连接池--><dataSource type="POOLED"><property name="driver" value="${mysql.driverClass}"/><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.username}"/><property name="password" value="${mysql.password}"/></dataSource></environment></environments><!--引入映射文件--><mappers><!--包扫描映射规则要求:要求接口文件名和映射文件名相同在包扫描中,需要在resources目录中创建同名同目录结构的文件,这样才能扫描映射--><package name="com.mybatis.mapper"/></mappers>
</configuration>

​ 4.创建数据库配置properties文件,实体类,mapper接口和接口SQL映射的XML文件

###连接的驱动
mysql.driverClass=com.mysql.cj.jdbc.Driver
###连接的数据库
mysql.url=jdbc:mysql://localhost:3306/servlet_zhenai?useSSL=true&serverTimezone=UTC
###用户名
mysql.username=root
###密码
mysql.password=root
package com.mybatis.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @program: vip03SSM* @description: 实体类* @author: 高天乐* @create: 2020-08-15 19:43**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {private Integer id;private String author;private String name;private String createTime;private Double price;private Integer sales;private Integer stock;
}
package com.mybatis.mapper;import org.apache.ibatis.annotations.Param;import java.util.HashMap;
import java.util.List;/*** @program: vip03SSM* @description: Book接口* @author: 高天乐* @create: 2020-08-15 19:52**/
public interface BookMapper {//查询全部List findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.BookMapper"><select id="findAll" resultType="book">select * from web_book</select>
</mapper>

​ 5.进行单元测试

MyBatis核心配置参数的设置、参数绑定

在Mybatis的核心配置文件中是有先后顺序的

<properties resource="jdbc.properties" /> 指定数据库连接信息的位置
resource:写数据库properties的配置文件
自定义别名
<typeAliases><!-- typeAlias:定义单个别名type:里对应实体类的全限定名alias:自定义别名不区分大小写--><!--<typeAlias alias="Book" type="com.mybatis.pojo.Book"  />--><!--package:定义多个别名.自定义扫描包里面的pojo实体类,定义别名,默认别名(首字母小写)name:写实体类包所在的地址--><package name="com.mybatis.pojo" />
</typeAliases>
<environments default="development"> 应用环境们  default为默认环境 包含environment
<environment id="development">  应用环境  id为唯一标识
<transactionManager type="JDBC"/>  事务管理器
<dataSource type="POOLED">  数据库连接池  type里面可写其他的数据源 如Druid
<!--引入映射文件--><mappers><!--mapper 映射单个文件--><!--<mapper resource="" />  resource里写SQL映射文件的地址 --><!--映射过个文件需要 package标签包扫描映射规则要求:要求接口文件名和映射文件名相同在包扫描中,需要在resources目录中创建同名同目录结构的文件,这样才能扫描映射--><package name="com.mybatis.mapper"/></mappers>

动态mapper

<mapper namespace="com.mybatis.mapper.BookMapper">
namespace:传递接口的映射(命名空间,对应接口类的全限定名)
mapper里的四种子节点标签 作用
select标签 对应SQL语句的查找
update标签 对应SQL语句的更新
delete标签 对应SQL语句的删除
insert标签 对应SQL语句的添加

上面四种标签里的属性的作用

属性 作用
id 唯一表示.要和接口方法名对应
parameterType 方法中参数的传递类型(多个不同类型的参数,可以不写)
resultType 方法返回值的类型(没有返回值可以不写)
useCache false:禁用二级缓存(对于变化频率较高的SQL可以使用)…默认开启
flushCache true:刷新缓存,默认就是true
resultMap 下列单独介绍

resultMap属性

指定字段与属性的对应映射关系 (当数据库中的字段和实体类中的属性映射不上时,通过resultMap来进行一一映射)

<resultMap id="baseResultMap" type="book">
id:自定义唯一标识,此id值用于对select元素resultMap属性的引用
type:表示该resultMap的映射结果类型(实体类,如果没有定义别名就写类全限定名)

resultMap里的子节点标签:

​ id标签:id标签只定义数据库表里的主键字段

​ result标签:对应数据库表里的字段

​ association标签:主要用于一对一的关联映射操作 映射到实体类的某个 "复杂类型"属性

​ collection标签:用来进行一对多的映射

总结一句话: resultMap标签中的子标记有先后顺序(将关联查询到的多条记录映射到集合中)

id标签 result标签 association标签的属性 属性介绍
id标签 column属性:对应数据库表字段 property属性:指定数据表字段名相对应的实体类属性名
result标签 column属性:对应数据库表字段 property属性:指定数据表字段名相对应的实体类属性名
association标签 column属性:对应数据库表字段 property属性:指定数据表字段名相对应的实体类属性名 javaType属性:属性的类型 对应类的全限定名或别名 (association标签里的子节点result标签和上列一样)
collection property属性:指定数据表字段名相对应的实体类属性名 ofType:指定映射的集合属性中pojo的类型

insert操作时主键自增:

insert中的属性 作用
keyColumn 指定数据库表主键的字段
keyProperty 指定数据库表字段对应的实体类属性名
userGeneratedKeys true开启主键回写(自增)
 <!--添加一条数据--><insert id="save" parameterType="book" keyColumn="id" keyProperty="id" useGeneratedKeys="true">insert into web_book(author,createTime,name,price,sales,stock) values (#{author},#{createTime},#{name},#{price},#{sales},#{stock})
</insert>

oracle不支持主键自增需要手动实现

<selectKey keyProperty="id" resultType="integer" order="AFTER">select last_insert_id()
</selectKey>

selectKey:返回主键值

keyProperty:pojo类中主键的属性名

resultType:pojo类中主键属性的类型

order:生成策略,指selectKey什么时候生成,AFTER表示之后生成

MySQL的自增原理:执行完SQL语句之后才生成

多参数查询:

​ 方法一: 根据作者和价格来进行查询默认实现

​ 接口方法

List<T> findByAuthorAndPrice(String author ,Double price);

​ 映射文件:

根据作者和价格来进行查询根据默认实现
<select id="findByAuthorAndPrice" resultType="book">select * from web_book where author=#{param1} and price=#{param2}
</select>

​ 方法一:

​ 接口方法:根据作者和价格来进行查询注解实现

List<T> findByAuthorAndPrice(@Param("author") String author , @Param("price") Double price);

​ 映射文件: 要注意–#{author}里的参数要和@Param(“author”)注解定义的参数写的一样

<!--根据作者和价格来进行查询根据注解实现-->
<select id="findByAuthorAndPrice" resultType="book">select * from web_book where author=#{author} and price=#{price}
</select>

模糊查询的两种方式

​ 方式一: 使用${}拼接SQL语句

<select id="findByLikeName" parameterType="string" resultType="student" >select * from student where user_name like '%${username}%'
</select>

​ 方式二:使用concat()

<select id="findByLikeName" parameterType="string" resultType="student" >select * from student where user_name like concat('%',#{username},'%')
</select>

SQL语句里的两种传值方式

${},#{}的区别
#{} 表示占位符,会以?号的形式显示,防止SQL注入
${} 表示SQL拼接语句,会直接显示出内容.(不安全)
提议 #{}可以防止SQL注入,尽量少用${}

区间查询:

在查询时有需求进行区间查询或在查询价格时查询比指定价格低或高的数据.在这里是不能直接是用 > < 号的.可以按以下进行书写

符号 在Mybatis SQl语句中的写法
> >
< <
>= 或 <= <![CDATA[>=]]> and <![CDATA[<=]]>
<!--根据价格排序查询-->
<select id="findByPriceOderBy" parameterType="double" resultType="book"><!--在映射文件中进行范围的查询操作:>,<是使用转译符号来表示 >:&gt; <:&lt;<![CDATA[符号]]> 定义-->select * from web_book where price &lt; #{price} order by price asc
</select>

动态SQL

1.标签 判断语句

<!--if标签的应用-->
<select id="findByStu" parameterType="string" resultType="student"><!--select * from Student where user_name=#{arg0} and password=#{arg1}-->select * from Student where 1=1<if test="userName != null and userName != ''">and user_name=#{userName}</if><if test="password != null and password != ''">and password=#{password}</if>
</select>

2. 辅助标签,主要用于SQL的拼接

​ where标签作用: 解决where 1=1 的问题

​ 如果where标签后面的字符串是以and和or开头的就移除它

<select id="findByStu1" parameterType="string" resultType="student"><!--select * from Student where user_name=#{arg0} and password=#{arg1}-->select * from Student<where><if test="userName != null and userName != ''">and user_name=#{userName}</if><if test="password != null and password != ''">and password=#{password}</if></where>
</select>

​ set标签: update student set user_name=?,password=?, where id=? 去除update拼接语句后面的最后一个逗号

<update id="updateByStu" parameterType="student">update Student<set><if test="user_name != null and user_name != ''">user_name=#{user_name},</if><if test="password != null and password != ''">password=#{password},</if></set>where id = #{id}
</update>

​ trim标签: where标签和set标签的功能都可以使用trim标签替代

​ trim里的属性:

​ prefix: 添加前缀

​ suffix: 添加后缀

​ prefixOverrides:去除前缀

​ suffixOverrides:去出后缀

<update id="updateByStu1" parameterType="student">update Student<trim prefix="set" suffixOverrides=","><if test="user_name != null and user_name != ''">user_name=#{user_name},</if><if test="password != null and password != ''">password=#{password},</if></trim>where id=#{id}
</update>

3.类似java中的switch语句,用于多条件分支判断

​ 多条件匹配的逻辑就要使用多分支判断标记
​ 特征:
​ choose标签包裹when,otherwise标签
​ 注意:choose标签中至少要有一个when标签,0个或1个otherwise标签 (当所有的when都不满足条件时,执行otherwise)

​ 需求: 查询操作
​ 1.当id有值时进行id查询
​ 2.当id没有值是进行用户名查询
​ 3.当id和用户名都没有值是,查询无结果

<select id="findByIdOrNameStu" resultType="student">select * from student<where><choose><when test="id != null and id != ''">and id = #{id}</when><when test="username != null and username != ''">and user_name = #{username}</when><otherwise>and id = -1</otherwise> <!--数据库查询空值--></choose></where>
</select>

4. 循环语句(重点掌握)

​ collection:必填属性,值为迭代循环的属性名,传递的参数类型首字母小写
​ 传递参数为Map时,collection里填 _parameter,或者使用注解@Param()指定别名
​ 列表和数组有默认的别名(list/array)
​ item:变量名,值为迭代对象中取出的每一个值
​ index:索引,如果是Map类型时,这个值为Map的key值
​ open:循环开始的字符串
​ close:循环结束的字符串
​ separator:循环的分割符

<!--多个id查询-->
<select id="selectByIds" parameterType="integer" resultType="student">select * from student where id in<foreach collection="list" open="(" close=")" separator="," item="id">#{id}</foreach>
</select>
<!--多个id删除-->
<delete id="deleteByIds" parameterType="integer">delete from student where id in<foreach collection="list" open="(" close=")" separator="," item="id">#{id}</foreach>
</delete>
<!--更新数据-->
<update id="updateByMap">update Student<set><foreach collection="_parameter" index="key" separator="," item="val">${key} = #{val}</foreach></set>where id = #{id}
</update>

5.用于构建变量

​ 其主要用于模糊查询当中

<select id="findByLikeUserName" parameterType="string" resultType="student">select * from student<where><if test="username != null and username != ''"><bind name="name" value="'%'+username+'%'" />and user_name like #{name}</if></where>
</select>

关联操作

(resultMap里的属性和子节点的属性查看上文)

一对一:

理解:在任意一方添加对方的主键作为外键

<resultMap id="baseResult" type="orders"><result column="id" property="id" /><result column="number" property="number" /><result column="createtime" property="createtime" /><result column="note" property="note" /><!--一对一--><association property="user" column="user_id" javaType="user"><result column="username" property="username" /><result column="address" property="address" /></association>
</resultMap><!--一对一查询--><select id="selectFindByIdOrder" parameterType="integer" resultMap="baseResult"><!--select * from orders where id = #{id}-->select o.*,u.username,u.address from orders oinner join t_user uon o.user_id = u.idand o.id = #{id}
</select>

一对多:

理解:在"多"的一方添加"一"的一方的主键作为外键

<resultMap id="baseResult" type="orders"><result column="id" property="id" /><result column="number" property="number" /><result column="createtime" property="createtime" /><result column="note" property="note" /><!--一对一--><association property="user" column="user_id" javaType="user"><result column="username" property="username" /><result column="address" property="address" /></association><!--一对多--><collection property="orderDetails" ofType="orderDetail"><result property="items_num" column="items_num" /><result property="items_id" column="items_id" /></collection>
</resultMap><!--多对多查询--><select id="selectOrdersAndOrderDetail" parameterType="integer" resultMap="baseResult"><!--select o.*,d.items_id,d.items_num,u.username,u.addressfrom orders as o, orderdetail as d, t_user as uwhere o.id=d.orders_idand o.user_id = u.idand o.id = #{id}-->select o.*,d.items_id,d.items_num,u.username,u.addressfrom (orders o inner join orderdetail d on o.id = d.orders_id)inner join t_user uon u.id = o.user_idand o.id = #{id}
</select>

多对多:

1:n ---- user:orders

1:n ---- orders: orderDetail

1:1 ---- orderDetail:items

n:n ---- user:items

    <resultMap id="userResult" type="user"><id property="id" column="id" /><result property="username" column="username" /><result property="address" column="address" /><collection property="orders" ofType="orders" ><result property="number" column="number" /><result property="createtime" column="createtime" /><collection property="orderDetails" ofType="orderDetail"><result property="items_id" column="items_id"/><result property="items_num" column="items_num" /><association property="items" javaType="items" ><result property="itemsName" column="itemsname" /></association></collection></collection></resultMap><select id="selectByIdOrdersAndTimes" parameterType="integer" resultMap="userResult" ><!--select o.*,d.items_id,d.items_num,d.orders_id,u.username,u.address,i.itemsnamefrom orders as o, orderdetail as d, t_user as u,items as iwhere o.id=d.orders_idand o.user_id = u.idand d.items_id = i.idand u.id = #{id}-->select o.*,d.items_id,d.items_num,d.orders_id,u.username,u.address,i.itemsnamefrom ((orders as o inner join orderdetail as d on o.id=d.orders_id)inner join t_user as u on o.user_id = u.id)inner join items as ion d.items_id = i.idand u.id = #{id}</select>

Mybatis的缓存

sqlSession.clearCahe(); //强制清除缓存

缓存中的数据(内存中)

缓存的作用:

​ 从缓存中查询,减少了服务器的请求次数,提高了查询的效率,解决了高并发系统的性能问题.

Mybatis的缓存:一级缓存/二级缓存

一级缓存:

​ 会话技术:cookie(客户端) / session(服务端)

​ mybatis的一级缓存的作用域是session(会话),

​ myBatis默认开启了一级缓存操作,并且是无法关闭的

​ 执行过程:

​ Mybatis执行查询时,首先去缓存去查找,如果能找到数据则直接返回,如果没有则执行SQL语句从数据库中查询

二级缓存:

​ Mybatis的二级缓存是Mapper级别的缓存,不同的Mapper都有一个二级缓存,不同的Mapper之间的二级缓存是互不影响的

问题:

​ Mybatis是如何区分不同的Mapper的二级缓存区域?

​ namespace(命名空间),两个Mapper相同的话存在相同的二级缓存区域里面

开启二级缓存:在MyBatis核心配置中开启
<settings><!--开启二级缓存,全局开关,这里如果是关闭状态,则在Mapper中开启也没用--><setting name="cacheEnabled" value="true"/>
</settings>

注意:

​ Mybatis二级缓存需要将查询结果映射的pojo实现序列化(Serializable)

实例类序列化的目的???

序列化就是对实例对象的状态(State 对象属性而不包括对象方法)进行通用编码(如格式化的字节码)并保存,以保证对象的完整性和可传递性。
简而言之:序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象

在开发过程中推荐:

​ Redis / Ehcache

Mybatis的分页插件(pageHelper)

在核心配置中配置

 <plugins><!--Mybatis的分页配置--><plugin interceptor="com.github.pagehelper.PageInterceptor" /></plugins>
 /*** 分页测试*/@Testpublic void findPageTest(){BookMapper mapper = sqlSession.getMapper(BookMapper.class);//PageHelper.startPage()配置分页  注意:需要先指定分页的条件,在执行查询PageHelper.startPage(2, 10);//查询数据List<Book> bookList = mapper.findPage();PageInfo<Book> pageInfo = new PageInfo(bookList,10);System.out.println("总记录数:" + pageInfo.getTotal());System.out.println("总页数:" + pageInfo.getPages());System.out.println("当前页:" + pageInfo.getPageNum());System.out.println("当前导航页码数:" + pageInfo.getNavigatePages()); // ==10,自定义了10,默认为8List<Book> pageList = pageInfo.getList();for (Book book : pageList){System.out.println(book);}}

以上为个人笔记总结,有错误或有待添加的地方请多多点评

认识MyBatis、Mybatis笔记.MyBatis的核心配置,动态Mapper,动态SQL,表的关联及分页操作和缓存理解相关推荐

  1. 【Mybatis 之应用篇】2_配置解析、属性名问题、日志、分页和注解开发

    文章目录 Mabatis 四.配置解析 1.核心配置文件 2.environments(环境配置)☆ 3.properties(属性)☆ 4.typeAliases(类型别名)☆ 5.settings ...

  2. Mybatis学习笔记——Mybatis入门

    文章目录 Mybatis入门 1.为什么要使用mybatis? 2.ORM 3.mybatis简介 4.mybatis框架 5.mybatis入门程序 5.1搭建环境 5.2 配置log4j 5.3 ...

  3. MyBatis核心源码剖析(SqlSession XML解析 Mapper executor SQL执行过程 自定义类型处理器 缓存 日志)

    MyBatis核心源码剖析 MyBatis核心源码剖析 1 MyBatis源码概述 1.1 为什么要看MyBatis框架的源码 1.2 如何深入学习MyBatis源码 1.3 源码分析的5大原则 2 ...

  4. 【Mybatis学习笔记】Mapper动态代理四项原则和注意事项

    如果使用原始的DAO,要自己对其进行实现,而如果使用Mybatis的Mapper动态代理,就可以让Mybatis自动帮你实现DAO接口. Mapper动态代理的四项原则 1.接口方法名需要与Mappe ...

  5. 笔记·mybatis核心对象和全局配置文件

    jar包官网: https://mvnrepository.com/artifact/org.mybatis 介绍: 持久化: 持久,即把数据(如内存中的对象)保存到可以永久保存的存储设备中,持久化的 ...

  6. 【MyBatis】MyBatis 核心配置综述之 ParameterHandler

    1.概述 转载:核心配置综述之 ParameterHandler MyBatis 四大核心组件我们已经了解到了两种,一个是 Executor ,它是MyBatis 解析SQL请求首先会经过的第一道关卡 ...

  7. MyBatis 核心配置综述之 Configuration详解

    颓废青年,快出来挨打! 点击上方"Java极客技术",选择"设为星标" 后台回复"java",获取Java知识体系/面试必看资料 资料会持续 ...

  8. Mybatis学习笔记-配置Log4j以便查看MyBatis操作数据库的过程

    配置Log4j 在src/main/resources中添加log4j.properties配置文件 编写测试代码 在配置中加入该SQL语句返回的结果集的封装类型 自行测试 java.sql.SQLN ...

  9. mybatis学习笔记(13)-延迟加载

    2019独角兽企业重金招聘Python工程师标准>>> mybatis学习笔记(13)-延迟加载 标签: mybatis [TOC] resultMap可以实现高级映射(使用asso ...

  10. mybatis学习笔记-02-第一个mybatis程序

    该视频为狂神说java视频配套笔记(博主自己手打223,日后做个参考223),b站连接:Mybatis最新完整教程IDEA版[通俗易懂]-02-第一个mybatis程序) 文章目录 2.第一个myba ...

最新文章

  1. 如何让li中的标签内容横向排列
  2. tomcat启动慢_Hack下mongodb jdbc driver启动慢
  3. 【微信小程序canvas】实现小程序手写板用户签名(附代码)
  4. 7.1 数据库的性质
  5. 培训是一种乐趣(3)
  6. 私有云存储 linux,搭建nextcloud私有云存储网盘
  7. Java 中的并发工具类
  8. 管理飞扬跋扈的技术部
  9. 大虾对51单片机入门的经验总结
  10. SAP License:今天你‘牺牲’了吗?
  11. 3.2 如何判断Java对象的存活
  12. 判断变量是空_python基础(二):变量的数据类型、常量、操作符、分支、循环、条件判断...
  13. php表单验证插件下载,强力推荐10款Javascript表单验证插件
  14. java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
  15. 计算机cpu风扇不转怎么办,计算机CPU风扇不转怎么办
  16. python面向对象的编程_python面向对象的编程
  17. chrome浏览器如何避免network报错:ERR_CERT_AUTHORITY_INVALID并添加为例外或继续前往
  18. 广州融媒体峰会现场直播中,BirdDog Full NDI应用有哪些优点?难点?如何解决?
  19. PHP(10):PHP读取Excel文件的记录-方法2
  20. RocketMq客户端日志参数设置

热门文章

  1. 北京市房价预测---数据收集
  2. CC2530 实现无线串口
  3. 杀毒软件已经进入空前弱智与混沌状态
  4. LOMO效果的PS Action
  5. C语言条件运算符详解
  6. 阿里云操作系统——飞天(Apsaras)
  7. java mybatis优点_mybatis优缺点是什么?有哪些优点和缺点?
  8. riot账号服务器互通吗,云顶之弈手游和PC数据互通吗账号数据同步分析
  9. 计算机也无法解的函数,XP提示“无法访问函数不正确”怎么办|XP提示“函数不正确”的四种解决方案...
  10. Openbravo开发手册