MABITIS

MABITIS框架知识点 java

一部分:框架spring

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀 持久层框架sql

MyBatis可使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。数据库

 

1. SqlMapConfig.xml,此文件做为mybatis的全局配置文件,配置了mybatis的运行环境等信息。(mapper.xml文件即sql映射文件,文件中配置了操做数据库的sql语句。编程

     此文件须要在SqlMapConfig.xml中加载。)设计模式

2经过mybatis环境等配置信息构造SqlSessionFactory即会话工厂。由会话工厂建立sqlSession即会话,操做数据库须要经过sqlSession进行。浏览器

3 mybatis底层自定义了Executor执行器接口操做数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。缓存

5Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id便是Mappedstatement的id。安全

6 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对                       preparedStatement设置参数。session

7 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor经过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程至关于jdbc编程中对结果     的解析处理过程。

 

 

二部分:Mapper代理开发

 

1、用mapper代理开发时只要写2个:

(1)mapper.xml

(2)mapper接口

2Mapper接口开发须要遵循如下规范:

(1)Mapper.xml文件中的namespace与mapper接口的类路径相同。

(2)Mapper接口方法名和Mapper.xml中定义的每一个statement的id相同。

(3)Mapper接口方法的输入参数类型和mapper.xml中定义的每一个sql 的parameterType的类型相同。

(4)Mapper接口方法的输出参数类型和mapper.xml中定义的每一个sql的resultType的类型相同。

3、代理对象内部调用selectOne()selectList()

若是mapper对象返回单个pojo对象(非集合对象)代理对象内部经过selectOne查询数据库,若是mapper方法返回集合对象,代理对象内部经过selectList查询数据库。

4mapper接口中的方法参数只能有一个是否影响系统开发,mapper接口方法参数只能有一个,

系统是否不利于维护?

回答:系统框架中,dao层的代码是被业务层公用的。mapper接口只有一个参数,可使用包装类型的pojo知足不一样的业务方法的需求。

 

<SqlMapConfig.xml全局配置文件解析见文档>

 

 

三部分:动态sql

OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。

 

 mybatis 动态SQL 语句主要有如下几类:  if  choose  trim   where  set  foreach

 if: 提供了title参数,那么就要知足title=#{title}

choose  :全部的when和otherwise条件中,只有一个会输出

trim   : 在本身包含的内容前加上某些前缀也能够在其后加上某些后缀

       prefix:前缀    prefixoverride:去掉第一个   suffixoverride:去掉最后一个逗号(也能够是其余的标记,就像是上面前缀中的and同样)  suffix:后缀

where : (主要是用来简化sql语句中where条件判断的,能智能的处理 and or 条件)

 set  :   主要用于更新时, 若是包含的语句是以逗号结束的话将会把该逗号忽略

 

<select id="dynamicForeachTest" resultType="com.mybatis.entity.User">

select * from t_user where id in

<foreach collection="list" index="index" item="item" open="(" separator=","

close=")">

#{item}

</foreach>

</select>

item表示集合中每个元素进行迭代时的别名。index指定一个名字,用于表示在迭代过程当中,每次迭代到位置。

open表示该语句以什么开始。separator表示在每次进行迭代之间以什么符号做为分隔符。

close表示以什么结束。

 

 

四部分 延迟加载

 

需求:若是查询订单而且关联查询用户信息。若是先查询订单信息便可知足要求,当咱们须要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

**延迟加载**:先从单表查询、须要时再从关联表去关联查询,大大提升数据库性能,由于查询单表要比关联查询多张表速度要快。

 

 

使用association实现延迟加载

须要定义两个mapper的方法对应的statement

<!-- 查询订单关联查询用户,用户信息按需延迟加载 的 resultMap定义 -->         第二部:查询订单,关联用户

<resultMap type="com.mybatis.entity.Orders" id="ordersUserLazyLoading">

<!--对订单信息进行映射配置 -->

<id column="id" property="id"/>

<result column="number" property="number"/>

<result column="createtime" property="createTime"/>

<!-- 实现对用户信息进行延迟加载   select:指定延迟加载须要执行的statement的id(是根据user_id查询用户信息的statement)

column:订单信息中关联用户信息查询的列,是user_id

<association property="user"  javaType="com.mybatis.entity.User"   select="findUserById"   column="user_id"/>       

</resultMap>

 

<!-- 查询订单关联用户,用户信息延迟加载 -->                                  第一步:查询订单,返回resultMap="ordersUserLazyLoading

<select id="findOrdersUserLazyLoading" resultMap="ordersUserLazyLoading">

select * from orders

</select>

<!-- 根据Id查询用户,用于测试延迟加载 -->                                     第三部,根据关联字段 user_id,查询用户信息

<select id="findUserById" parameterType="int" resultType="com.mybatis.entity.User" >

select * from t_user where id=#{id}

</select>

 

延迟加载在mybatis核心配置文件sqlMapConfig.xml中的配置

