springboot使用一年后开发总结

springboot的优势主要有以下几:1.独立运行Spring项目:Springboot可以以jar包形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar来运行。2.内嵌servlet容器:可以选择内嵌Tomcat、jetty或者Undertow,这样我们无须以war包形式部署项目。3.提供starter简化Maven配置。4.自动装配。5快速构建项目。

1.springboot数据校验

添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

构建需要校验的实体类:

@AllArgsConstructor
@NoArgsConstructor
@Accessors
@Data
public class User {

    @NotNull(message = "用户id不能为空")
    private Integer id;

    @NotBlank(message = "姓名不能为空")
    @Length(min = 2, max = 15, message = "姓名长度为2-15位。")
    private String name;

    @Range(min = 0, max = 100, message = "年龄范围应该在0-100内。")
    private Integer age;

    @Email(message = "邮箱格式错误")
    private String email;

    @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
    @NotBlank(message = "手机号码不能为空")
    private String phone;
}

Controller的请求参数上添加@Valid 注解开启验证

@RestController
@Slf4j
public class UserController {

    @PostMapping("/user")
    public String Validate(@RequestBody @Valid User user){
        log.info("The user's information is {}", user);
        return "success";
    }

}

在这里插入图片描述

2.拦截器

编写拦截器实现类,实现HandlerInterceptor接口,在方法内实现自己的业务逻辑代码

package com.wyu.tt12validation.common.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class AdminInterceptor implements HandlerInterceptor {
    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
        //如果设置为true时,请求将会继续执行后面的操作
        log.info("请求处理之前进行调用");
        return true;
    }

    /**
     * 请求处理之后进行调用,Controller方法调用之后
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        log.info("请求处理之后进行调用");
    }

    /**
     * 在整个请求结束之后被调用,主要是用于进行资源清理工作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        log.info("请求结束之后进行调用");
    }
}

配置拦截器类并实现WebMvcConfigurer类,并重写其中的方法

@Configuration
public class MyInterceptorConfig implements  WebMvcConfigurer {

    @Bean
    public AdminInterceptor adminInterceptor(){
        return new AdminInterceptor ();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(adminInterceptor());
        registration.addPathPatterns("/**");                      //所有路径都被拦截
        registration.excludePathPatterns(                         //添加不拦截路径
                "/**/*.html",            //html静态资源
                "/**/*.css"            //css静态资源
        );
    }
}

执行效果:
在这里插入图片描述

3.过滤器

1.拦截器与过滤器的区别

  • Filter是依赖于Servlet容器,而拦截器则是独立存在的,可以在任何情况下使用
  • Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行
  • Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理

2.编写过滤器类:

public class LogFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化----------》");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
     FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("完成请求所需时间:"+(System.currentTimeMillis()-start));
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁----------》");
    }
}

3.配置过滤器类:

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new LogFilter());
        registration.addUrlPatterns("/*");
        registration.setName("LogFilter");
        registration.setOrder(1); //配置多个过滤器时,执行的优先级
        return registration;
    }

}

4.springboot使用@Scheduled定时任务

1.cron表达式字符含义说明
cron表达式:* * * * * *,其实就是一个字符串,
字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,其中常用为六个域。
corn从左到右(用空格隔开)分别是:秒 分 小时 月份中的日期 月份 星期中的日期 年份

字段允许值允许的特殊字符
秒(Seconds)0~59的整数, - * / 四个字符
分(Minutes)0~59的整数, - * / 四个字符
小时(Hours)0~23的整数, - * / 四个字符
日期(DayofMonth)1~31的整数(但是你需要考虑你月的天数),- * ? / L W C 八个字符
月份(Month)1~12的整数或者 JAN-DEC, - * / 四个字符
星期(DayofWeek)1~7的整数或者 SUN-SAT (1=SUN), - * ? / L C # 八个字符
年(可选,不常用)(Year)1970~2099, - * / 四个字符

corn表达式示范

  • 每隔5秒执行一次:*/5 * * * * ?
  • 每隔1分钟执行一次:0 */1 * * * ?
  • 每小时的20分执行一次:0 20 * * * ?
  • 每天的两点35分执行一次:0 35 2 * * ?
  • 每月的1日的凌晨2点调整任务:0 0 2 1 * ? *
  • 每天上午10点,下午2点,4点 执行一次:0 0 10,14,16 * * ?
  • 每周星期天凌晨1点实行一次 :0 0 1 ? * L

