项目中要用到的后端技术点总结

介绍

本文针对写项目时用到的知识点进行总结

MyBatis-Plus

依赖

 <!--mybatis-plus 持久层-->
  <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>${mybatis-plus.version}</version>
  </dependency>

  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
  </dependency>

配置文件

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://jiacloud.ml:3306/yygh_hosp?characterEncoding=utf-8&useSSL=false
spring.datasource.username=用户名
spring.datasource.password=密码
# mybatis-plus
#mybatis-plus
mybatis-plus.mapper-locations=classpath:xml放的位置
mybatis-plus.type-aliases-package=要扫描的包

使用MyBatis-plus

第一步:继承BaseMapper

@Mapper//将其注册到spring容器中
public interface UserMapper extends BaseMapper<User>{}

第二部:在启动类上加上扫描包路径

@SpringBootApplication
@MapperScan("com.test.mapper")
public class SpringBootMybatisPlusApplication {}

第三步:新建Mybatis-plus配置类

@Configuration
public class MyBatisPlusConfig {
    //分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}

第四步:编写服务层接口Service

//继承通用IService
public interface UserService extends IService<User> {}

第五步:编写Service实现

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
//ServiceImpl中已经注入了baseMapper,所以继承后可以直接调用baseMapper

第六步:编写Controller

@RestController
public class UserController{
//注入service
@AutoWired
private UserService userService;
//编写服务
}

常用方法

分页查询的实现

public List<User> UserPage(long page,long limit,String username){
	//创建page对象
	Page<User> page = new Page<>(page,limit);
	//构造条件查询
	QueryWrapper<User> qw = new QueryWrapper<>();
	qw.eq("username",username);
	Page<User> pageDate= userService.page(page,qw);
	return pageDate.getRecords();
}

常用注解

@TableName:数据库表相关
@TableId:表主键标识
@TableField:表字段标识
@TableLogic:表字段逻辑处理注解(逻辑删除)

@TableId(type= IdType.ID_WORKER_STR)

@TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的。

@TableField(exist = true):表示该属性为数据库表字段。

@TableField(condition = SqlCondition.LIKE):表示该属性可以模糊搜索。

@TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!

常用实现

逻辑删除

#配置可配可不配
mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
    @TableLogic
    private Integer isDeleted;

主键自增

    @TableId(type = IdType.AUTO)
    private Long id;

MongoDB

依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

配置文件

spring.data.mongodb.host=数据库地址
spring.data.mongodb.port=端口号
spring.data.mongodb.database=使用的数据库
spring.data.mongodb.authentication-database=要验证的数据库名称
spring.data.mongodb.username=用户名
spring.data.mongodb.password=密码
## 这里的用户名和密码要填写的是验证的数据库用户名和密码,而不是使用的数据库

使用MongoDB

第一种方式

第一步:创建pojo对象

@Document("User")//标明由mongo来维护该表
public class User {
    @Id//指定为表的ID
    private String id;
}

第二部:编写Repository用来操作数据库

public interface UserRepository extends MongoRepository<User,String>{}

第三步:在Service实现类中注入Repository进行数据库增删改查

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@AutoWired
private UserRepository userRepository;
}

第二种方式

创建pojo对象后直接在Service实现中注入MongoTemplate

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@AutoWired
private MongooTemplate mongoTemplate;
}

MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足。

实现

如果使用MongoRepository操作数据库
Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了
在这里插入图片描述
在这里插入图片描述
例如根据id查询数据库中User表信息

//这样可以直接调用,规则就是find表名By字段名,后面还可以接And,如findUserByIdAndName()就表示根据ID和name进行查询
User user = userRepository.findUserById();

常见使用和重点

分页查询

public Page<User> getUserList(User user, int page, int limit) {
    //创建pageable page从0开始
    Pageable pageable = PageRequest.of(page-1,limit);
    //创建Example对象,模糊查询,忽略大小写
    ExampleMatcher matcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING).withIgnoreCase(true);
    Example<Schedule> example = Example.of(user,matcher);
    Page<Schedule> all = scheduleRepository.findAll(example, pageable);
    return all;
}

MongoTemplate聚合操作(重难点)