mybatis默认没有开启延迟加载,须要在SqlMapConfig.xml中setting配置。

 

mybatis核心配置文件中配置:

lazyLoadingEnabled:全局性设置懒加载。若是设为'false'(默认),则全部相关联的都会被初始化加载。    

aggressiveLazyLoading:true(默认)懒加载的对象可能被任何懒属性所有加载。false,每一个属性都按需加载。

 

延迟加载的原理:

    它的原理是,使用CGLIB建立目标对象的代理对象,当调用目标方法时,进入拦截器方法,好比调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好

的查询关联B对象的sql,把B查询上来,而后调用a.setB(b),因而a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

 

 

 

 

 

五部分 查询缓存

 

查询缓存:mybatis提供查询缓存(一级缓存和二级缓存),用于减轻数据压力,提升数据库性能。 

一级缓存(默认支持)

一级缓存是sqlSession级别的缓存。在操做数据库时须要构造sqlSession对象,在对象中有一个数据结构(HashMap),用于存储缓存数据。不一样的sqlSession之间的缓存区域(HashMap)是互不影响的。

***若是是执行两次service调用查询相同的用户信息,不走一级缓存,由于session方法结束,sqlSession就关闭,一级缓存就清空。

 

(1). 第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,若是没有,从数据库查询用户信息。获得用户信息,而后将用户信息存储到一级缓存中。

(2). 若是sqlSession去执行commit操做(执行插入、更新、删除),清空SqlSession中的一级缓存,这样作的目的为了让缓存中存储的是最新的信息,避免脏读。

(3). 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。  

 

二级缓存

 

(1). 首先开启mybatis的二级缓存。

(2). sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。

(3). 若是SqlSession3去执行相同 mapper下sql,执行commit提交,清空该 mapper下的二级缓存区域的数据。

(4). sqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,若是存在直接从缓存中取出数据。

 

二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlSession能够共享一个UserMapper的二级缓存区域。

UserMapper有一个二级缓存区域(按namespace分) ,其它mapper也有本身的二级缓存区域(按namespace分)。每个namespace的mapper都有一个二缓存区域,两个mapper的namespace

若是相同,这两个mapper执行sql查询到数据将存在相同的二级缓存区域中。

开启二级缓存

mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存

<setting name="cacheEnabled" value="true"/>

禁用二级缓存

在statement中设置useCache=false能够禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认状况是true,即该sql使用二级缓存。

<select id="findOrderListResultMap" resultMap="ordersUserMap"    useCache="false">

刷新缓存

设置statement配置中的flushCache="true" 属性,默认状况下为true即刷新缓存,若是改为false则不会刷新。使用缓存时若是手动修改数据库表中的查询数据会出现脏读。

<insert id="insertUser" parameterType="com.mybaits.entity.User"    flushCache="true">

Mybatis Cache参数

flushInterval(刷新间隔)能够被设置为任意的正整数,并且它们表明一个合理的毫秒形式的时间段。默认状况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。size(引用数目)能够被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。readOnly(只读)属性能够被设置为true或false。只读的缓存会给全部调用者返回缓存对象的相同实例。所以这些对象不能被修改。这提供了很重要的性能优点。可读写的缓存会返回缓存对象的拷贝(经过序列化)。这会慢一些,可是安全,所以默认是false

 

二级缓存应用场景

对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术下降数据库访问量,提升访问速度,业务场景好比:耗时较高的统计分析sql、电话帐单查询sql等。

实现方法以下:经过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,好比设置为30分钟、60分钟、24小时等,根据需求而定。

7、二级缓存的局限性

mybatis二级缓存对细粒度的数据级别的缓存实现很差,好比以下需求:对商品信息进行缓存,因为商品信息查询访问量大,可是要求用户每次都能查询最新的商品信息,此时若是使用mybatis的二级

缓存就没法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,由于mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将全部商品信息的缓存数据所有清空。解

决此类问题须要在业务层根据需求对数据有针对性缓存。

 

 

 

 

六部分高级映射

 

例:业务关系

 

 

 

 

 

一对一查询 :建立包装类VO

 

需求:查询订单信息,关联查询用户信息,resultType实现(resultMapXXX)

SELECT t1.*,  t2.username,t2.sex,t2.address  FROM orders t1,t_user t2  WHERE t1.user_id=t2.id

步骤: 建立各个实体类;

建立一个包装类,将查询到的信息能够所有映射到此类:OrdersCustom.java public class OrdersCustom extends Orders,全部订单信息和部分用户信息) 