2.@Scheduled注解说明:

@Scheduled(
    initialDelay = 5000,         //第一次延迟多长时间后再执行
    initialDelayString = "5000", //第一次延迟5秒后执行,值为String类型                        
    fixedDelay = 5000,           //上一次执行完毕时间点之后多长时间再执行
    fixedDelayString = "5000",   //上一次执行完毕时间点之后5秒再执行,值为String类型
    fixedRate = 5000,            //上一次开始执行时间点之后多长时间再执行
    fixedRateString = "5000",    //上一次开始执行时间点之后5s再执行,值为String类型
    cron = "",                   //cron的表达式
    zone = ""                    //时区,cron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区
) 

3.springboot工程中使用
在springboot的主类上,加上注解@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class MybatisplusdemoApplication {

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

}

编写测试类

package com.wyu.mybatisplusdemo.article.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Scheduled;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class Schedule {
    Logger log = LoggerFactory.getLogger(Schedule.class);

    //cron表达式:每隔5秒执行一次
    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh点mm分ss秒");
        // 将date日期解析为字符串
        String date = simpleDateFormat.format(new Date());
        log.info("当前时间:" + date);
    }

}

执行结果:
在这里插入图片描述

5.SpringBoot整合MybatisPlus

1.引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.9</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.1</version>
</dependency>

2.添加配置:

server:
  port: 8090

spring:
  #------------------------MySql-----------------------------
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

mybatis-plus:
  mapper-locations: classpath:mapper/*/*Mapper.xml
  type-aliases-package: com.wyu.tt13mybatisplus.*.model
  global-config:
    refresh-mapper: true

3.数据库表设计:

CREATE TABLE `article` (
  `article_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(128) DEFAULT NULL COMMENT '文章标题',
  `content` longtext COMMENT '正文内容',
  PRIMARY KEY (`article_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='文章表';

4.实体类:

@AllArgsConstructor
@NoArgsConstructor
@Accessors
@Data
@TableName("article")
public class Article implements Serializable {

    private static final long serialVersionUID = 1L;

    //标识主键策略
    @TableId
    private Long articleId;

    private String title;

    private String content;
}

5.ArticleDao接口,另外也可以在这里自定义mybatis接口写sql

@Mapper
public interface ArticleDao extends BaseMapper<Article> {
}

6.ArticleService :


@Service
public class ArticleService {

    @Autowired
    private ArticleDao articleDao;

    /**
     * 1.新增 , insert方法
     * @param article
     * @return
     */
    public boolean save(Article article){
        return articleDao.insert(article) > 0;
    }

    /**
     * 2.通过QueryWrapper查询数量
     */
    public Integer selectArticleCount(){
        return articleDao.selectCount(new QueryWrapper<Article>().eq("title","测试"));
    }

    /**
     * 3.通过selectMaps查询list<Map<String, Object>>
     */
    public List<Map<String, Object>> selectArticleMaps(){
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title", "测试");
        List<Map<String, Object>> list = articleDao.selectMaps(queryWrapper);
        return list;
    }

    /**
     * 4.通过QueryWrapper查询list<Object>
     */
    public List<Object> selectObjs()
    {
        List<Object> list = articleDao.selectObjs(new QueryWrapper<Article>().eq("title", "测试"));
        return list;
    }

    /**
     * 5.分页查询,笔者个人还是比较喜欢使用pagehelper来分页,毕竟比较简单
     */
    public IPage<Article> selectPage()
    {
        QueryWrapper queryWrapper = new QueryWrapper<Article>().eq("title", "测试");
        int count = articleDao.selectCount(queryWrapper);
        IPage<Article> page  = new Page(1,2);
        IPage<Article> list = articleDao.selectPage(page, queryWrapper);

        System.out.println("返回数据:"+ list.getRecords());

        System.out.println("总条数:"+list.getTotal() + "当前页码:"+list.getCurrent()+ "总页码:"+list.getPages() + "每页显示条数:"+list.getSize());

        System.out.println("返回的数据:"+page.getRecords());

        return list;
    }

    /**
     * 6,删除,根据articleId来删除
     */
    public boolean delete(Long articleId)
    {
        return articleDao.deleteById(articleId) > 0;
    }

    /**
     * 7,删除,根据QueryWrapper删除
     */
    public boolean deleteByQueryWrapper()
    {
        return articleDao.delete(new QueryWrapper<Article>().eq("title", "测试")) > 0;
    }

    /**
     * 8, 批量删除,把多个id存放到list中,再批量删除,其实很少会用到
     */
    public boolean deleteBatchIds(List<Long> articleIdList)
    {
        return articleDao.deleteBatchIds(articleIdList) > 0;
    }

    /**
     * 9,修改  封装方法中做了非空校验,如果该字段为null,则不进行更新
     */
    public boolean updateById(Article article) {
        return articleDao.updateById(article) > 0;
    }
}

