0705 - ORM框架
2021-04-18 10:04:08 1 举报
AI智能生成
架构师技术栈-单体应用
作者其他创作
大纲/内容
其它框架
日志框架
作用
用于Java应用日志记录,通常保存到文件中,方便调试跟踪系统运行情况及排查问题
分类
日志门面
Apache的commons-logging
slf4j
slf4j-api-xxx.jar
jboss-logging
Hibernate依赖其作为日志记录
桥接器(适配器)
slf4j-log4j:slf4j适配log4j
slf4j-logback:slf4j适配logback
slf4j-jdk14:slf4j适配JDK提供的日志框架(JUL)
具体实现
log4j
log4j2
logback
JUL(java.util.logging)
安全框架
Shiro
主要功能
权限控制
身份认证(登录)Authentication
权限验证(授权)Authorization
会话管理
数据加密
常用的加密算法
API
当前用户(不一定是人,比如爬虫程序)Subject
安全管理器SecurityManager,shiro的核心
SecurityUtils工具类
Realm,域,从中获取用户的角色,权限信息进行身份认证
Spring Security
Spring Security基础篇
简介
Spring Security 是强大的,且容易定制的,基于Spring开发的实现认证登录与资源授权的应用安全框架
Spring Security的核心功能
Authentication:身份认证,用户登陆的验证(解决你是谁的问题)
Authorization:访问授权,授权系统资源的访问权限(解决你能干什么的问题)
安全防护,防止跨站请求,session 攻击等
HttpBasic模式登录认证
HttpBasic模式的应用场景
HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式,也可以说是最简陋的一种方式。
它的目的并不是保障登录验证的绝对安全,而是提供一种“防君子不防小人”的登录验证。
它的目的并不是保障登录验证的绝对安全,而是提供一种“防君子不防小人”的登录验证。
spring boot2.0整合Spring security
<dependency>
groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
HttpBasic登录认证模式
如果使用的Spring Boot版本为1.X版本,依赖的Security 4.X版本,那么就无需任何配置,启动项目访问则会弹出默认的httpbasic认证
使用的是spring boot2.0版本(依赖Security 5.X版本),HttpBasic不再是默认的验证模式,在spring security 5.x默认的验证模式已经是表单模式
HttpBasic模式的原理说明
首先,HttpBasic模式要求传输的用户名密码使用Base64模式进行加密。如果用户名是 "admin" ,密码是“ admin”,则将字符串"admin:admin"使用Base64编码算法加密。加密结果可能是:YWtaW46YWRtaW4=
然后,在Http请求中使用Authorization作为一个Header,“Basic YWtaW46YWRtaW4=“作为Header的值,发送给服务端。(注意这里使用Basic+空格+加密串)
服务器在收到这样的请求时,到达BasicAuthenticationFilter过滤器,将提取“ Authorization”的Header值,并使用用于验证用户身份的相同算法Base64进行解码
解码结果与登录验证的用户名密码匹配,匹配成功则可以继续过滤器后续的访问
formLogin模式登录认证
源码解析登录验证流程
自定义登录验证结果处理
session会话管理
认证授权鉴权功能深入
RBAC权限管理模型
结合真实系统讲解RBAC实现
加载动态数据进行登录与授权
动态加载资源鉴权规则
权限表达式使用方法总结
RememberMe记住我功能
退出登录功能的实现
多种图片验证码实现方案
基于session的图片验证码实现
短信验证码登录功能
.账户多次登录失败锁定
前后端分离的应用认证
详述JWT使用场景及结构安全
Spring Security-JWT实现原理
编码实现JWT认证鉴权
解决跨域访问的问题
CSRF跨站攻击防护
JWT集群应用方案
SpringSocial社交登录
OAuth2授权标准简介
SpringSocia源码分析
QQ互联注册及应用创建
实现QQ登录功能
QQ登录功能细节处理
QQ登录用户关系绑定
Spring-Security-OAuth2项目
Spring与OAuth2发展路线图
实现授权码模式认证服务器
实现其它三种模式认证服务器
AccessToken令牌的刷新
编码实现资源服务器
认证资源服务器分离
认证资源服务整合JWT
定时任务框架
Quartz
Spring Task
工作流引擎
JBPM(Java Business Process Management)
Activity
模板引擎
freemarker、velocity、thymeleaf、beetl(国产)
全文检索框架
Apache Lucene
主要功能
创建及维护索引,提供全文检索服务,支持结果排序及关键字高亮
组要组成
索引保护目录Directory
FSDirectory:索引存储在磁盘
RAMDirectory:索引存储在内存
索引文档Document
Field:StringField只索引不分词,TextFiled即索引又分词
分词器Analyzer
对于索引内容进行分词
常用分词器
简单分词器SimpleAnalyzer
标准分词器StandardAnalyzer
中文分词器:SmartChineseAnalyser、IKAnalyzer、庖丁分词器PaodingAnalyzer
索引管理器IndexWriter
负责索引文档的创建、更新、删除
查询分析器QueryParser
构造索引条件并分析
索引阅读器IndexReader
索引搜索器IndexSearcher
根据搜索条件返回匹配的结果
Compass
基础Lucene,ElasticSearch的前身
提供了Spring、Hibernate框架集成
ElasticSearch
基于Lucene,分布式的,适合于实时,大数据量的搜索场景
Apache Solr
基于Lucene,适合于常规搜索场景
利用Zookeeper进行分布式管理
Hibernate Search
集成了Hibernate、Lucene和ElasticSearch
网络编程框架
HTTP客户端
Apache HttpClient
OkHttp
网络IO框架
Netty
Mina
Hibernate-Validator 参数校验框架
Bean Validation规范的实现
Spring
ContextLoaderListener监听器
是整个Spring应用启动的关键
Spring启动过程大致如下:
1、在Servlet容器启动后,会创建一个ServletContext(整个Web应用的上下文);
2、由于ContextLoaderListener实现了ServletContextListener,因此会在ServletContext创建完成后,其中的contextInitialized方法会自动被调用;contextInitialized方法将通过ServletContext实例的getParameter()方法找到Spring配置文件位置,然后根据其中的内容为Spring创建一个根上下文(WebApplicationContext,即通常所说的IOC容器);
3、将WebApplicatonContext作为ServletContext的一个属性放进去,名称是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
1、在Servlet容器启动后,会创建一个ServletContext(整个Web应用的上下文);
2、由于ContextLoaderListener实现了ServletContextListener,因此会在ServletContext创建完成后,其中的contextInitialized方法会自动被调用;contextInitialized方法将通过ServletContext实例的getParameter()方法找到Spring配置文件位置,然后根据其中的内容为Spring创建一个根上下文(WebApplicationContext,即通常所说的IOC容器);
3、将WebApplicatonContext作为ServletContext的一个属性放进去,名称是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
Spring IOC
定义
WebApplicationContext:即Spring IOC容器,由容器创建和管理Bean,使用时直接从容器中获得
配置方式
XML配置文件
@Resource/@Autowired注解配置
Bean的作用域
Spring支持如下5种作用域(见ConfigurationBeanFactory和WebApplicationContext接口源码):
(1)singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;
(2)prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例;
(3)request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,只有在Web应用中使用Spring时,该作用域才有效;
(4)session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
(5)globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet; *context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。
(1)singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;
(2)prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例;
(3)request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,只有在Web应用中使用Spring时,该作用域才有效;
(4)session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
(5)globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet; *context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。
依赖注入的几种方式
构造注入
属性注入setter
静态工厂注入
接口注入
理解Spring IOC容器设计原理
Bean的生命周期
实例化
实例化一个Bean,也就是我们常说的new
IOC依赖注入
按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
setBeanName实现
如果这个Bean 已经实现了BeanNameAware 接口,会调用它实现的setBeanName(String)方法,
此处传递的就是Spring 配置文件中Bean 的id 值
此处传递的就是Spring 配置文件中Bean 的id 值
BeanFactoryAware实现
如果这个Bean 已经实现了BeanFactoryAware 接口,会调用它实现的setBeanFactory,
setBeanFactory(BeanFactory)传递的是Spring 工厂自身(可以用这个方式来获取其它Bean,
只需在Spring 配置文件中配置一个普通的Bean 就可以)
setBeanFactory(BeanFactory)传递的是Spring 工厂自身(可以用这个方式来获取其它Bean,
只需在Spring 配置文件中配置一个普通的Bean 就可以)
ApplicationContextAware实现
如果这个Bean 已经实现了ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入Spring 上下文(同样这个方式也
可以实现步骤4 的内容,但比4 更好,因为ApplicationContext 是BeanFactory 的子接口,
有更多的实现方法)
setApplicationContext(ApplicationContext)方法,传入Spring 上下文(同样这个方式也
可以实现步骤4 的内容,但比4 更好,因为ApplicationContext 是BeanFactory 的子接口,
有更多的实现方法)
postProcessBeforeInitialization接口实现-初始化预处理
如果这个Bean 关联了BeanPostProcessor 接口,将会调用postProcessBeforeInitialization(Object obj, String s)
方法,BeanPostProcessor 经常被用作是Bean 内容的更改,并且由于这个是在Bean 初始化结束时调用那个的方法,
也可以被应用于内存或缓存技术。
方法,BeanPostProcessor 经常被用作是Bean 内容的更改,并且由于这个是在Bean 初始化结束时调用那个的方法,
也可以被应用于内存或缓存技术。
init-method
如果Bean 在Spring 配置文件中配置了init-method 属性会自动调用其配置的初始化方法
postProcessAfterInitialization
如果这个Bean 关联了BeanPostProcessor 接口,将会调用postProcessAfterInitialization(Object obj, String s)方法。
注:以上工作完成以后就可以应用这个Bean 了,那这个Bean 是一个Singleton 的,所以一般情况下我们调用同一个id
的Bean 会是在内容地址相同的实例,当然在Spring 配置文件中也可以配置非Singleton。
注:以上工作完成以后就可以应用这个Bean 了,那这个Bean 是一个Singleton 的,所以一般情况下我们调用同一个id
的Bean 会是在内容地址相同的实例,当然在Spring 配置文件中也可以配置非Singleton。
Destroy过期清理阶段
当Bean 不再需要时,会经过清理阶段,如果Bean 实现了DisposableBean 这个接口,会调用那个其实现的destroy()方法
destroy-method子配置清理
最后,如果这个Bean 的Spring 配置中配置了destroy-method 属性,会自动调用其配置的销毁方法
-------------------------------------------------------------------------------------------------------
bean标签有两个重要的属性(init-method 和destroy-method)。用它们你可以自己定制初始化和
注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。
<bean id="" class="" init-method="初始化方法" destroy-method="销毁方法">
-------------------------------------------------------------------------------------------------------
bean标签有两个重要的属性(init-method 和destroy-method)。用它们你可以自己定制初始化和
注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。
<bean id="" class="" init-method="初始化方法" destroy-method="销毁方法">
Spring Context装载过程分析
FactoryBean与BeanFactory区别
Spring AOP
AOP两种代理方式
Spring 提供了两种方式来生成代理对象: JDKProxy 和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport
对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK 动态代理技术,否则使用Cglib 来生成代理。
对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK 动态代理技术,否则使用Cglib 来生成代理。
JDK动态代理(针对接口,代理类为其兄弟类)
JDK 动态代理主要涉及到java.lang.reflect 包中的两个类:Proxy 和InvocationHandler。
InvocationHandler 是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类
的代码,动态将横切逻辑和业务逻辑编制在一起。Proxy 利用InvocationHandler 动态创建
一个符合某一接口的实例,生成目标类的代理对象。
InvocationHandler 是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类
的代码,动态将横切逻辑和业务逻辑编制在一起。Proxy 利用InvocationHandler 动态创建
一个符合某一接口的实例,生成目标类的代理对象。
CGLIB动态代理(针对类,代理类为其子类)
CGLib 全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,
可以在运行期扩展Java 类与实现Java 接口,CGLib 封装了asm,可以再运行期动态生成新
的class。和JDK 动态代理相比较:JDK 创建代理有一个限制,就是只能为接口创建代理实例,
而对于没有通过接口定义业务方法的类,则可以通过CGLib 创建动态代理。
可以在运行期扩展Java 类与实现Java 接口,CGLib 封装了asm,可以再运行期动态生成新
的class。和JDK 动态代理相比较:JDK 创建代理有一个限制,就是只能为接口创建代理实例,
而对于没有通过接口定义业务方法的类,则可以通过CGLib 创建动态代理。
拦截器
掌握Spring AOP编程概念
AOP注解编程
@EnableAspectJAutoProxy
@Before/@After/@AfterReturning/@AfterThrowing/@Around
@Pointcut
基于Spring Aop实现应用插件机制
Spring AOP源码解析
ProxyFactory源码解析
AOP代理源码解析
连接器与织入源码解析
SPring事务控制与底层源码分析
@EnableTransactionManagement源码剖析
@Transaction源码剖析
事务管理
五大事务隔离级别
事务的隔离级别是为了防止脏读、不可重复读、幻读问题的发生。 ----------------------------------------------------------------------------------------------------------
ISOLATION_DEFAULT :使用后端数据库默认的隔离级别。
ISOLATIONREADUNCOMMITTED :允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。
ISOLATIONREADCOMMITTED :允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
ISOLATIONREPEATABLEREAD :对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
ISOLATION_SERIALIZABLE :完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。
ISOLATION_DEFAULT :使用后端数据库默认的隔离级别。
ISOLATIONREADUNCOMMITTED :允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。
ISOLATIONREADCOMMITTED :允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
ISOLATIONREPEATABLEREAD :对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
ISOLATION_SERIALIZABLE :完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。
七大事务传播属性
Spring在TransactionDefinition接口中定义了7种类型的事务传播行为,它们规定了事务方法间发生嵌套调用时事务如何进行传播。
------------------------------------------------------------------------------------------------------------
PROPAGATION_MANDATORY :表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
PROPAGATIONNESTED :表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATIONREQUIRES一样。
PROPAGATION_NEVER :表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
PROPAGATIONNOTSUPPORTED:表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
PROPAGATION_SUPPORTS :如果当前方法在一个事务中,则以事务的形式运行;如果当前不再一个事务中,那么就以非事务的形式运行。
PROPAGATIONREQUIRESNEW :表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
PROPAGATION_REQUIRES :表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。
------------------------------------------------------------------------------------------------------------
PROPAGATION_MANDATORY :表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
PROPAGATIONNESTED :表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATIONREQUIRES一样。
PROPAGATION_NEVER :表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
PROPAGATIONNOTSUPPORTED:表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
PROPAGATION_SUPPORTS :如果当前方法在一个事务中,则以事务的形式运行;如果当前不再一个事务中,那么就以非事务的形式运行。
PROPAGATIONREQUIRESNEW :表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
PROPAGATION_REQUIRES :表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。
事务管理器
核心接口PlatformTransactionManager
编程式事务
通过使用TransactionTemplate或者PlatformTransactionManager相关事务API来实现事务管理
声明式事务
XML配置<tx:advice>标签
@Transactional标签
异常回滚
只会回滚RuntimeException异常
定时任务调度Spring Task
XML配置<task:scheduler>标签
@Scheduled注解配置
异步任务
XML配置<task:executor>标签
@Async注解配置
缓存支持Spring Cache
Spring注解式开发
@Bean/@ComponentScan/@Configuration/@Conditional
@Component/@Service/@Controller/@Repository
@Lazy/@Scope/@Import/@Value/@Profile
@Autowired/@Resources/@Inject
Spring5.0 新特性
兼容Java9
响应式编程模型
响应式编程WebFlux
概念
即Spring-WebFlux模块,以Reactor库为基础,包含了对响应式Http、服务器推送事件(Server-Sent Event)和WebSocket的客户端和服务端的支持。
基于Java注解编程模型
使用方式和SpringMVC基本一样,只是使用的类型不是普通的对象,而是响应式编程中的Mono、Flux对象
Mono对象:表示单个对象,如User用法与Optional类似
Flux对象:表示一系列的对象,类似于List<User>
基于函数式编程基础
服务器端
HandlerFunction函数式接口
Mono<T extends ServerResponse> handle(ServerRequest request)方法用于处理客户端请求
RouterFunction路由接口
Mono<HandlerFunction<T enxtends ServerResponse>> route(ServerRequest request)方法用于选择处理对应请求的HandlerFunction对象并返回
客户端
使用WebClient.create方法创建客户端发起HTTP请求调用REST API和SSE(服务端推送)服务
使用WebSocketClient类的API访问WebSocket
测试
使用WebTestClient类进行测试
函数式风格的ApplicationContext
Kotlin表达式的支持
常用工具类
Goole Guava
Optional类
避免空指针
MoreObjects工具类
作为java.util.Objects类的扩展
字符串操作,如split、join等操作
Spliter、Joiner类
函数式编程
Apahce Commons
commons-beanutils包
用于处理JavaBean相关操作,最常见的就是属性复制
如BeanUtils.copyProperties()、ProperUtils.copyProperties()
commons-lang包
如:StringUtils
commons-io包
简化IO操作,如IOUtils
commons-fileupload包
处理文件上传相关操作
Spring 中的工具类
StringUtils
字符串操作
WebUtils
处理web相关操作
FileCopyUtils(文件复制)、ResourceUtils(读取文件)等
ObjectUtils
ReflectionUtils
简化反射操作
其它工具类
lombok
通过注解简化Java代码编写,使代码看起来更简洁。可以自动生成类的getter、setter、toString、hashcode、equals、构造器等
常用注解
@Getter、@Setter
为属性自动生成getter、setter方法
@NoArgsConstructor
生成无参构造器
@AllArgsConstructor
生成包含所有属性的构造器
@Data
生成getter、setter、hashcode、equals、toString方法
hutool
简介
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”
文档
https://www.hutool.cn/
Swagger
可以与Spring MVC集成为项目生成RESTful API文档,并且可以直在页面测试
MVC框架
Struts2
流程图
Struts2流程图
核心过滤器StrutsPrepareAndExecuteFilter
PrepareOperations
包括setEncodeingAndLocal、createActionContext、findActionMapping等重要操作
ExecuteOperations
包括executeStaticResourceRequest、executeAction操作
ActionMapping
包含Action的基本信息,名称、命名空间、方法名、请求参数以及返回结果Result等信息
拦截器Interceptor
intercept(ActionInvocation invocation)方法用于在调用ActionInvocation.invoke方法前后执行其它操作
控制器Action
执行ActionInvocation.invoke方法负责调用执行
值栈ValueStack
模型驱动ModelDriven
Action实现ModelDriven接口;在Action中定义实体类属性,并通过getModel方法返回
OGNL
OgnlValueStack类
其中的数据分成了两个部分:
1、root(栈结构,CompoundRoot,继承于ArrayList)
2、context(map形式,OgnlContext)
1、root(栈结构,CompoundRoot,继承于ArrayList)
2、context(map形式,OgnlContext)
OGNL表达式:#相当于调用ActionContext.getContext()方法、%用于、$引用OGNL表达式
struts2标签库
struts2标签统一使用s作为标签前缀,类似<s:property>
分类
内置标签
常用的有:<s:property>、<s:if>、<s:else>等
自定义标签
1、创建Component类,继承org.apache.struts2.components.Component类,并重写start(),end()方法;
2、创建标签类,继承org.apache.struts2.views.jsp.ComponentTagSupport类,并重写getBean()方法和populateRarams()方法;
3、在项目WEB-INF目录下创建tld文件(其中描述了标签的语法,如:标签有哪些属性,标签的属性是否支持表达式等内容))
2、创建标签类,继承org.apache.struts2.views.jsp.ComponentTagSupport类,并重写getBean()方法和populateRarams()方法;
3、在项目WEB-INF目录下创建tld文件(其中描述了标签的语法,如:标签有哪些属性,标签的属性是否支持表达式等内容))
国际化
文件上传
数据验证
Action中的input、validate方法
请求参数类型转换TypeConverter
SpringMVC
理解MVC设计思想
原理图解
SpringMVC流程图
基本组成
DispatcherServlet
找到对应请求的HandlerMapping,将请求转发给对应的HandlerAdapter
处理器映射器HandlerMapping
保存请求的URL与Handler(可以是Controller或Servlet等)的对应关系
处理器适配器HandlerAdapter
调用对应的Handler进行处理,并返回ModelAndView对象给DispatherServlet
控制器Controller
拦截器HandlerInterceptor
Handle、postHandle、afterCompletion方法
HandlerExecutionChain
负责Handler执行前后的HandlerInterceptor调用
模型视图ModelAndView、模型Model/ModelMap
视图解析器ViewResolver
将逻辑试图转为物理试图
请求参数解析和封装
RequestMappingHandlerAdapter
HandlerMethodArgumentResolver接口
HandlerMethodArgumentResolverComposite类默认定义了26个不同的参数解析器
ServletModelAttributeMethodProcessor两种情况:
1、使用@ModelAttribute注解的类型
2、自定义实体POJO:通过特定的DataBinder将请求参数绑定到实体中的属性上
1、使用@ModelAttribute注解的类型
2、自定义实体POJO:通过特定的DataBinder将请求参数绑定到实体中的属性上
其它类型的参数处理:如Map、ServletRequest、ServletResponse、Model等使用内置转换器自动转换
类型转换
Converter<S, T>接口
自定义类型转换器:实现Converter接口,并重写convert方法
ConversionService接口
方法返回值处理
HandlerMethodReturnValueHandler接口
文件上传
配置CommonsMultipartResolver文件上传解析器
MultipartFile对象作为方法参数接收
全局异常处理
实现HandlerExceptionResolver接口
使用@ControllerAdvice/@RestControllerAdvice注解
SpringMVC使用拦截器实现鉴权的原理
鉴权流程图
ORM框架
Hibernate
HQL
可以看成是面向对象的SQL,它将原生SQL中的表明和列名分别用全类名和属性名替换了
对象的三种状态
transient(瞬时状态)、persistent(持久化状态)和 detached(离线状态)
主要组成
Session:提供用户对数据操作的API
SessionFactory:创建Sesson的对象工厂
Query:负责执行数据库查询操作,支持SQL、HQL两种
缓存机制
一级缓存
基于Session的缓存
二级缓存
基于SessionFactory级别的缓存
Criteria(QBC)
多表映射
注解
JPA提供的注解
javax.persistence包下:@Id、@Column、@Entity、@Table、@OneToMany、@ManyToOne等
Hibernate增加的注解
数据库方言Dialect
HibernateTemplate
Spring对Hibernate的集成和封装,使用它可以很方便的进行数据库操作
HibernateTemplate的作用是保证session能够正确的打开和关闭,避免手工管理Session带来的问题
使用HibernateTemplate是必须进行事务管理,否则将会报错
Mybatis
组要组成
Configuration MyBatis配置信息
配置方式
XMl文件
注解
SqlSession 提供用户对数据库操作的API,完成增删查改
Executor 有SqlSession调用执行数据库操作
StatementHandler 对SQL语句进行操作
ParameterHandler 将用户传递的参数转换成JDBC Statement所需要的参数
ResultSetHandler 将JDBC返回的ResultSet结果集对象转换成List集合
TypeHandler 负责Java数据类型和JDBC数据类型之间的映射和转换
流程图
Mybatis运行流程图
Mybatis原理图
缓存机制
一级缓存原理
第一次发出一个查询sql,sql 查询结果写入sqlsession 的一级缓存中,缓存使用的数据结构是一个map。
key:MapperID+offset+limit+Sql+所有的入参
value:用户信息
同一个sqlsession 再次发出相同的sql,就从缓存中取出数据。如果两次中间出现commit 操作(修改、添加、删除),
本sqlsession 中的一级缓存区域全部清空,下次再去缓存中查询不到所以要从数据库查询,从数据库查询到再写入缓存。
key:MapperID+offset+limit+Sql+所有的入参
value:用户信息
同一个sqlsession 再次发出相同的sql,就从缓存中取出数据。如果两次中间出现commit 操作(修改、添加、删除),
本sqlsession 中的一级缓存区域全部清空,下次再去缓存中查询不到所以要从数据库查询,从数据库查询到再写入缓存。
二级缓存原理
二级缓存的范围是mapper 级别(mapper 同一个命名空间),mapper 以命名空间为单位创建缓存数据结构,结构是map。
mybatis 的二级缓存是通过CacheExecutor 实现的。CacheExecutor其实是Executor 的代理对象。所有的查询操作,在
CacheExecutor 中都会先匹配缓存中是否存在,不存在则查询数据库。
key:MapperID+offset+limit+Sql+所有的入参
具体使用需要配置:
1. Mybatis 全局配置中启用二级缓存配置
2. 在对应的Mapper.xml 中配置cache 节点
3. 在对应的select 查询节点中添加useCache=true
mybatis 的二级缓存是通过CacheExecutor 实现的。CacheExecutor其实是Executor 的代理对象。所有的查询操作,在
CacheExecutor 中都会先匹配缓存中是否存在,不存在则查询数据库。
key:MapperID+offset+limit+Sql+所有的入参
具体使用需要配置:
1. Mybatis 全局配置中启用二级缓存配置
2. 在对应的Mapper.xml 中配置cache 节点
3. 在对应的select 查询节点中添加useCache=true
什么是Mybatis
1、Mybatis 是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql 执行性能, 灵活度高。
2、MyBatis 可以使用XML 或注解来配置和映射原生信息, 将POJO 映射成数据库中的记录,避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。
3、通过xml 文件或注解的方式将要执行的各种statement 配置起来,并通过java 对象和statement 中sql 的动态参数进行映射生成最终执行的sql 语句,最后由mybatis 框架执行sql 并将结果映射为java 对象并返回。(从执行sql 到返回result 的过程)。
SQL被调用到的原理
1、读取配置文件,配置文件包含数据库连接信息和Mapper映射文件或者Mapper包路径;
2、有了这些信息就能创建SqlSessionFactory,SqlSessionFactory的生命周期是程序级,程序运行的时候建立起来,程序结束的时候消亡;
3、SqlSessionFactory建立SqlSession,目的执行sql语句,SqlSession是过程级,一个方法中建立,方法结束应该关闭;
4、当用户使用mapper.xml文件中配置的的方法时,mybatis首先会解析sql动态标签为对应数据库sql语句的形式,并将其封装进MapperStatement对象,然后通过executor将sql注入数据库执行,并返回结果;
5、将返回的结果通过映射,包装成java对象。
2、有了这些信息就能创建SqlSessionFactory,SqlSessionFactory的生命周期是程序级,程序运行的时候建立起来,程序结束的时候消亡;
3、SqlSessionFactory建立SqlSession,目的执行sql语句,SqlSession是过程级,一个方法中建立,方法结束应该关闭;
4、当用户使用mapper.xml文件中配置的的方法时,mybatis首先会解析sql动态标签为对应数据库sql语句的形式,并将其封装进MapperStatement对象,然后通过executor将sql注入数据库执行,并返回结果;
5、将返回的结果通过映射,包装成java对象。
MyBatis的好处是什么
1)MyBatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的维护带来了很大便利。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)MyBatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,大大简化了Java数据库编程的重复工作。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3)因为MyBatis需要程序员自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,因此能够实现比Hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)MyBatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,大大简化了Java数据库编程的重复工作。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3)因为MyBatis需要程序员自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,因此能够实现比Hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。
MyBatis的缺点是什么
1、SQL 语句的编写工作量较大,尤其当字段多、关联表多时, 对开发人员编写SQL 语句的功底有一定要求。
2、SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
2、SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
MyBatis的适用场景
1、MyBatis 专注于SQL 本身,是一个足够灵活的DAO 层解决方案。
2、对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。
2、对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。
MyBatis与Hibernate有哪些不同
1、Mybatis 和hibernate 不同,它不完全是一个ORM 框架,因为MyBatis 需要程序员自己编写Sql 语句。
2、Mybatis 直接编写原生态sql,可以严格控制sql 执行性能,灵活度高, 非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁, 一但需求变化要求迅速输出成果。但是灵活的前提是mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql 映射文件,工作量大。
3、Hibernate 对象/关系映射能力强, 数据库无关性好, 对于关系模型要求高的软件,如果用hibernate 开发可以节省很多代码,提高效率。
2、Mybatis 直接编写原生态sql,可以严格控制sql 执行性能,灵活度高, 非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁, 一但需求变化要求迅速输出成果。但是灵活的前提是mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql 映射文件,工作量大。
3、Hibernate 对象/关系映射能力强, 数据库无关性好, 对于关系模型要求高的软件,如果用hibernate 开发可以节省很多代码,提高效率。
#{}和${}的区别是什么
1)#{}是预编译处理,${}是字符串替换。
2)Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
3)Mybatis在处理${}时,就是把${}替换成变量的值。
4)使用#{}可以有效的防止SQL注入,提高系统安全性。
2)Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
3)Mybatis在处理${}时,就是把${}替换成变量的值。
4)使用#{}可以有效的防止SQL注入,提高系统安全性。
当实体类中的属性名和表中的字段名不一样,怎么办
第1 种: 通过在查询的sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id=”selectorder” parametertype=”int” resultetype=me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>
第2 种: 通过<resultMap>来映射字段名和实体类属性名的一一对应的关系。
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用id 属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result 属性来映射非主键字段,property 为实体类属性名,column为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
<!–用id 属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result 属性来映射非主键字段,property 为实体类属性名,column为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
模糊查询like 语句该怎么写
第1 种: 在Java 代码中添加sql 通配符。String value = "%smi%"; select * from foo where bar like #{value}
第2 种: 在sql 语句中拼接通配符,会引起sql 注入。String value = "smi"; select * from foo where bar like "%"#{value}"%"
什么是MyBatis的接口绑定,有什么好处?
接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们通过直接调用接口方法 例如:
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)就可以,这样比起原来了SqlSession提供的方法,
例如List<Country> countryList = sqlSession.selectList("selectAll");我们可以有更加灵活的选择和设置
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:
(1)Mapper.xml文件的namespace属性必须配置为接口的全限定名称,接口方法名与Mapper.xml中的<select><insert>id值必须相同,且接口方法的返回值类型必须与Mapper.xml配置的resultType一致,这里后者起到决定作用。
(2)select查询通过在Mapper.xml中配置ResultMap标签,将查询结果的列名与字段名对应。
(3)Mapper.xml接口绑定本质是动态代理。
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)就可以,这样比起原来了SqlSession提供的方法,
例如List<Country> countryList = sqlSession.selectList("selectAll");我们可以有更加灵活的选择和设置
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:
(1)Mapper.xml文件的namespace属性必须配置为接口的全限定名称,接口方法名与Mapper.xml中的<select><insert>id值必须相同,且接口方法的返回值类型必须与Mapper.xml配置的resultType一致,这里后者起到决定作用。
(2)select查询通过在Mapper.xml中配置ResultMap标签,将查询结果的列名与字段名对应。
(3)Mapper.xml接口绑定本质是动态代理。
接口绑定有两种实现方式:
------------------------------------------------------------------------------------------------------------------------------------------
1)注解绑定:就是在接口的方法上面@Select@Update等注解里面包含Sql语句来绑定;
2)另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。
------------------------------------------------------------------------------------------------------------------------------------------
1)注解绑定:就是在接口的方法上面@Select@Update等注解里面包含Sql语句来绑定;
2)另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。
什么情况下用注解绑定,什么情况下用xml绑定?
------------------------------------------------------------------------------------------------
1)当Sql语句比较简单时候,用注解绑定;
2)当Sql语句比较复杂时候,用xml绑定,一般用xml绑定的比较多
------------------------------------------------------------------------------------------------
1)当Sql语句比较简单时候,用注解绑定;
2)当Sql语句比较复杂时候,用xml绑定,一般用xml绑定的比较多
Mybatis如何分页,实现原理是什么
Mybatis 使用RowBounds 对象进行分页,它是针对ResultSet 结果集执行的内存分页,而非物理分页。可以在sql 内直接书写带有物理分页的参数来完成物理分页功能, 也可以使用分页插件来完成物理分页。
实现原理
实现Mybatis提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,1
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,1
分页插件:PageHelper
据说在PageHelper之前的mybatis都是逻辑上的分页;PageHelper出来之后彻底实现了mybatis的物理分页
实现原理:就是在StatementHandler之前进行拦截,对MappedStatement进行一系列的操作(大致就是拼上分页sql)
Mybatis 是如何进行结果封装的
第一种:是使用<resultMap>标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种:是使用sql 列的别名功能,将列的别名书写为对象属性名。有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性, 是无法完成赋值的。
第二种:是使用sql 列的别名功能,将列的别名书写为对象属性名。有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性, 是无法完成赋值的。
如何执行批量插入
// 注意这里executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
如何获取自动生成的(主)键值
insert 方法总是返回一个int 值,这个值代表的是插入的行数。
如果采用自增长策略,自动生成的键值在insert 方法执行完后可以被设置到传入的参数对象中。
示例:
<insert id="insertname" usegeneratedkeys="true" keyproperty="id">
insert into names (name) values (#{name})
</insert>
如果采用自增长策略,自动生成的键值在insert 方法执行完后可以被设置到传入的参数对象中。
示例:
<insert id="insertname" usegeneratedkeys="true" keyproperty="id">
insert into names (name) values (#{name})
</insert>
在mapper 中如何传递多个参数
1、第一种:DAO 层的函数
public UserselectUser(String name,String area);
对应的xml,#{0}代表接收的是dao 层中的第一个参数,#{1}代表dao 层中第二参数,更多参数一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap">
select * from user_user_t where user_name = #{0} and user_area=#{1}
</select>
对应的xml,#{0}代表接收的是dao 层中的第一个参数,#{1}代表dao 层中第二参数,更多参数一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap">
select * from user_user_t where user_name = #{0} and user_area=#{1}
</select>
2、第二种: 使用@param 注解
public interface usermapper {
user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword);
}
然后,就可以在xml 像下面这样使用(推荐封装为一个map,作为单个参数传递给mapper:
<select id=”selectuser” resulttype=”user”>
select id, username, hashedpassword
from some_table
where username = #{username}
and hashedpassword = #{hashedpassword}
</select>
user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword);
}
然后,就可以在xml 像下面这样使用(推荐封装为一个map,作为单个参数传递给mapper:
<select id=”selectuser” resulttype=”user”>
select id, username, hashedpassword
from some_table
where username = #{username}
and hashedpassword = #{hashedpassword}
</select>
3、第三种:多个参数封装成map
try {
//映射文件的命名空间.SQL 片段的ID,就可以调用对应的映射文件中的SQL
//由于我们的参数超过了两个,而方法中只有一个Object 参数收集,因此我们使用Map 集合来装载我们的参数
Map < String, Object > map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
} catch (Exception e) {
e.printStackTrace();
sqlSession.rollback();
throw e;
} finally {
MybatisUtil.closeSqlSession();
}
//映射文件的命名空间.SQL 片段的ID,就可以调用对应的映射文件中的SQL
//由于我们的参数超过了两个,而方法中只有一个Object 参数收集,因此我们使用Map 集合来装载我们的参数
Map < String, Object > map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
} catch (Exception e) {
e.printStackTrace();
sqlSession.rollback();
throw e;
} finally {
MybatisUtil.closeSqlSession();
}
MyBatis动态sql是做什么的,简述一下动态sql的运行原理
1)Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
-----------------------------------------------------------------------------------------------------------------------------------
2)Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
-----------------------------------------------------------------------------------------------------------------------------------
3)其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
-----------------------------------------------------------------------------------------------------------------------------------
2)Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
-----------------------------------------------------------------------------------------------------------------------------------
3)其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
XML中有哪些常用的标签
<resultMap>、<parameterMap>、<sql>、<include>、<selectKey> trim、where、set、foreach、if、choose、when、otherwise、bind 其中<sql>为sql 片段标签,通过<include>标签引入sql 片段,<selectKey>为不支持自增的主键生成策略标签。
Mybatis 的Xml映射文件中,不同的Xml 映射文件, id 是否可以重复
不同的Xml 映射文件,如果配置了namespace,那么id 可以重复;如果没有配置namespace,那么id不能重复;
原因就是namespace+id 是作为Map<String, MapperStatement>的key使用的, 如果没有namespace,就剩下id,那么, id 重复会导致数据互相覆盖。有了namespace,自然id 就可以重复,namespace 不同,namespace+id 自然也就不同。
原因就是namespace+id 是作为Map<String, MapperStatement>的key使用的, 如果没有namespace,就剩下id,那么, id 重复会导致数据互相覆盖。有了namespace,自然id 就可以重复,namespace 不同,namespace+id 自然也就不同。
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
MyBatis实现一对一有几种方式?具体怎么操作的
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键 id,去再另外一个表里面查询数据,也是通过 association 配置,但另外一个表的查询通过 select 属性配置。
MyBatis实现一对多有几种方式,怎么操作的
有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection 节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select 节点配置。
Mybatis是否支持延迟加载?实现原理是什么?
1)Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
Mybatis的缓存机制
1)一级缓存: 基于PerpetualCache 的HashMap本地缓存,其存储作用域为Session,当Session flush或close之后,该Session中的所有Cache就将清空, 默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcach
3)对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有select 中的缓存将被clear。
2)二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcach
3)对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有select 中的缓存将被clear。
MyBatis的mapper接口调用时有哪些要求
1、Mapper 接口方法名和mapper.xml 中定义的每个sql 的id 相同;
2、Mapper 接口方法的输入参数类型和mapper.xml 中定义的每个sql 的parameterType 的类型相同;
3、Mapper 接口方法的输出参数类型和mapper.xml 中定义的每个sql 的resultType 的类型相同;
4、Mapper.xml 文件中的namespace 即是mapper 接口的类路径。
2、Mapper 接口方法的输入参数类型和mapper.xml 中定义的每个sql 的parameterType 的类型相同;
3、Mapper 接口方法的输出参数类型和mapper.xml 中定义的每个sql 的resultType 的类型相同;
4、Mapper.xml 文件中的namespace 即是mapper 接口的类路径。
Mapper 编写有哪几种方式
第一种: 接口实现类继承SqlSessionDaoSupport:使用此种方法需要编写
mapper 接口, mapper 接口实现类、mapper.xml 文件。
mapper 接口, mapper 接口实现类、mapper.xml 文件。
1、在sqlMapConfig.xml 中配置mapper.xml 的位置
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
2、定义mapper 接口
3、实现类集成SqlSessionDaoSupport mapper 方法中可以this.getSqlSession()进行数据增删改查。
4、spring 配置
<bean id=" " class="mapper 接口的实现">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
2、定义mapper 接口
3、实现类集成SqlSessionDaoSupport mapper 方法中可以this.getSqlSession()进行数据增删改查。
4、spring 配置
<bean id=" " class="mapper 接口的实现">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
第二种: 使用org.mybatis.spring.mapper.MapperFactoryBean
1、在sqlMapConfig.xml 中配置mapper.xml 的位置, 如果mapper.xml 和mappre 接口的名称相同且在同一个目录,这里可以不用配置
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
2、定义mapper 接口
1、mapper.xml 中的namespace 为mapper 接口的地址
2、mapper 接口中的方法名和mapper.xml 中的定义的statement 的id 保持一致
3、Spring 中定义
<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mapper 接口地址" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
2、定义mapper 接口
1、mapper.xml 中的namespace 为mapper 接口的地址
2、mapper 接口中的方法名和mapper.xml 中的定义的statement 的id 保持一致
3、Spring 中定义
<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mapper 接口地址" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
第三种: 使用mapper 扫描器
1、mapper.xml 文件编写:
mapper.xml 中的namespace 为mapper 接口的地址;mapper 接口中的方法名和mapper.xml 中的定义的statement 的id 保持一致;如果将mapper.xml 和mapper 接口的名称保持一致则不用在sqlMapConfig.xml中进行配置。
2、定义mapper 接口:
注意mapper.xml 的文件名和mapper 的接口名称保持一致, 且放在同一个目录
3、配置mapper 扫描器:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper 接口包地址"></property>
<property name="sqlSessionFactoryBeanName"value="sqlSessionFactory"/>
</bean>
mapper.xml 中的namespace 为mapper 接口的地址;mapper 接口中的方法名和mapper.xml 中的定义的statement 的id 保持一致;如果将mapper.xml 和mapper 接口的名称保持一致则不用在sqlMapConfig.xml中进行配置。
2、定义mapper 接口:
注意mapper.xml 的文件名和mapper 的接口名称保持一致, 且放在同一个目录
3、配置mapper 扫描器:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper 接口包地址"></property>
<property name="sqlSessionFactoryBeanName"value="sqlSessionFactory"/>
</bean>
插件运行原理,如何编写一个插件?
1)Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件
MyBatis与Hibernate区别
1)Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句,不过 mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对象。
2)Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql,可严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套 sql 映射文件,工作量大。
3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用 hibernate 开发可以节省很多代码,提高效率。但是Hibernate 的缺点是学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
SpringData JPA
@Entity
@Table(name = " ") 表名
@Id: 声明主键的配置
@GenerateValue:配置主键的生成策略
strategy=GenerationType.IDENTITY 自增 (MySQL)
strategy=GenerationType.SEQUENCE 序列 (ORACLE)
strategy=GenerationType.TABLE jpa提供的一种机制,通过一张数据表的形式帮助我们完成主键自增
stagegy=GenerationType.AUTO 由程序自动帮助我们选择主键生成策略
@Column:配置属性和字段的映射关系
name = " " 数据库表中字段的名称
0 条评论
下一页