建立OrdersCustomMapper.java接口,public interface OrdersCustomMapper { 

建立OrdersCustomMapper.xml和上面对应的接口名称一致,以便经过mapper接口加载配置文件  

      <!-- 查询订单,关联查询用户信息 -->

<select id="findOrdersUser" resultType="com.mybatis.entity.OrdersCustom">

<!sql语句 ;  肯定查询的主表:订单表,肯定查询的关联表:用户表。>

select t1.*,t2.username,t2.sex,t2.address from orders t1,t_user t2

where t1.user_id = t2.id

</select>

 

 

一对多查询 : mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。

需求:查询订单(关联用户)及订单明细;

orders.java类中添加List<orderDetail> orderDetails属性(上面实体已添加)。最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中.

在ordersCustomMapper.xml中添加以下代码

<!-- 查询订单(关联用户)及订单明细的resultMap -->

<resultMap type="com.mybatis.entity.Orders"  id="ordersAndOrderDetailResultMap"   extends="OrdersUserResultMap">

<collection  property="orderdetails"  ofType="com.mybatis.entity.OrderDetail">

<id column="orderdetail_id" property="id"/>

<result column="items_id" property="itemsId"/>

<result column="items_num" property="itemsNum"/>

</collection>

</resultMap>

 

statement定义

<!-- 查询订单关联查询用户及订单明细 -->

<select id="findOrdersAndOrderDetailResultMap"  resultMap="ordersAndOrderDetailResultMap">

SELECT t1.*,t2.username,t2.sex,t2.address,t3.id orderdetail_id,t3.items_id,

t3.items_num,t3.orders_id FROM orders t1,t_user t2,orderdetail t3

WHERE t1.user_id = t2.id AND t3.orders_id=t1.id

</select>

 

、在OrdersCustomMapper.java接口类中添加一个方法

/**查询订单(关联用户)以及订单明细*/

public List<OrderDetail>findOrdersAndOrderDetailResultMap();

 

多对多

使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

1association

做用:将关联查询信息映射到一个pojo对象中。

场合:为了方便查询关联信息可使用association将关联订单信息映射为用户对象的pojo属性中,好比:查询订单及关联用户信息。使用resultType没法将查询结果映射到pojo对象的pojo属性中,根据

对结果集查询遍历的须要选择使用resultType仍是resultMap。

2collection

做用:将关联查询信息映射到一个list集合中。

场合:为了方便查询遍历关联信息可使用collection将关联信息映射到list集合中,好比:查询用户权限范围模块及模块下的菜单,可以使用collection将模块映射到模块list中,将菜单列表映射到模块对象的

菜单list属性中,这样的做的目的也是方便对查询结果集进行遍历查询。若是使用resultType没法将查询结果映射到list集合中。

 

 

 

 

 

 

 

SpRING+SPEINGMVC+MABATIS  框架

 

  1. Spring用了那些设计模式?Spring注入bean的方式?对SpringIOCSpringAOP的理解?

工厂设计模式(BeanFactory 、ApplicationContext/ 代理设计模式(AOP)/ 单例设计模式(bean) /模板设计  (jdbcTemplate) /适配器模式(AOP中的加强,MVC) /包装器 /观察者…  

Spring 经过XML配置或者注解的方式来管理bean .

IoC是spring的核心,贯穿始终。所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和对象间的关系。AOP(面向方面编程),代码每每水平地散布在全部对象层次中,而与它所散布到的对象的核心功能毫无关系。将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减小系统的重复代码,下降模块间的耦合度,并有利于将来的可操做性和可维护性。

 

  1. Spring事务隔离级别和传播机制

    事务的隔离级别就是为了解决脏读、幻读、不可重复读等问题,包括DEFAULT /READ_UNCOMMITTED /READ_COMMITED  /REPEATABLE_READ  /SERLALIZABLE ,传播机制包括 PROPAGATION_REQUIRED   PROPAGATION_REQUIRES_NEW   PROPAGATION_SUPPORTS

 

  1. Mybatis的缓存机制(一级缓存和二级缓存),mybatismapper文件中的#$的区别

一级缓存是sqlSession 级别的,一级缓存默认开启;二级缓存是userMapper级别的,二级缓存须要开启,查询的实时性不高。#会给参数加上“”,防止sql注入。

 

  1. SpringMVC的流程

DispatcherServlet接收到请求后,根据对应配置文件中配置的处理器映射,找到对应的处理器映射项(HandlerMapping),根据配置的映射规则,找到对应的处理器(Handler)。接着再经过相应的HandlerAdapter处理该Handler

HandlerAdapter在对Handler进行处理以后会返 回一个ModelAndView传给DispatcherServlet, ModelAndView包含了处理结果的视图和视图中要使用的数据。

DispatcherServlet根据获得的ModelAndView中的视图对象,找到一个合适的ViewReslover(视图解析器),根据视图解析器的配置,DispatcherServlet将视图要显示的数据传给对应的视图,最后给浏览器构造一个HTTP响应。

 

  1. SpringSpringBoot的区别?  
  2. springBoot的理解

    来简化新Spring应用的初始搭建以及开发过程, 。该框架使用了特定的方式来进行配置,从而使开发人员再也不须要定义样板化的配置。

  1. RPC框架有哪些,他们的区别?

Dubbo

  1. Dubbo的使用和理解
  2. SpringCloud的使用和理解
相关文章
相关标签/搜索