7.controller:

@RestController
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @RequestMapping("/selectArticleCount")
    public Integer selectArticleCount(){
        return articleService.selectArticleCount();
    }

    @RequestMapping("/selectPage")
    public String selectPage(){
        return articleService.selectPage().toString();
    }
}

6.springboot整合freemarker

1.引入依赖:

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

2.添加配置:

  #------------------------freemarker-----------------------------
spring:
  freemarker:
    cache: false
    suffix: .ftl
    template-loader-path: classpath:/templates
    content-type: text/html; charset=utf-8
    settings:
      number_format: 0   #数字格式,比较大的数字会带有逗号,如1,000

4.Freemarker表达式使用:

  • 获取元素值:
<#if (msg)!="">
     ${msg}
</#if>
  • 循环输出list,先判断list是否为空:
<#if students ?? && students ?size gt 0>
	   <#list students as student>
		    ${student.name}
		    ${student.age}
	   </#list>
</#if>
  • 逻辑判断:
<#if type == 1>
    type=1                                 
<#elseif type == 2>
    type=2
</#if>
  • 格式化输出时间:
${createTime?string('yyyy-MM-dd hh:mm:ss')}
  • include标签,引入其他页面
<#include "right.ftl">

7.springboot整合kafka

1.引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2.添加配置:

spring:
  kafka:              # 指定kafka 代理地址,可以多个
    bootstrap-servers: 192.168.211.137:9092,192.168.211.139:9092,192.168.211.140:9092
    template:    # 指定默认topic id
      default-topic: producer
    listener:   # 指定listener 容器中的线程数,用于提高并发量
      concurrency: 5
    consumer:
      group-id: myGroup # 指定默认消费者group id
      client-id: 200
      max-poll-records: 200
      auto-offset-reset: earliest # 最早未被消费的offset
    producer:
      batch-size: 1000 # 每次批量发送消息的数量
      retries: 3
      client-id: 200

3.生产者

@Slf4j
@Component
public class KafkaProducer {

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    public void send(String topic, Object body) {
        Message<String> message = new Message<>();
        message.setId(System.currentTimeMillis());
        message.setMessage(body.toString());
        message.setTime(new Date());
        String content = null;
        try {
            content = objectMapper.writeValueAsString(message);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        kafkaTemplate.send(topic, content);
        log.info("send {} to {} success!", message, topic);
        System.out.println("send "+ message +" to "+ topic +" success!");
    }
}

4.消费者

@Slf4j
@Component
public class KafkaConsumer {

    /**
     * 有消息就读取,读取消息topic,offset,key,value等信息
     */
    @KafkaListener(topics = {"kafka1"})
    public void listen(ConsumerRecord<?, ?> record) {
        Optional<?> kafkaMessage = Optional.ofNullable(record.value());
        if (kafkaMessage.isPresent()) {
            Object message = kafkaMessage.get();
            log.info("详细消息读取-------------------->");
            log.info("message:{} + record:{}", message, record);
        }
    }

    /**
     * 有消息就读取,批量读取消息
     */
    @KafkaListener(topics = "kafka1")
    public void onMessage(List<String> crs) {
        for(String str : crs){
            log.info("批量读取-------------------->");
            log.info("kafka1:" + str);
        }
    }

