社区项目中的社区核心功能开发。主要包含内容:前缀树(过滤敏感词),AJAX(发布帖子,发送私信),事务管理(添加评论),AOP(统一处理异常,统一记录日志)。
过滤敏感词
前缀树
- 名称:Trie、字典树、查找树
- 特点:查找效率高,消耗内存大
- 应用:字符串检索、词频统计、字符串排序等
敏感词过滤器
发布帖子
AJAX
- (Asynchronous JavaScript and XML)异步的JavaScript与XML,不是一门新技术,只是一个新术语
- 使用AJAX,网页能够将增量更新呈现在页面上,而不需要刷新整个页面
- 虽然X代表XML,但是目前JSON的使用比XML更加普遍
示例
实践
采用AJAX请求,实现发布帖子的功能
在dao下的DiscussPostMapper类中新建增加帖子的方法:
对应的resource下的discusspost-mapper.xml中的sql语句进行增加:
在service下的DiscussPostService类下新建增加帖子的方法,判断传入的参数不能为空后对帖子内容进行转义和过滤:
在controller下新建DiscussPostController类,声明访问路径为"/discuss",并在类中新建新增帖子的方法,判断客户端数据无误后传到服务器:
最后在index.js文件中编写JQuery方法发送异步请求。如果点击我要发贴后不刷新界面,显示发帖框。发帖成功会显示提示框,2s后刷新界面:
帖子详情
DiscussPostMapper
DiscussPostService
DiscussPostController
index.html
discuss-detail.html
事务管理
什么是事务
事务时由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全执行,要么全放弃执行。
事务的特性(ACID)
- 原子性(Atomicity):事务时应用中不可再分的最小执行体;
- 一致性(Consistency):事务执行的结果,须使数据从一个一致性状态,变为另一个一致性状态;
- 隔离性(Isolation):各事务的执行互不干扰,任何事务的内部操作对其他事务都是隔离的;
- 持久性(Durability):事务一旦提交,对数据所做的任何改变都要记录到永久的存储器中。
事务的隔离性
常见并发异常:
第一类丢失更新,第二类丢失更新
第一类丢失更新:某一个事务回滚,导致另外一个事务已更新的数据丢失。
时刻 事务1 事务2 T1 Read:N=10 T2 Read:N=10 T3 Write:N=9 T4 Commit:N=9 T5 Write:N=11 T6 Rollback:N=10 第二类丢失更新:某一个事务提交,导致另外一个事务已更新的数据丢失。
时刻 事务1 事务2 T1 Read:N=10 T2 Read:N=10 T3 Write:N=9 T4 Commit:N=9 T5 Write:N=11 T6 Commit:N=11 脏读、不可重复读、幻读
脏读:某一个事务,读取了另外一个事务未提交的数据。
时刻 事务1 事务2 T1 Read:N=10 T2 Write:N=11 T3 Read:N=11 T4 Rollback:N=10 不可重复读:某一个事务,对同一个数据前后读取的结果不一致。
时刻 事务1 事务2 T1 Read:N=10 T2 Read:N=10 T3 Write:N=11 T4 Commit:N=11 T5 Read:N=11 幻读:某一个事务,对同一个表前后查询到的行数不一致。
时刻 事务1 事务2 T1 Select:id<10(1,2,3) T2 Insert:id=4 T3 Commit:id=(1,2,3,4) T4 Select:id<10(1,2,3,4)
常见隔离级别:
- Read Uncommitted:读取未提交的数据
- Read Committed:读取已提交的数据
- Repeatable Read:可重复读
- Serializable:串行化
隔离级别 第一类丢失更新 脏读 第二类丢失更新 不可重复读 幻读 Read Uncommitted Y Y Y Y Y Read Committed N N Y Y Y Repeatable Read N N N N Y Serializable N N N N N
实现机制
悲观锁(数据库)
共享锁(S锁)
事务A对某数据加了共享锁之后,其他事务只能对该数据加共享锁,但不能加排他锁。
排他锁(X锁)
事务A对某数据加了排他锁之后,其他事务对该数据既不能加共享锁,也不能加排他锁。
乐观锁(自定义)
版本号,时间戳等
在更新数据前,检查版本号是否发生变化。若变化则取消本次更新,否则就更新数据(版本号+1)。
Spring事务管理
显示评论
数据层
业务层
表现层
添加评论
数据层
业务层
表现层
私信列表
私信列表
私信详情
发送私信
发送私信
设置已读
统一处理异常
- @ControllerAdvice
- 用于修饰类,表示该类是Controller的全局配置类
- 在此类中,可以对Controller进行如下三种全局配置:异常处理方案、绑定数据方案、绑定参数方案
- @ExceptionHandler 异常处理方案
- 用于修饰方法,该方法会在Controller出现异常后被调用,用于处理捕获到的异常。
- @ModelAttribute 绑定数据方案
- 用于修饰方法,该方法会在Controller方法执行前被调用,用于为Model对象绑定参数。
- @DataBinder
绑定参数方案
- 用于修饰方法,该方法会在Controller方法执行前被调用,用于绑定参数的转换器。
全局配置类:在Controller包下新建advice包,在addvice包下新建ExceptionAdvice类用来做全局配置类:
在HomeController类下配置error页面:
统一记录日志
需求:帖子模块、评论模块、消息模块
AOP的概念
- Aspect Oriented Programing,即面向方面(切面)编程
- AOP是一种编程思想,是对OOP的补充,可以进一步提高编程的效率。
AOP术语
AOP的实现
AspectJ
- AspectJ是语言级的实现,它扩展了Java语言,定义了AOP语法
- AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码规范的class文件
Spring AOP
- Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器。
- Spring AOP在运行时通过代理的方式织入代码,只支持方法类型的连接点。
- Spring AOP支持对AspectJ的集成。
JDK动态代理
- java提供的动态代理技术,可以在运行时创建接口的代理实例
- Spring AOP默认采用此种方式,在接口的代理实例中织入代码
CGlib动态代理
- 采用底层的字节码技术,在运行时创建子类代替实例
- 当目标对象不存在接口时,Spring AOP会采用此种方式,在子类实例中织入代码
使用方式