//根据id,name查询后通过sex进行分组后根据年龄进行排序后进行分页
public List<User> getUserListPage(int page,int limit,String id, String name) {
        Criteria criteria = Criteria.where("id").is(id).and("name").is(name);
        //根据日期进行分组
        Aggregation agg= Aggregation.newAggregation(
                Aggregation.match(criteria),//匹配条件
                Aggregation.group("sex")//分组字段
                .first("sex").as("性别")
                //号源统计
                //排序
                Aggregation.sort(Sort.Direction.DESC,"age"),
                //分页
                Aggregation.skip((page-1)*limit),
                Aggregation.limit(limit)
        );
        AggregationResults<User> aggregate = mongoTemplate.aggregate(agg, User.class, User.class);
        return aggregate.getMappedResults();
}

缓存Redis

依赖

  <!-- redis -->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
  <!-- spring2.X集成redis所需common-pool2-->
  <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.6.0</version>
  </dependency>

配置文件

spring.redis.host=服务地址
spring.redis.port=端口
spring.redis.database= 所用数据库
#过期时间
spring.redis.timeout=1800000
spring.redis.password=密码
#最大连接数
spring.redis.lettuce.pool.max-active=20
#生成池最大等待数(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0

使用Redis

第一步:编写Redis配置文件,开启缓存