    /**
     * 有消息就读取message
     */
    @KafkaListener(topics = {"kafka1"})
    public void receiveMessage(String message){
        log.info("读取message-------------------->");
        log.info("kafka1:" + message);
    }
}

5.Controller:

@Slf4j
@RestController
public class KafkaController {
    @Autowired
    private KafkaProducer kafkaProducer;

    @GetMapping("/kafka/{topic}")
    public String send(@PathVariable("topic") String topic, @RequestParam String message) {
        kafkaProducer.send(topic, message);
        return "success";
    }
}

8.springboot邮件发送

1.添加依赖:

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

2.添加配置:

spring:	
	mail:
	    host: smtp.163.com
	    username: ****@163.com #自己的邮箱账号
	    password: *******  #这个不是登录密码而是163授权登录的密码
	    default-encoding: UTF-8

获取163授权的密码,到163的网页端,把以下两个开关打开
在这里插入图片描述
3.功能测试

@Autowired
    private JavaMailSender javaMailSender;
	
	//发送普通文本邮件
    @RequestMapping(value = "/sendMail")
    public String sendMail(Model model) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("654321***@163.com"); //发送者
        message.setTo("123456***@qq.com");  //接受者
        message.setCc("654321***@163.com"); //抄送,填发送者的邮箱即可
        message.setSubject("今天天气真好");	//主题
        message.setText("你好你好你好!");	//内容
        try {
            javaMailSender.send(message);
            System.out.println("简单邮件已经发送");
        } catch (Exception e) {
            System.out.println("发送简单邮件时发生异常!"+e.toString());
        }
        model.addAttribute("msg", "");
        return "login";
    }
    
 //也可以发送html形式的邮件   
 @RequestMapping("/sendHtmlMail")
    public void sendHtmlMail() {
        String content="<html>\n" +
                "<body>\n" +
                "    <h3>你好你好你好!</h3>\n" +
                "</body>\n" +
                "</html>";
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
            messageHelper.setFrom("654321***@163.com");
            messageHelper.setTo("123456***@qq.com");
            messageHelper.setSubject("今天天气真好");
            messageHelper.setText(content, true);
            javaMailSender.send(message);
            System.out.println("邮件成功发送");
        } catch (MessagingException e) {
            System.out.println("发送邮件时发生异常!"+e.toString());
        }
    }

4.执行效果:
在这里插入图片描述

9.springboot整合redis

1.引入依赖:

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

2.添加配置:

spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
#连接池最大连接数
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间 默认 -1 表示没有限制
spring.redis.jedis.pool.max-wait=-1ms
#连接池最大空闲连接数
spring.redis.jedis.pool.max-idle=8
#连接池最小空闲连接数
spring.redis.jedis.pool.min-idle=0

3.常用方法:
StringRedisTemplate:

//先引入StringRedisTemplate
@Autowired
private StringRedisTemplate stringRedisTemplate;

//向redis里存入数据和设置缓存时间  
stringRedisTemplate.opsForValue().set("redis", "100", 60 * 10, TimeUnit.SECONDS);
//val做-1操作  
stringRedisTemplate.boundValueOps("redis").increment(-1);
//根据key获取缓存中的val  
stringRedisTemplate.opsForValue().get("redis")
//val +1  
stringRedisTemplate.boundValueOps("redis").increment(1);
//根据key获取过期时间  
stringRedisTemplate.getExpire("redis");
//根据key获取过期时间并换算成指定单位  
stringRedisTemplate.getExpire("redis",TimeUnit.SECONDS);
//根据key删除缓存  
stringRedisTemplate.delete("redis");
//检查key是否存在,返回boolean值  
stringRedisTemplate.hasKey("redis");
//向指定key中存放set集合  
stringRedisTemplate.opsForSet().add("redis", "1","2","3");
//设置过期时间  
stringRedisTemplate.expire("redis",1000 , TimeUnit.MILLISECONDS);
//根据key查看集合中是否存在指定数据  
stringRedisTemplate.opsForSet().isMember("redis", "1");
//根据key获取set集合  
stringRedisTemplate.opsForSet().members("redis");
//验证有效时间
Long expire = stringRedisTemplate.boundHashOps("redis").getExpire();
System.out.println("redis有效时间:"+expire+"秒");

