1、mybatis的执行原理及常用功能和标签
1.1、执行流程
1.2、核心类
SqlSessionFactory:每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或通过Java的方式构建出 SqlSessionFactory 的实例。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,建议使用单例模式或者静态单例模式。一个SqlSessionFactory对应配置文件中的一个环境(environment),如果你要使用多个数据库就配置多个环境分别对应一个SqlSessionFactory。
SqlSession:SqlSession是一个接口,它有2个实现类,分别是DefaultSqlSession(默认使用)以及SqlSessionManager。SqlSession通过内部存放的执行器(Executor)来对数据进行CRUD。此外SqlSession不是线程安全的,因为每一次操作完数据库后都要调用close对其进行关闭,官方建议通过try-finally来保证总是关闭SqlSession。
Executor:Executor(执行器)接口有两个实现类,其中BaseExecutor有三个继承类分别是BatchExecutor(重用语句并执行批量更新),ReuseExecutor(重用预处理语句prepared statements),SimpleExecutor(普通的执行器)。以上三个就是主要的Executor。通过下图可以看到Mybatis在Executor的设计上面使用了装饰者模式,我们可以用CachingExecutor来装饰前面的三个执行器目的就是用来实现缓存。
MappedStatement:MappedStatement就是用来存放我们SQL映射文件中的信息包括sql语句,输入参数,输出参数等等。一个SQL节点对应一个MappedStatement对象。
1.3、常用标签
namespace:全路径限定名(指定接口mapper的位置)
id: 必须与接口中方法名一致,才可以映射
sql:定义sql片段,重复使用
<!--sql片段-->
<sql id="brand_column">
id,brand_name as brandName,company_name as companyName,ordered,description,status
</sql>
<select id="selectAll" resultType="brand">
select
<include refid="brand_column"/>
from tb_brand
</select>
select insert delete update :查增删改
resultType resultMap:结果处理
select标签中只能使用resultType或resultMap其中之一(不能同时存在)
resultType:通常查询的结果封装到一个实体类中时使用
resultMap: 多表查询
一对一标签:association标签,一对多标签:collection标签
- 作用:可以解决查询的列名和实体类属性名不一致问题
- 例如:
- 表中的字段名:user_id
- 实体类中的属性名: id
- 使用驼峰命名映射也解决不了,需要使用resultMap或起别名
choose:选择标签,满足执行
<choose>
<when test="条件1">
//执行SQL1
</when>
<when test="条件2">
//执行SQL2
</when>
<when test="条件3">
//执行SQL3
</when>
<otherwise>
//以上条件都不满足时执行
</otherwise>
</choose>
foreach 循环 : 循环执行sql语句
<!--list是集合,id相当于临时变量-->
<!--open:sql语句以什么开头
close:sql语句以什么关闭
separator:语句中间分隔符-->
<delete id="deleteByIds" parameterType="list">
delete from student where sid in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
if where 生成动态标签where 标签去除多余and和or**
<select id="findByCondition" parameterType="map" resultType="domain.Student">
select sid,sname,birthday,sex from student
<where>
<if test="sname!=null">
and sname=#{sname}
</if>
<if test="birthday!=null">
and birthday=#{birthday}
</if>
<if test="sex!=null">
and sex=#{sex}
</if>
</where>
</select>
set:自动添加SET关键字,去除多余的逗号
1.4、常用注解
@Insert : 插入sql , 和xml insert sql语法完全一样@Select : 查询sql, 和xml select sql语法完全一样 @Update : 更新sql, 和xml update sql语法完全一样 @Delete : 删除sql, 和xml delete sql语法完全一样 @Param : 入参 @Results : 设置结果集合@Result : 结果 @ResultMap : 引用结果集合 @SelectKey : 获取最新插入id
2、说说你对dubbo的理解,他有哪些关键组件及属性
2.1、dubbo流程概述
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案Dubbo的协议是长连接、单一链接
名词解释
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方【生产者】 |
Consumer | 调用远程服务的服务消费方【消费者】 |
Registry | 服务注册与发现的注册中心【nacos】 |
Monitor | 统计服务的调用次数和调用时间的监控中心【监控出现问题不影响服务调用】 |
Container | 服务运行容器 |
调用关系说明
-
服务容器负责启动,加载,运行服务提供者。
-
服务提供者在启动时,向添加中心添加自己提供的服务。
-
服务消费者在启动时,向添加中心订阅自己所需的服务。
-
添加中心返回服务提供者地址列表给消费者,如果有变更,添加中心将基于长连接推送变更数据给消费者。
-
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
-
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
2.2、消费端服务端注解
@DubboService:属性
version:服务版本,生产者和消费者版本要一致
group:服务分组,当一个接口有多个实现类时用分组区分
delay:延迟注册服务时间,类似懒加载
timeout:远程服务调用超时时间(毫秒)
retries:远程调用重试次数,不包括第一次
connections:最大连接数
loadbalance:负载均衡策略
weight:服务权重
executes:服务提供者每服务每方法最大可并行执行请求数
@DubboReference:
version:服务版本,生产者和消费者版本要一致
group:服务分组,当一个接口有多个实现类时用分组区分
delay:延迟注册服务时间,类似懒加载
timeout:远程服务调用超时时间(毫秒)
retries:远程调用重试次数,不包括第一次
connections:最大连接数
loadbalance:负载均衡策略
weight:服务权重
check:启动时检查提供者是否存在,true报错,flase忽略
actives:每服务消费者每服务每方法最大并发调用数
2.3、协议类型
dubbo协议:
特性
缺省协议,使用基于 netty `3.2.5.Final` 和 hessian2 `3.2.1-fixed-2(Alibaba embed version)` 的 tbremoting 交互。
- 连接个数:单连接
- 连接方式:长连接
- 传输协议:TCP
- 传输方式:NIO 异步传输
- 序列化:Hessian 二进制序列化
- 适用范围:传入传出参数数据包较小(建议小于100K)消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。
- 适用场景:常规远程服务方法调用
约束
- 参数及返回值需实现 `Serializable` 接口
- 参数及返回值不能自定义实现 `List`, `Map`, `Number`, `Date`, `Calendar` 等接口,只能用 JDK 自带的实现,因为 hessian 会做特殊处理,自 定义实现类中的属性值都会丢失。
- Hessian 序列化,只传成员属性值和值的类型
rest 协议
基于标准的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的简写)实现的REST调用支持
快速入门
http协议
特性
连接个数:多连接
连接方式:短连接
传输协议:HTTP
传输方式:同步传输
序列化:表单序列化
适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
适用场景:需同时给应用程序和浏览器 JS 使用的服务。
约束
参数及返回值需符合 Bean 规范
hessian 协议
Hessian协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。
Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即:
- 提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用
- 或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。
特性
- 连接个数:多连接
- 连接方式:短连接
- 传输协议:HTTP
- 传输方式:同步传输
- 序列化:Hessian二进制序列化
- 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
- 适用场景:页面传输,文件传输,或与原生hessian服务互操作
2.4、集群容错
集群调用失败时,Dubbo 提供的容错方案,在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。
各节点关系:
-
这里的
Invoker
是Provider
的一个可调用Service
的抽象,Invoker
封装了Provider
地址及Service
接口信息 -
Directory
代表多个Invoker
,可以把它看成List<Invoker>
,但与List
不同的是,它的值可能是动态变化的,比如注册中心推送变更 -
Cluster
将Directory
中的多个Invoker
伪装成一个Invoker
,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个 -
Router
负责从多个Invoker
中按路由规则选出子集,比如读写分离,应用隔离等 -
LoadBalance
负责从多个Invoker
中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选
Failover Cluster
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2"
来设置重试次数(不含第一次)。
Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2"
来设置最大并行数。
Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
2.5、负载均衡
Random LoadBalance
-
随机,按权重设置随机概率。
-
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
-
轮询,按公约后的权重设置轮询比率。
-
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
-
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
-
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
-
一致性 Hash,相同参数的请求总是发到同一提供者。
-
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
-
缺省只对第一个参数 Hash,如果要修改,请配置
<dubbo:parameter key="hash.arguments" value="0,1" />
-
缺省用 160 份虚拟节点,如果要修改,请配置
<dubbo:parameter key="hash.nodes" value="320" />
2.6、隐式传参
通过 Dubbo 中的 Attachment 在服务消费方和提供方之间隐式传递参数
可以通过 RpcContext
上的 setAttachment
和 getAttachment
在服务消费方和提供方之间进行参数的隐式传递。
注意:path, group, version, dubbo, token, timeout 几个 key 是保留字段,请使用其它值。
3、餐掌柜中的链路如何调用的?
在开始业务开发之前,我们首先看一下系统的调用链路,以restkeeper-model-shop模块为例,其调用的时序图如下所示:
-
请求到达商家网关,会将请求路由到下层服务(服务web层),本项目中即model-shop-web(消费者)
-
在ioc容器中通过@DubboRefernce找到接口实例化对象
-
通过实例化接口找到接口的实现类,即生产者
-
通过@DubboService在IOC容器中实例化对象进行方法调用
4、文件服务是如何设计的?文件数据据表结构如何?
启动热点数据加载:
文件上传后,其内容是基本上不变的,所以项目启动时候,我们可以吧在mysql中图片信息直接缓存到redis中,当我们进行文件查询时候可以直接从redis中读取
功能设计:
所有的附件数据都存储在tab_affix中,其他业务表通过:business_id进行关联,好处:
-
集中管理附件,方便数据统计
-
同一个业务可以通过business_type可以关联多种附件
-
在上传图片时,我们可以接入第三方组件【阿里云内容安全】进行鉴黄鉴爆处理
-
图片服务抽离为微服务,提供统一:上传、下载、业务关联查询等服务
-
使用策略模式,可以对接多个存储文件
标签:02,调用,服务,提供者,门店,接口,sql,day,Hessian From: https://www.cnblogs.com/-turing/p/16610038.html