@Configuration
@EnableCaching//开启缓存
public class RedisConfig {
    /**
     * 自定义key规则
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }

    /**
     * 设置RedisTemplate规则
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //序列号key value
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 设置CacheManager缓存规则
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

第二步:在方法上使用注解进行缓存

	//根据id查询用户信息,然后将其返回
	//vule表示命名,keyGenerator表示名字生成规则
    @Cacheable(value = "user",keyGenerator = "keyGenerator")//key的命名
    public List<User> findChlidData(Long id) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("id",id);
        List<User> users = baseMapper.selectList(qw);
        return users;
    }

常用注解

@Cacheable
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

在这里插入图片描述
@CachePut
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
在这里插入图片描述
@CacheEvict
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
在这里插入图片描述
SpEL上下文数据
在这里插入图片描述

EasyExcel数据字典处理

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

依赖

	<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.1</version>
     </dependency>

编写实体类

@Data
public class UserEeVo {
	@ExcelProperty(value = "id",index = 0)
	private Long id;
	
	@ExcelProperty(value = "名称",index = 1)
	private String name;
	
	@ExcelProperty(value = "年龄",index = 2)
	private int age;
	
	@ExcelProperty(value = "性别",index = 3)
	private int sex;
}

导出

@Override
public void exportData(HttpServletResponse response) {
try {
      response.setContentType("application/vnd.ms-excel");
      response.setCharacterEncoding("utf-8");
	  // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
	  String fileName = URLEncoder.encode("用户列表", "UTF-8");
	  //导出文件名字
      response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
	  //调用查询数据库信息
      List<User> userList = dictMapper.selectList(null);
      //创建导出用的list集合,根据数据库查询到的数量进行定义长度
      List<UserEeVo> userVoList = new ArrayList<>(userList.size());
for(User user : userList) {
         UserEeVo userVo = new UserEeVo();
         //使用工具将user中的数据拷贝到Uservo中
         BeanUtils.copyBean(user, userVo, UserEeVo.class);
         //将数据添加到list集合
         userVoList.add(userVo);
      }
	  //调用输出方法将数据变成excel输出
      EasyExcel.write(response.getOutputStream(), UserEeVo.class).sheet("用户列表").doWrite(userVoList);
   } catch (IOException e) {
      e.printStackTrace();
   }
}

读取

第一步:创建监听器

@Component
public class UserListener extends AnalysisEventListener<UserEeVo> {
    @Autowired
    private UserMapper userMapper ;
    @Override
    //每行每行读取
    public void invoke(UserEeVo userEeVo, AnalysisContext analysisContext) {
        User user =new User();
        //将vo中数据拷贝到user类中
        BeanUtils.copyProperties(userEeVo,user);
        //设置逻辑删除值
        user.setIsDeleted(0);
        //将数据插入数据库
        userMapper.insert(user);
    }

    @Override
    //读取后运行
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

读取前端发来的文件,将数据放到数据库

    @Override
    public void importExport(MultipartFile file) {
        try {
            //将export中数据上传到数据库,调用read方法,传入文件和类型还有监听器,进行处理
            EasyExcel.read(file.getInputStream(),UserEeVo.class,userListener).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

SpringCloud

我本次写项目用到了nacos注册中心,Feign服务调用和GateWay三个模块,下面对每个作用和使用进行总结

NACOS注册中心

Nacos 是用来发现、配置和管理微服务的管理平台

依赖

	<dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
编写配置文件
#nacos地址默认地址未8848
nacos:
	config:
		server-addr: 127.0.0.1:8848
#配置服务名字
spring:
	application:
		name: user
在启动类上添加注释
@SpringBootApplication
//配置包扫描
@ComponentScan(basePackages = "com.jiaboke")
//开启发现客户端
@EnableDiscoveryClient
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}
启动NACOS

下载官方安装包,解压,找到bin目录,window运行startup.cmd
脚本进行启动,Linux运行startup.sh进行启动。然后就可以访问
127.0.0.1:8848/nacos进行服务的查看和管理(默认用户:nacos,密码:nacos)

Feign服务调用

Spring Cloud Feign提供的声明式服务绑定功能来实现对该服务接口的调用

服务提供方

依赖
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
主类开启支持
@SpringBootApplication
@ComponentScan(basePackages = "com.jiaboke")
//开启服务发现
@EnableDiscoveryClient
//开启服务调用支持
@EnableFeignClients(basePackages = "com.jiaboke")
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceHospApplication.class,args);
    }
}
编写要被调用的方法
@RestController
@Api(tags = "用户管理")
@RequestMapping("admin/user")
public class UserController {
	//注入service
	@Autowired
	private UserService userService;
	@ApiOperation(value = "根据id查询用户")
    @GetMapping("selectUserById/{id}")
    public User selectUserById(@PathVariable String id){
        //调用service方法查询到用户信息,将其返回
        return userService.selectById(id);
    }
}

编写服务模块

依赖
<?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">
    <parent>
        <artifactId>user-parent</artifactId>
        <groupId>com.jiaboke.user</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <version>1.0</version>
    <artifactId>service-user-client</artifactId>
    <packaging>jar</packaging>
    <name>service-user-client</name>
    <description>service-user-client</description>

    <dependencies>
    	<!--导入工具类-->
        <dependency>
            <groupId>com.jaboke</groupId>
            <artifactId>common-util</artifactId>
            <version>1.0</version>
        </dependency>
        <!--导入实体类-->
        <dependency>
            <groupId>com.jiaboke</groupId>
            <artifactId>model</artifactId>
            <version>1.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided </scope>
        </dependency>

        <!-- 服务调用feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <scope>provided </scope>
        </dependency>
    </dependencies>
</project>
创建FeignClient
//服务提供者名字
@FeignClient(value = "user")
//将其注册到Spring托管
@Repository
public interface UserFeignClient {
    //根据id获取用户信息
    @GetMapping("admin/user/selectUserById/{id}")
    User selectUserById(@PathVariable("id") Long id);
}

服务调用方

将FeignClient模块引入
		<dependency>
            <groupId>com.jiaboke.user</groupId>
            <artifactId>service-user-client</artifactId>
            <version>1.0</version>
        </dependency>
在需要调用的地方将其注入
public class UserTestServiceImpl implements UserTestService{
	@Autowired
	private UserFeignClient userFeignClient;
	public User UserTest(String id){
		return userFeignClient.selectUserById(id);
	}
}

Spring Cloud Gateway

Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等

依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- 服务注册 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

添加配置文件

# 服务端口
server.port=80
# 服务名
spring.application.name=service-gateway

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#使用服务发现路由
spring.cloud.gateway.discovery.locator.enabled=true

#设置路由id
spring.cloud.gateway.routes[0].id=user
#设置路由的uri
spring.cloud.gateway.routes[0].uri=lb://user
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[0].predicates= Path=/*/user/**

创建启动类

@SpringBootApplication
public class ServiceGateWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceGateWayApplication.class,args);
    }
}

处理跨域问题

什么是跨域?
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域

跨域的解决方法

第一种:在controller类上添加@CrossOrigin就可以了,不过该方法有个弊端,你每写一个controller都要进行添加,所以就有第二种方法
第二种:在gateway中统一进行解决,方法代码如下

//处理跨域,代码较为固定,不多做解释用到粘贴复制就行
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

SpringBootMail

这个是springboot提供的邮箱服务,我的项目用来发送验证码等消息(原本想用短信服务,但是个人注册不了阿里云的短信服务就出此下策)

依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

编写配置文件

#配置邮箱服务
spring.mail.host=smtp.qq.com#用的QQ邮箱,根据你选择的邮箱进行修改
spring.mail.username=XXXXXX@qq.com##邮箱
spring.mail.password= XXXXXXXX #QQ邮箱的授权码
spring.mail.properties.mail.smtp.ssl.enable=true#开启ssl支持,不是所有邮箱都需要,根据需要填写

编写工具类

@Component
public class MyEmailUtils {
    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 普通邮件发送
     * @param from 发送者
     * @param to 接受人
     * @param subject 邮件主题
     * @param content 内容
     */
    public Boolean myEmail(String from,String to,String subject,String content){
        SimpleMailMessage message = new SimpleMailMessage();
        //邮件发送人
        message.setFrom(from);
        //邮件接收人
        message.setTo(to);
        //邮件主题
        message.setSubject(subject);
        //邮件内容
        message.setText(content);
        //发送邮件
        try {
            javaMailSender.send(message);
            return true;
        }catch (Exception e){
            return false;
        }

    }