10.springboot整合mongodb

1.添加依赖:

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

2.添加如下配置:
itblog表示MongoDB中的itblog库

spring:
  data:
    mongodb:
      uri: "mongodb://192.168.55.1:27017/itblog"

3.编写实体类

@Data
@Document("user")
public class User {
    @Id
    private String id;

    @Field("name")
    private String name;

    @Field("password")
    private String password;

    @Field("address")
    private String address;

    @Field("create_time")
    private Date createTime;

}

4.编写dao

public interface UserDao {
    List<User> findAll();

    User findById(String id);

    User save(User user);

    User insert(User user);

    void deleteById(String id);
}

5.编写service

@Service
public class UserService implements UserDao {

    @Autowired
    private MongoTemplate template;

    @Override
    public List<User> findAll() {
        return template.findAll(User.class);
    }

    @Override
    public User findById(String id) {
        return template.findById(id,User.class);
    }

    @Override
    public User save(User user) {
        return template.save(user);
    }

    @Override
    public User insert(User user) {
        return template.insert(user);
    }

    @Override
    public void deleteById(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        template.remove(query, User.class);
    }
}

6.编写controller


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;


    @GetMapping("")
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public User getByUserId(@PathVariable String userId) {
        return userService.findById(userId);
    }

    @PostMapping("")
    public User addNewUser(@RequestBody User user) {
        if (user.getId() == null) {
            return userService.insert(user);
        }
        return userService.save(user);
    }

    @DeleteMapping("/{id}")
    public String delete(@PathVariable String id) {
        User user = new User();
        user.setId(id);
        userService.deleteById(id);
        return "deleted: " + id;
    }

    @PutMapping("")
    public User update(@RequestBody User user) {
        return userService.save(user);
    }
}

11.SpringBoot整合Swagger

1.引入依赖:

<dependency>
	  <groupId>io.springfox</groupId>
	  <artifactId>springfox-swagger2</artifactId>
	  <version>2.9.2</version>
</dependency>
<dependency>
	  <groupId>io.springfox</groupId>
	  <artifactId>springfox-swagger-ui</artifactId>
	  <version>2.9.2</version>
</dependency>

2.swagger配置类:


@Configuration
@EnableSwagger2
public class SwaggerConfig {
    /**
     * swagger通过配置会生成文档,包括接口名、请求方法、参数、返回信息等
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wyu.tt08mongo"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("基于Swagger构建的Rest API文档")
                .description("MongoDB 在线文档!")
                .termsOfServiceUrl("https://blog.csdn.net/weixin_39025362/article/details/106938581")
                .version("1.0")
                .build();
    }
}

3.执行结果:
在这里插入图片描述

12.SpringBoot自定义注解

1.引入依赖:

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

2.新建一个注解类

//注解的生命周期,表示注解会被保留到什么阶段,可以选择编译阶段、类加载阶段,或运行阶段
@Retention(RetentionPolicy.RUNTIME)
//注解作用的位置,ElementType.METHOD表示该注解仅能作用于方法上
@Target(ElementType.METHOD)
public @interface Note {
    String note() default "";
}

3.新建该类的切面类,记录代码的执行时间


@Aspect
@Component
@Slf4j
public class NoteAspect {

    final static Logger logger = LoggerFactory.getLogger(NoteAspect.class);

    ThreadLocal<Long> beginTime = new ThreadLocal<>();

    /**
     * 其中@Pointcut声明了切点(这里的切点是我们自定义的注解类),
     * @Before声明了通知内容,在具体的通知中,我们通过@annotation(logger)拿到了自定义的注解对象,
     * 所以就能够获取我们在使用注解时赋予的值了。
     */
    @Pointcut("@annotation(note)")
    public void serviceStatistics(Note note) {
    }

    //在切点之前,织入相关代码
    @Before("serviceStatistics(note)")
    public void doBefore(JoinPoint joinPoint, Note note) {
        // 记录请求到达时间
        beginTime.set(System.currentTimeMillis());
        logger.info("cy666 note:{}", note.note());

    }

    //在切点之后,织入相关代码
    @After("serviceStatistics(note)")
    public void doAfter(Note note) {
        logger.info("cy666 statistic time:{}, note:{}", System.currentTimeMillis() - beginTime.get(), note.note());
    }
}

