栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis学习笔记重点梳理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis学习笔记重点梳理

Mybatis温习笔记

  1. 如果使用注解和 XML 文件两种方式同时定义,那么 XML 方式将覆盖掉注解方式。
  2. ${}与#{}的区别

(1)#{}是参数占位符,即预编译。

解析时将传入的数据都当成一个字符串,会对传入的变量自动加一个单引号。
如:user_id = #{userId},如果传入的值是111,那么解析成sql时的值为user_id = ‘111’,如果传入的值是id,则解析成的sql为user_id = ‘id’。

(2)${}是字符串替换符,即SQL拼接。

解析时,会将传入的参数直接显示生成在sql中,且不加任何引号。
如:user_id = ${userId},如果传入的值是111,那么解析成sql时的值为user_id = 111 , 如果传入的值是id,则解析成的sql为user_id = id。

(3)用$的情况

MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。

默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName},这里MyBatis不会修改或转义字符串。

${}方式一般用于传入数据库对象,例如传入表名
Select * from ${tableName} where user_id = #{userId}

sql执行过程
(1)#{}:编译好SQL后语句再去取值
(2)${}:取值以后再去编译SQL语句

3. (重点)多对多关联关系
由于多对多的关系比较复杂,会增加理解和关联的复杂度,所以应用较少。MyBatis 没有实现多对多级联,推荐通过两个一对多级联替换多对多级联,以降低关系的复杂度,简化程序。

例如,一个订单可以有多种商品,一种商品可以对应多个订单,订单与商品就是多对多的级联关系。可以使用一个中间表(订单记录表)将多对多级联转换成两个一对多的关系。
示例
下面以订单和商品(实现“查询所有订单以及每个订单对应的商品信息”的功能)为例讲解多对多关联查询。
(1)创建数据表
创建 order(订单),product(商品)和 order_details(订单和商品中间表),SQL 语句如下。

CREATE TABLE `order` (
  `oid` int(11) NOT NULL AUTO_INCREMENT,
  `ordernum` int(25) DEFAULT NULL,
  `userId` int(11) DEFAULT NULL,
  PRIMARY KEY (`oid`),
  KEY `userId` (`userId`),
  CONSTRAINT `order_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

insert  into `order`(`oid`,`ordernum`,`userId`) values (1,20200107,1),(2,20200806,2),(3,20206702,3),(4,20200645,1),(5,20200711,2),(6,20200811,2),(7,20201422,3),(8,20201688,4),(9,NULL,5);

DROp TABLE IF EXISTS `orders_detail`;

CREATE TABLE `orders_detail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orderId` int(11) DEFAULT NULL,
  `productId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

insert  into `orders_detail`(`id`,`orderId`,`productId`) values (1,1,1),(2,1,2),(3,1,3),(4,2,3),(5,2,1),(6,3,2);

DROP TABLE IF EXISTS `product`;

CREATE TABLE `product` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) DEFAULT NULL,
  `price` double DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

insert  into `product`(`pid`,`name`,`price`) values (1,'Java教程',128),(2,'C语言教程',138),(3,'Python教程',132.35);

(2)创建持久化类
Order 类代码如下。

package net.biancheng.po;

import java.util.List;

public class Order {
    private int oid;
    private int ordernum;
    private List products;

    

    @Override
    public String toString() {
        return "Order [id=" + oid + ", ordernum=" + ordernum + ", products=" + products + "]";
    }

}

Product 类方法如下。

package net.biancheng.po;

import java.util.List;

public class Product {
    private int pid;
    private String name;
    private Double price;

    // 多对多中的一个一对多
    private List orders;

    

    @Override
    public String toString() {
        return "Product [id=" + pid + ", name=" + name + ", price=" + price + "]";
    }
}

(3)创建接口和映射文件
OrderMapper 接口代码如下。

package net.biancheng.mapper;

import java.util.List;

import net.biancheng.po.Order;

public interface OrderMapper {
    public List selectAllOrdersAndProducts();
}
OrderMapper.xml 代码如下。





    
        
        

        
            
            
            
        
    

    
    
    SELECT id,name,url,age,country
    FROM website
    WHERe name like #{pattern}

