一、引言
1.实验目的
利用Spring技术实现一个校友信息的收集和展示页面。要求采用MVC框架,要求加入依赖注入和面向切面的编程。
构建一个日志记录的切面。要求:
a. 对于所有的Alumni表的查询操作,记录各个操作的时间、用户,读取内容,存入ReadLog表格中。
b. 对于所有的Alumni表的更新(更新和删除)操作,记录各个操作的时间、用户,修改的新值和旧值,存入UpdateLog表格中(删除的新值为null)。
2.环境配置
- 操作系统:Windows 10 X64
- 编程工具:Intellij IDEA 2019.2×64,Navicat for MySQL
- 数据库:Mysql
- 环境:Java jdk 1.8
二、实验具体过程
1.创建数据库
(1)创建用户表user_info
(2)创建记录查询操作的日志表readlog,其中content为用户读取内容
(3)创建记录更新(更新和删除)操作的日志表updatelog,其中operation为用户操作,1表示用户更新信息表记录,0表示用户删除信息表记录
2.项目后端代码编写
(1)后端代码结构如下
(2)AOP层代码
具体代码如下:SpringAopTest.java
import com.example.aoptest.Entity.UserEntity;
import com.example.aoptest.Service.UpdatelogService;
import com.example.aoptest.Service.ReadlogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class SpringAopTest {
@Autowired
private ReadlogService readlogService;
@Autowired
private UpdatelogService updatelogService;
//查询信息切点
@Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.findByAll(*))")
public void findAOP(){
}
//更新信息切点
@Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.updateByUsername(..)))")
public void updateAOP(){
}
//删除信息切点
@Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.deleteByUsername(*)))")
public void deleteAOP(){
}
//将查询信息操作日志写入数据库
@Before("findAOP()")
public void beforeread(JoinPoint joinPoint){
UserEntity userEntity =(UserEntity)joinPoint.getArgs()[0];
readlogService.insert(userEntity);
System.out.println("Before: " + joinPoint);
}
//将更新信息操作日志写入数据库
@Before("updateAOP()")
public void beforeupdate(JoinPoint joinPoint){
UserEntity userEntity =(UserEntity)joinPoint.getArgs()[0];
String username=String.valueOf(joinPoint.getArgs()[1]);
updatelogService.insertUpdate(userEntity,username);
System.out.println("Before: " + joinPoint);
}
//将删除信息操作日志写入数据库
@Before("deleteAOP()")
public void beforedelete(JoinPoint joinPoint) {
String username = String.valueOf(joinPoint.getArgs()[0]);
updatelogService.insertDelete(username);
System.out.println("Before: " + joinPoint);
}
}
(3)Controller层代码
具体代码如下:UserController.java
(4)Entity层代码
具体代码如下:UserEntity.java
Readlog.java
Updatelog.java
(5)Mapper层代码
具体代码如下:UserMapper.java
ReadlogMapper.java
UpdatelogMapper.java
(6)Service层代码
具体代码如下:UserService.java
ReadlogService.java
UpdatelogService.java
3.运行结果
(1)记录用户jojo查询个人信息操作
user_info表中的用户jojo的信息如下:
在查询操作之前的readlog表中无数据记录:
执行查询信息的测试代码:
执行输出结果如下:
数据库readlog表中被写入数据,其中content是查询到的数据的内容:
(2)记录用户jojo的更新个人信息操作
user_info表中的用户jojo的更新之前的信息如下:
在更新操作之前的updatelog表中无数据记录:
执行更新信息的测试代码:
执行输出结果如下:
数据库updatelog表中被写入数据:
可以看到modify_old中是未修改的phone12345678901,modify_new是修改后的phone1234,operation为1表示为修改操作
下面是修改后的user_info表:
(3)记录用户jojo的删除个人信息操作
在删除操作之前updatelog表中只有1条更新操作的数据记录:
执行删除信息的测试代码:
执行输出结果如下:
数据库updatelog表中被写入一条删除数据的操作记录:
可以看到modify_old中是未更新(删除)之前的数据记录,modify_new是更新(修改)之后的数据(记录为null),operation为0表示为删除操作
再看user_info表中用户jojo已被删除:
三、总结
在本次实验中遇到了一些问题,现在总结一下:
(1)在连接数据库时遇到了错误[08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up.之后查资料发现这是因为安装mysql的时候时区设置的默认是美国的时区,而我们中国大陆要比他们迟8小时,采用+8:00格式。使用的数据库是MySQL,在没有指定MySQL驱动版本的情况下它自动依赖的驱动是8.0.16很高的版本,这是由于数据库和系统时区差异所造成的,在jdbc连接的url后面加上serverTimezone=GMT即可解决问题。
(2)mybatis配置时出现错误rg.apache.ibatis.binding.BindingException: Invalid bound statement (not found)!这个错误导致无法将mapper层的代码映射到xml文件当中,就无法对数据库进行操作。解决方法是在application.properties配置文件中指定xml文件夹和实体的文件夹路径。
(3)Aop在设置切点的时候,如果拦截的controller层的方法有两个参数不能用*来匹配,要用…否则无法匹配
(4)本次实验还学会了使用MybatisCodeHelper pro工具来自动生成实体层、mapper层以及xml的代码,自动生成代码对于Spring框架来说减轻了不少负担,而且出错的概率也大大降低,但缺点是对于xml层的sql语句的具体写法可能就不够熟练了。