文章目录
1、缓存
缓存就是将数据暂时放在内存或者硬盘中,当查询数据时,如果缓存中有相同的数据就直接返回,而不用从数据库去读取,进而减少了应用与数据库的交互次数,这样提升了程序的执行效率。
什么时候适合缓存?
- 适合:经常查询并且不经常改变的数据,数据的正确与否对最终结果影响不大;
- 不适合:经常改变的数据,数据的正确与否对最终结果影响很大;例如:商品的库银行存款等;
MyBatis提供两种缓存:一级缓存和二级缓存
-
一级缓存:SqlSession对象级别的缓存。
- 当执行查询后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的结构是一个HashMap,不同的SqlSession的缓存区域是互相不受影响的。
- 当再次查询同样的数据,Mybatis会先去SqlSession的缓存区域中查询是否有,有的话直接拿出来用,没有则去数据库查询。
- 当SqlSession对象消失后(被flush或close),Mybatis的一级缓存也就消失了。(一级缓存默认是启动的,而且是一直存在的)
-
二级缓存:Mapper对象(Namspace)级别的缓存(也可以说是SqlSessionFactory对象级别的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存)。
- 多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
- 二级缓存Mybatis默认是关闭的,需要自己去手动配置开启或可以自己选择用哪个厂家的缓存来作为二级缓存
- 相同点:都是基于PerpetualCache 的 HashMap本地缓存,
- 不同点:一级缓存作用域为SqlSession,而二级缓存作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache,Redis,Memcache等。
2、分页
当查询的数据量非常大的时候,如果一次性查询出所有数据,那么会导致数据可读性和数据库性能极差,所以往往会使用分页进行查询,这样对数据库的压力就在可控范围内;
下面介绍MyBatis的几种分页方式:
- 原生SQL的Limit分页
- 原生Limit分页就是在编写sql语句时需要自己加上limit关键字,然后传入分页参数进行分页,例如select * from t_user limit 0,3;
- MyBatis自带的RowBounds
- Mybatis内置了一个专门处理分页的类——RowBounds,我们使用它可以轻松完成分页。
- 使用RowBounds分页我们可以不写在映射SQL中写limit关键字,到时候自动回给我们拼接。
- RowBounds分页有一点好处就是处理数据量少时还可以,但是数据量大时,就不行好用了,此时一般都会实现拦截器来完成分页。
- 自定义拦截器插件进行分页
- 自定义拦截器插件分页 需要自己定义一个类实现Interceptor接口,这个接口是Mybatis提供的。任何分页插件想要对Mybatis进行分页就必须实现Interceptor接口,包括后面PageHelper分页插件。
- 使用PageHelper插件分页
- PageHelper分页其实也是自定义拦截器方式的一种第三方实现,它内部帮助我们实现了Interceptor的功能。所以实际上我们在执行查询方法之前,PageHelper分页插件同样是对我们的 sql 进行拦截,然后对分页参数进行拼接。
3、MyBatis中的设计模式
3.1Builder模式
“将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。”
属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式和Builder模式,相对于工厂模式会产生出一个完整的产品,Builder应用于更加复杂的对象构建,甚至只会构建产品的一个部分。
3.2工厂模式
简单工厂模式:(静态工厂模式)属于类创建型模式;
在简单工厂模式中,可以根据参数的不同返回不同类的实例;简单工厂模式专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类;
3.3单例模式
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个实例称为单例类,它提供全局访问的方法;
单例模式的要点有三个:
- 某个类只能有一个实例
- 必须自行创建这个实例
- 必须自行向整个系统提供这个实例
单例模式属于对象创建型模式;
3.4代理模式
代理模式是MyBatis的核心使用的模式,正是由于代理模式,我们只需编写Mapper.java接口而不需要实现,就是由MyBatis后台帮助我们完成具体SQL的执行的。
代理模式:给某一个对象提供一个代理,并由代理对象控制对原对象的引用;
代理模式属于对象结构型模式;
代理模式包含如下角色:
- Subject:抽象主题角色
- Proxy:代理主题角色
- RealSubject:真是主题角色
3.5组合模式
组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次;
组合模式对单个对象和组合对象具有一致性,它将对象组织到树结构中可以用来描述整体与部分的关系;同时,它也模糊了简单元素和复杂元素的概念,使得客户能够像处理简单元素一样来处理复杂元素,从而使客户程序能够与复杂元素的内部结构解耦合。
在使用组合模式中需要注意一点,也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口;这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。
3.6模版方法模式
模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术。
模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本方法汇总起来的方法叫做模板方法(template method),这个设计模式的名字就是从此而来。
模板类定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
3.7适配器模式
适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
3.8装饰者模式
装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式。
3.9迭代器模式
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。