bind 元素属性如下。

  • value:对应传入实体类的某个字段,可以进行字符串拼接等特殊处理。
  • name:给对应参数取的别名。
    以上代码中的“_parameter”代表传递进来的参数,它和通配符连接后,赋给了 pattern,然后就可以在 select 语句中使用这个变量进行模糊查询,不管是 MySQL 数据库还是 Oracle 数据库都可以使用这样的语句,提高了可移植性。

7. trim标签
trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。trim 语法格式如下。


    SQL语句

trim 中属性说明如下。

  • prefix 给SQL语句拼接的前缀,为 trim 包含的内容加上前缀
  • suffix 给SQL语句拼接的后缀,为 trim 包含的内容加上后缀
  • prefixOverrides 去除 SQL 语句前面的关键字或字符,该关键字或者字符由 prefixOverrides 属性指定。
  • suffixOverrides 去除 SQL 语句后面的关键字或者字符,该关键字或者字符由 suffixOverrides 属性指定。

8. Mybatis分页原理
MyBatis 的分页功能是基于内存的分页,即先查询出所有记录,再按起始位置和页面容量取出结果;
limit #{from},#{pageSize}
例子:limit 0,10

注意:实现分页的方法中第一个参数为 limit 的起始位置(下标从 0 开始),而不是用户输入的真正页码(页码从1开始)。用户输入的页码应该转换为 limit 的起始位置下标,即:起始位置下标=(页码-1)*页面容量,那么这个转换操作必然不能在 DAO 层实现,需要在业务层实现。所以我们在测试类中传入的参数为下标,而不是页码。

9. Mybatis缓存机制
MyBatis 提供了一级缓存和二级缓存的支持。默认情况下,MyBatis 只开启一级缓存。

一级缓存
**一级缓存是基于 PerpetualCache(MyBatis自带)的 HashMap 本地缓存,作用范围为 session 域内。**当 session flush(刷新)或者 close(关闭)之后,该 session 中所有的 cache(缓存)就会被清空。

在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用同一个 mapper 的方法,往往只执行一次 SQL。因为使用 SqlSession 第一次查询后,MyBatis 会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession 会取出当前缓存的数据,而不会再次发送 SQL 到数据库。

由于 SqlSession 是相互隔离的,所以如果你使用不同的 SqlSession 对象,即使调用相同的 Mapper、参数和方法,MyBatis 还是会再次发送 SQL 到数据库执行,返回结果。

二级缓存
二级缓存是全局缓存,作用域超出 session 范围之外,可以被所有 SqlSession 共享。

一级缓存缓存的是 SQL 语句,二级缓存缓存的是结果对象。
二级缓存的配置
1)MyBatis 的全局缓存配置需要在 mybatis-config.xml 的 settings 元素中设置,代码如下。


    

2)在 mapper 文件(如 WebMapper.xml)中设置缓存,默认不开启缓存。需要注意的是,二级缓存的作用域是针对 mapper 的 namescape 而言,即只有再次在 namescape 内(net.biancheng.WebsiteMapper)的查询才能共享这个缓存,代码如下。


    
    
    ...

以上属性说明如下。
(1)eviction 代表的是缓存回收策略,目前 MyBatis 提供以下策略。

  • LRU:使用较少,移除最长时间不用的对象;
  • FIFO:先进先出,按对象进入缓存的顺序来移除它们;
  • SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象;
  • WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象。

(2)flushInterval 刷新间隔时间,单位为毫秒,这里配置的是 100 秒刷新,如果省略该配置,那么只有当 SQL 被执行的时候才会刷新缓存。
(3)size 引用数目,正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。这里配置的是 1024 个对象。
(4)readOnly 只读,默认值为 false,意味着缓存数据只能读取而不能修改,这样设置的好处是可以快速读取缓存,缺点是没有办法修改缓存。
3)在 mapper 文件配置支持 cache 后,如果需要对个别查询进行调整,可以单独设置 cache,代码如下。


对于 MyBatis 缓存仅作了解即可,因为面对一定规模的数据量,内置的 Cache 方式就派不上用场了,并且对查询结果集做缓存并不是 MyBatis 所擅长的,它专心做的应该是 SQL 映射。对于缓存,采用 OSCache、Memcached 等专门的缓存服务器来做更为合理。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/978473.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号