4.在controller上使用该注解

	@RequestMapping("/login")
    @Note(note = "代码执行所需时间")
    public String login(){
        String msg = "success";
        return msg;
    }

13.SpringBoot自定义banner

1.输出效果
在这里插入图片描述

2.在/src/main/resources目录下创建一个banner.txt文件,将字符画复制进去,就能替换默认的banner了
除此之外还可以添加如下设置
1、 ${AnsiColor.BRIGHT_RED}:设置控制台中输出内容的颜色
2、 ${application.version}:用来获取MANIFEST.MF文件中的版本号
3、 a p p l i c a t i o n . f o r m a t t e d − v e r s i o n :格式化后的 {application.formatted-version}:格式化后的 application.formattedversion:格式化后的{application.version}版本信息
4、 ${spring-boot.version}:Spring Boot的版本号
5、 s p r i n g − b o o t . f o r m a t t e d − v e r s i o n :格式化后的 {spring-boot.formatted-version}:格式化后的 springboot.formattedversion:格式化后的{spring-boot.version}版本信息

3.生成ASCII字符网站

14.SpringBoot配置clickhouse

1.添加maven依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.13</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- clickHouse数据库 -->
        <dependency>
            <groupId>ru.yandex.clickhouse</groupId>
            <artifactId>clickhouse-jdbc</artifactId>
            <version>0.1.53</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

2、配属数据源

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
clickhouse:
  driverClassName: ru.yandex.clickhouse.ClickHouseDriver
  url: jdbc:clickhouse://192.168.55.1:8123/default
  password: ck的密码
  initialSize: 10
  maxActive: 100
  minIdle: 10
  maxWait: 6000
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: com.wyu.tt16clickhouse.entity
server:
  port: 8090

3.参数配置

@Data
@Component
public class ChParam {
    private String driverClassName;
    private String url;
    private String password;
    private Integer initialSize;
    private Integer maxActive;
    private Integer minIdle;
    private Integer maxWait;

    @Value("${clickhouse.driverClassName}")
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    @Value("${clickhouse.url}")
    public void setUrl(String url) {
        this.url = url;
    }

    @Value("${clickhouse.password}")
    public void setPassword(String password) {
        this.password = password;
    }

    @Value("${clickhouse.initialSize}")
    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }

    @Value("${clickhouse.maxActive}")
    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    @Value("${clickhouse.minIdle}")
    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    @Value("${clickhouse.maxWait}")
    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }
}

4、Druid连接池配置

@Configuration
public class DruidConfig {

    @Autowired
    private ChParam chParam;

    @Bean
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(chParam.getUrl());
        datasource.setDriverClassName(chParam.getDriverClassName());
        datasource.setInitialSize(chParam.getInitialSize());
        datasource.setMinIdle(chParam.getMinIdle());
        datasource.setMaxActive(chParam.getMaxActive());
        datasource.setMaxWait(chParam.getMaxWait());
        datasource.setPassword(chParam.getPassword());
        return datasource;
    }
}

5、Mapper.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.wyu.tt16clickhouse.UserMapper">

    <select id="queryUser" resultType="com.wyu.tt16clickhouse.entity.User">
        select userId, appId, version, regTime from `default`.`user`
    </select>

    <insert id="insertUser" parameterType="com.wyu.tt16clickhouse.entity.User">
         INSERT INTO `default`.`user` (`userId`, `appId`, `version`, `regTime`)
         VALUES (#{userId}, #{appId}, #{version}, #{regTime})
    </insert>
</mapper>

6、Mapper接口

@Mapper
public interface UserMapper {

    List<User> queryUser();

    Integer insertUser(User user);

}

7.controller接口

@Slf4j
@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/queryUser")
    public Object query(){
        List userList = userMapper.queryUser();
        log.info(userList.toString());
        return userList.toString();
    }

    @RequestMapping("/insertUser")
    public Object insertUser(){
        User user = new User();
        user.setAppId("SS");
        user.setRegTime(new Date());
        user.setUserId(777744);
        user.setVersion("3.2");
        Integer flag = userMapper.insertUser(user);
        return flag;
    }
}


  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高并发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值