Spring面向切面与定时任务之章节练习[宠物数据的增删改查]
一、练习要求如下
章节练习: 1.创建项目 spring-mybatis,并完成 spring 与 mybatis 整合,使用 easycode 完成 pet 表的基本方法的生成。
2.在项目 spring-mybatis 中,为 service 层创建切面,凡是以 query 开头的方法都将获取到的数据缓存到磁盘文件,凡是以 update、delete、insert 开头的请求将删除所有缓存的文件,并重新调用 dao 层。
3.在上面项目中创建定时任务:每天晚上 12 点整向控制台打印:新的一天又开始了。
4.在上面项目中创建定时任务:所有工作日早上 7:30 向控制台打印:起床了,起床了!
二、相关流程及其参考代码如下:
①annotation自定义注解类层
MyCacheAble代码如下:
package com.allen.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyCacheAble {
}
MyCacheEvict代码如下:
package com.allen.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyCacheEvict {
}
②aop切面类层
CacheAop类代码:
package com.allen.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.Arrays;
@Component
@Aspect
public class CacheAop {
@Around("execution(* com.allen.service.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行方法名:" + methodName);
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
System.out.println("执行时长:" + (System.currentTimeMillis() - start));
return result;
}
@Around("@annotation(com.allen.annotation.MyCacheAble)")
public Object cache(ProceedingJoinPoint point) throws Throwable {
System.out.println("缓存文件");
String name = point.getSignature().getName();
String args = Arrays.toString(point.getArgs());
if (new File("H:\\demotest\\spring-mvc\\spring-mvc001\\cache\\"+name+args+".txt").exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("H:\\demotest\\spring-mvc\\spring-mvc001\\cache\\"+name + args+".txt"));
Object o = objectInputStream.readObject();
objectInputStream.close();
return o;
}
ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("H:\\demotest\\spring-mvc\\spring-mvc001\\cache\\" +name+ args+".txt"));
Object proceed = point.proceed();
stream.writeObject(proceed);
stream.close();
return proceed;
}
@Around("@annotation(com.allen.annotation.MyCacheEvict)")
public static Object clearCache(ProceedingJoinPoint point) throws Throwable {
File file = new File("H:\\demotest\\spring-mvc\\spring-mvc001\\cache\\");
File[] files = file.listFiles();
for (File f : files) {
if (f.getName().endsWith(".txt")) {
f.delete();
}
}
Object proceed = point.proceed();
return proceed;
}
@Around("execution(* com.allen.service.impl.*.insert*(..))")
public Object cleanInsert(ProceedingJoinPoint joinPoint) throws Throwable {
return clearCache(joinPoint);
}
@Around("execution(* com.allen.service.impl.*.update*(..))")
public Object cleanUpdate(ProceedingJoinPoint joinPoint) throws Throwable {
return clearCache(joinPoint);
}
@Around("execution(* com.allen.service.impl.*.delete*(..))")
public Object cleanDelete(ProceedingJoinPoint joinPoint) throws Throwable {
return clearCache(joinPoint);
}
}
③controller层
PetController类代码:
package com.allen.controller;
import com.allen.entity.Pet;
import com.allen.service.PetService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("pet")
public class PetController {
@Resource
private PetService petService;
@GetMapping("selectOne")
public Pet selectOne(Integer id) {
return this.petService.queryById(id);
}
@GetMapping("findAllByLimit")
public List<Pet> findAllByLimit() {
return this.petService.queryAllByLimit(0, 3);
}
@GetMapping("findAll")
public List<Pet> findAll(Pet pet) {
return this.petService.findAll(pet);
}
@GetMapping("findById")
public Pet findById(Integer id) {
return this.petService.queryById(id);
}
@GetMapping("deleteById")
public boolean deleteById(Integer id) {
return this.petService.deleteById(id);
}
@GetMapping("insert")
public Pet insert(Pet pet) {
return this.petService.insert(pet);
}
@GetMapping("update")
public Pet update(Pet pet) {
return this.petService.update(pet);
}
@GetMapping("selectAll")
public List<Pet> selectAll() {
return this.petService.selectAll();
}
}
④dao层
PetDao类代码:
package com.allen.dao;
import com.allen.entity.Pet;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PetDao {
Pet queryById(Integer id);
List<Pet> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);
List<Pet> queryAll(Pet pet);
int insert(Pet pet);
int update(Pet pet);
int deleteById(Integer id);
List<Pet> selectAll();
}
⑤entity层
Pet类:
package com.allen.entity;
import java.io.Serializable;
public class Pet implements Serializable {
private static final long serialVersionUID = -19296965584496535L;
private Integer id;
private String name;
private Double weight;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
@Override
public String toString() {
return "\nPet{" +
"id=" + id +
", name='" + name + '\'' +
", weight=" + weight +
'}';
}
}
⑥service层
impl包下面的PetServiceImpl类:
package com.allen.service.impl;
import com.allen.annotation.MyCacheAble;
import com.allen.annotation.MyCacheEvict;
import com.allen.dao.PetDao;
import com.allen.entity.Pet;
import com.allen.service.PetService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class PetServiceImpl implements PetService {
@Resource
private PetDao petDao;
@Override
@MyCacheAble
public Pet queryById(Integer id) {
return this.petDao.queryById(id);
}
@Override
@MyCacheAble
public List<Pet> queryAllByLimit(int offset, int limit) {
return this.petDao.queryAllByLimit(offset, limit);
}
@Override
@MyCacheEvict
public Pet insert(Pet pet) {
this.petDao.insert(pet);
return pet;
}
@Override
@MyCacheEvict
public Pet update(Pet pet) {
this.petDao.update(pet);
return this.queryById(pet.getId());
}
@Override
@MyCacheEvict
public boolean deleteById(Integer id) {
return this.petDao.deleteById(id) > 0;
}
@Override
@MyCacheAble
public List<Pet> findAll(Pet pet) {
return this.petDao.queryAll(pet);
}
@Override
@MyCacheAble
public List<Pet> selectAll(){
return this.petDao.selectAll();
}
}
PetService类:
package com.allen.service;
import com.allen.entity.Pet;
import java.util.List;
public interface PetService {
Pet queryById(Integer id);
List<Pet> queryAllByLimit(int offset, int limit);
Pet insert(Pet pet);
Pet update(Pet pet);
boolean deleteById(Integer id);
List<Pet> findAll(Pet pet);
List<Pet> selectAll();
}
⑦util工具类
Menu菜单类:
package com.allen.util;
import org.springframework.stereotype.Component;
@Component
public class Menu {
public void PetMenu(){
System.out.println("************************************************************************************************");
System.out.println("\t\t\t\t\t\t*****************宠物管理系统*****************");
System.out.println("\t\t\t\t\t\t*****************1、查询全部宠物**************");
System.out.println("\t\t\t\t\t\t*****************2、根据id找宠物**************");
System.out.println("\t\t\t\t\t\t*****************3、根据id删除宠物*************");
System.out.println("\t\t\t\t\t\t*****************4、新增宠物******************");
System.out.println("\t\t\t\t\t\t*****************5、根据id修改宠物*************");
System.out.println("\t\t\t\t\t\t*****************0、退出系统******************");
System.out.println("\t\t\t\t\t\t*****************请选择相应的菜单选项:");
}
}
⑧App类
package com.allen;
import com.allen.controller.PetController;
import com.allen.entity.Pet;
import com.allen.util.Menu;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
import java.util.Scanner;
public class App
{
public static void main( String[] args )
{
Menu menu=new Menu();
Scanner scanner=new Scanner(System.in);
Pet pet=new Pet();
ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
PetController petController = context.getBean(PetController.class);
while (true){
menu.PetMenu();
int num = scanner.nextInt();
switch (num){
case 1:
List<Pet> list = petController.selectAll();
System.out.println(list);
break;
case 2:
System.out.println("请输入宠物Id:");
int id = scanner.nextInt();
Pet pet1 = petController.findById(id);
System.out.println(pet1);
break;
case 3:
System.out.println("请输入宠物Id:");
int id1 = scanner.nextInt();
boolean delete = petController.deleteById(id1);
if(delete){
System.out.println("恭喜您删除宠物成功");
}else {
System.out.println("对不起,没有对应的宠物");
}
break;
case 4:
System.out.println("请输入宠物名称");
String name = scanner.next();
pet.setName(name);
System.out.println("请输入宠物体重:");
double weight = scanner.nextDouble();
pet.setWeight(weight);
Pet insert = petController.insert(pet);
System.out.println(insert);
break;
case 5:
System.out.println("请输入相关宠物Id");
int id2 = scanner.nextInt();
pet.setId(id2);
System.out.println("请输入宠物名称");
String name2 = scanner.next();
pet.setName(name2);
System.out.println("请输入宠物体重:");
double weight2 = scanner.nextDouble();
pet.setWeight(weight2);
Pet pet2 = petController.update(pet);
System.out.println("修改后的宠物数据为:"+pet2);
break;
case 0:
System.exit(0);
default:
System.out.println("选项输入错误,请重新输入相关的选项:");
break;
}
}
}
}
⑨PetScheduled定时任务类
package com.allen;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class PetScheduled {
@Scheduled(cron = "0 0 00 ? * *")
public void newOfDay(){
System.out.println("新的一天又开始了。");
}
@Scheduled(cron = "0 30 07 ? * 2-6")
public void getUp(){
System.out.println("起床了!起床了!");
}
}
⑩resources包下面的mapper包里面的PetDao.xml配置文件
PetDao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.allen.dao.PetDao">
<resultMap type="com.allen.entity.Pet" id="PetMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="weight" column="weight" jdbcType="DOUBLE"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="PetMap">
select
id, name, weight
from mybatis.pet
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="PetMap">
select
id, name, weight
from mybatis.pet
limit #{offset}, #{limit}
</select>
<!--通过实体作为筛选条件查询-->
<select id="queryAll" resultMap="PetMap">
select
id, name, weight
from mybatis.pet
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="weight != null">
and weight = #{weight}
</if>
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into mybatis.pet(name, weight)
values (#{name}, #{weight})
</insert>
<!--通过主键修改数据-->
<update id="update">
update mybatis.pet
<set>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="weight != null">
weight = #{weight},
</if>
</set>
where id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from mybatis.pet where id = #{id}
</delete>
<select id="selectAll" resultType="com.allen.entity.Pet">
select * from pet
</select>
</mapper>
⑩①mapper下面的db.properties配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:/
jdbc.username=root
jdbc.password=123456
⑩②mapper下面的spring-mybatis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- spring 使用 context:component-scan 将指定包下面的带有声明 bean 的注解的类加入到 spring 容器管理-->
<context:component-scan base-package="com.allen"/>
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据库数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 创建 session 工厂-->
<bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!--告诉spring mybatis接口的位置-->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.allen.dao"/>
</bean>
<!-- 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用注解的方式完成事务控制-->
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
<!-- 在配置文件中开启 aspectj 代理,同时切面类必须定义在 spring 的包扫描下-->
<aop:aspectj-autoproxy/>
<!-- 切面类需要在包扫描下声明为组件(Component)同时还要添加注解 @Aspect 声明为切面类-->
<!-- 定时任务-->
<task:annotation-driven/>
<!-- 配置 xml 开启允许异步-->
<!-- <task:executor id="executor" pool-size="5"/>-->
<!-- <task:annotation-driven executor="executor"/>-->
</beans>
⑩③pom.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.allen</groupId>
<artifactId>spring-mvc001</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-mvc001</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
⑩④cache层:
??该层是存储运行时期的缓存文件的,当方法不是查询时,运行其他的方法会将cache包里面的缓存数据清空。
⑩⑤pet宠物类数据库
三、测试结果如下:
①查询全部宠物
②根据ID查找宠物
③新增宠物数据
④根据Id修改宠物
⑤根据Id删除宠物
⑥退出系统
|