    /**
     *
     * @param from 发件人
     * @param to 收件人
     * @param subject 主题
     * @param content 内容
     * @param html 是否开启html支持
     */
    public void myEmailHtml(String from,String to,String subject,String content,Boolean html){
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            //发件人
            helper.setFrom(from);
            //收件人
            helper.setTo(to);
            //主题
            helper.setSubject(subject);
            //内容,是否开启html支持
            helper.setText(content,html);
            //发送
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
            System.out.println("发送失败");
        }
    }
}

编写验证码生成工具

public class MyConde {
    private static final String SYMBOLS = "0123456789";
    /**
     * Math.random生成的是一般随机数,采用的是类似于统计学的随机数生成规则,其输出结果很容易预测,因此可能导致被攻击者击中。
     * 而SecureRandom是真随机数,采用的是类似于密码学的随机数生成规则,其输出结果较难预测,若想要预防被攻击者攻击,最好做到使攻击者根本无法,或不可能鉴别生成的随机值和真正的随机值。
     */
    private static final Random RANDOM = new SecureRandom();

    public static String generateVerCode() {
        char[] nonceChars = new char[6];
        for (int i = 0; i < nonceChars.length; i++) {
            nonceChars[i] = SYMBOLS.charAt(RANDOM.nextInt(nonceChars.length));
        }
        return new String(nonceChars);
    }
}

验证码生成发送

    @Autowired
    private MyEmailUtils myEmailUtils;
    public Boolean sendCode(String email,String code){

        String text= "尊敬的用户,您好:\n本次请求的邮件验证码为 "+ code+ " ,本验证码5分钟内有效,请及时输入。(请勿泄露此验证码如非本人操作,请忽略该邮件。\n(这是一封自动发送的邮件,请不要直接回复)";
        //
        return myEmailUtils.myEmail("xxxx@qq.com", email, "预约挂号验证码", text);
    }

验证码过期时间设置是使用Readis来实现的,每次生成验证码都将验证码存到Readis中并设置过期时间,在验证的地方从readis中取出来跟用户输入进行比较

RabbitMQ

创建RabbitMQ工具模块

依赖

	<dependencies>
        <!--rabbitmq消息队列-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
    </dependencies>

编写设置类

@Configuration
public class MQConfig {
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

编写静态常量类

public class MqConst {
    /**
     * 订单
     */
     //交换机名称
    public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";
    //路由键名称
    public static final String ROUTING_ORDER = "order";
    //队列
    public static final String QUEUE_ORDER  = "queue.order";

编写Rabbit服务

@Service
public class RabbitService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     *  发送消息
     * @param exchange 交换机
     * @param routingKey 路由键
     * @param message 消息
     */
    public boolean sendMessage(String exchange, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchange, routingKey, message);
        return true;
    }
}

使用

在需要的模块引入工具模块

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>rabbit-utils</artifactId>
        </dependency>

添加配置

#rabbitMQ
spring.rabbitmq.host=ip地址
spring.rabbitmq.port=端口号
spring.rabbitmq.username=用户名
spring.rabbitmq.password=密码
spring.rabbitmq.virtual-host=主机名

调用

rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);

创建监听

@Component
public class HospitalReceiver {
    @Autowired
    private RabbitService rabbitService;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_ORDER, durable = "true"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_ORDER),
            key = {MqConst.ROUTING_ORDER}
    ))
    public void receiver(OrderMqVo orderMqVo, Message message, Channel channel) throws IOException {
        //对订单进行处理
    }
}

后记

我做的项目还有几个技术每写出来比如说微信登录,微信支付和退款,阿里云的OSS存储等等,因为这些东西都比较固定,需要的时候直接翻阅官方文档即可,没有总结的必要,而且是中国企业开发的,文档也比较友好,因此就不再进行总结

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值