您当前的位置: 首页 >  Java

彭世瑜

暂无认证

  • 0浏览

    0关注

    2791博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java笔记:SpringBoot开发常用技术整合

彭世瑜 发布时间:2020-11-26 22:57:36 ,浏览量:0

一、构建springboot工程

参考源码地址 https://github.com/leechenxiang/imooc-springboot-starter

可选IDE STS Spring Tool Suit

快速开始:https://spring.io/quickstart

配置文件 application.properties


############################################################
#
# 开发模式设置
#
############################################################

# 热部署生效
spring.devtools.restart.enabled=true

# 监听目录
spring.devtools.restart.additional-paths=src/main/java

#spring.devtools.restart.exclude=static/**,public/**
#spring.devtools.restart.exclude=WEB-INF/**


############################################################
#
# server 服务端配置
#
############################################################

server.port=8080

#server.servlet.context-path=/demo
#server.error.path=/error
#server.address=192.168.1.2
#server.session-timeout=60

############################################################
#
# server.tomcat 服务端配置
#
############################################################

#server.tomcat.max-threads=250
server.tomcat.uri-encoding=UTF-8
#server.tomcat.basedir=H:/springboot-tomcat-tmp
#server.tomcat.access-log-enabled=true
#server.tomcat.access-log-pattern=
#server.tomcat.accesslog.directory=
#logging.path=H:/springboot-tomcat-tmp
#logging.file=myapp.log

二、接口返回json
# 时间格式化
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-dates-as-timestamps=false

package com.example.demo.pojo;

/**
 * 统一的返回封装
 */
public class JsonResult {
    private Integer code;
    private String msg;
    private Object data;

    public JsonResult(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static JsonResult success(Object data){
        return new JsonResult(0, "success", data);
    }

    public static JsonResult error(String errorMessage) {
        return new JsonResult(-1, errorMessage, null);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

package com.example.demo.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

import java.util.Date;

/**
 * jackson注解使用示例
 */
@Data
public class User {

    private String name;
    private Integer age;

    // 忽略显示
    @JsonIgnore
    private String password;

    // 格式化
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", locale="zh", timezone="GMT+8")
    private Date birthday;

    // 为空不显示
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String desc;

}

三、热部署


    org.springframework.boot
    spring-boot-devtools
    true

IDEA需要做额外的配置

四、资源属性配置

resource.properties

# 配置文件
com.demo.name=MyBlog
com.demo.language=zh

package com.example.demo.pojo;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * 资源文件中的配置映射到实体类
 */
@Configuration
@ConfigurationProperties(prefix = "com.demo")
@PropertySource(value = "classpath:resource.properties")
public class Resource {
    private String name;
    private String language;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }
}

五、模板引擎


    org.springframework.boot
    spring-boot-starter-freemarker




    org.springframework.boot
    spring-boot-starter-thymeleaf



############################################################
#
# freemarker
#
############################################################

# 上线改为true
spring.freemarker.cache=false
#spring.freemarker.template-loader-path=classpath:/templates
#spring.freemarker.charset=UTF-8
#spring.freemarker.check-template-location=true
#spring.freemarker.content-type=text/html
#spring.freemarker.expose-request-attributes=true
#spring.freemarker.expose-session-attributes=true
#spring.freemarker.request-context-attribute=request
#spring.freemarker.suffix=.ftl

############################################################
#
# thymeleaf
#
#############################################################
# 上线改为true
spring.thymeleaf.cache=false
#spring.thymeleaf.prefix=classpath:/templates/
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.mode=HTML5
#spring.thymeleaf.encoding=UTF-8
#spring.thymeleaf.servlet.content-type=text/html

# 静态文件
spring.mvc.static-path-pattern=/static/**

freemarker

freemarker

${resource.name}
${resource.language}

thymeleaf

基本使用方式 对象引用方式 时间类型转换 text与utext URL 引入静态资源文件js/css 条件判断th:if与th:unless 循环th:each 分支th:switch与th:case




    
    Title
    



基本语法




日期格式化


简便写法

    
    
    


text与utext
text: 
utext: 

网址
www.baidu.com

表单

    
    
    


判断
 age == 20
 age > 20
 age < 20
 age >= 20
 age 
    20
    18


循环

    


分支

    超级管理员
    管理员
    普通会员



六、异常处理

通用异常 web和ajax

package com.example.demo.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

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

/**
 * 处理错误页面
 */
@ControllerAdvice
public class CustomExceptionHandler {
    public static final String ERROR_VIEW = "thymeleaf/error";

    @ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest request,
                               HttpServletResponse response, Exception e) throws Exception {

        if (isAjax(request)) {
            ModelAndView model = new ModelAndView(new MappingJackson2JsonView());
            model.addObject("data", null);
            model.addObject("code", -1);
            model.addObject("msg", e.getMessage());
            return model;
        } else {
            ModelAndView model = new ModelAndView();
            model.addObject("exception", e);
            model.addObject("url", request.getRequestURL());
            model.setViewName(ERROR_VIEW);

            return model;
        }

    }

    /**
     * 判断是否为ajax
     *
     * @param request
     * @return
     */
    public boolean isAjax(HttpServletRequest request) {
        String ContentType = request.getHeader("Content-Type");
        String Accept = request.getHeader("Accept");

        if (ContentType != null &&
                ContentType.contains("json")) {
            return true;
        } else if (Accept != null &&
                Accept.contains("json")) {
            return true;
        } else {
            return false;
        }
    }


}

处理ajax错误

package com.example.demo.exception;

import com.example.demo.pojo.JsonResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

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

/**
 * 处理ajax错误
 */
@RestControllerAdvice
public class AjaxExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public JsonResult errorHandler(HttpServletRequest request,
                               HttpServletResponse response, Exception e) throws Exception {

        return JsonResult.error(e.getMessage());
    }
}

七、MyBatis

依赖引入pom.xml



    mysql
    mysql-connector-java
    8.0.20



    com.alibaba
    druid
    1.1.0



    com.alibaba
    druid-spring-boot-starter
    1.1.9




    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    1.3.1






    tk.mybatis
    mapper-spring-boot-starter
    2.0.0




    com.github.pagehelper
    pagehelper-spring-boot-starter
    1.2.3



    org.mybatis.generator
    mybatis-generator-core
    1.3.2
    compile
    true

参数配置 application.properties

############################################################
#
# druid
#
############################################################
spring.datasource.url=jdbc:mysql://localhost:3306/data
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
#spring.datasource.druid.stat-view-servlet.allow=true


############################################################
#
# mybatis
# https://github.com/abel533/MyBatis-Spring-Boot
############################################################
mybatis.type-aliases-package=com.example.demo.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

# 通用mapper
mapper.mappers=com.example.demo.utils.MyMapper
mapper.not-empty=false
mapper.identity=MYSQL

# 分页插件
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

自动代码生成配置 generatorConfig.xml





    
        
        

        
            
        

        
        

        
        

        
        

        
        


        
         
    

逆向工程工具

package com.example.demo.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class GeneratorDisplay {

    public void generator() throws Exception{

        List warnings = new ArrayList();
        boolean overwrite = true;
        // 指定 逆向工程配置文件
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                callback, warnings);
        myBatisGenerator.generate(null);

    } 
    
    public static void main(String[] args) throws Exception {
        try {
            GeneratorDisplay generatorSqlmap = new GeneratorDisplay();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

通用Mapper


package com.example.demo.utils;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * 继承自己的MyMapper
 */
public interface MyMapper extends Mapper, MySqlMapper {
    //TODO
    //FIXME 特别注意,该接口不能被扫描到,否则会出错
}

package com.example.demo.mapper;

import com.example.demo.pojo.SysUser;
import com.example.demo.utils.MyMapper;

public interface UserMapper extends MyMapper {
}

自定义Mapper

package com.example.demo.mapper;

import com.example.demo.pojo.Person;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

// 自定义Mapper
public interface PersonMapper {
    Person queryUserById(Integer id);

    @Transactional(propagation= Propagation.REQUIRED)
    void deleteById(Integer id);

    @Transactional(propagation= Propagation.REQUIRED)
    void updateById(Person person);
}
package com.example.demo.pojo;

import lombok.Data;

@Data
public class Person {

    private Integer id;
    private String name;
    private Integer age;
}





    
    select
        id, name, age
    from
        person
    where
        id = #{id, jdbcType=INTEGER}
    limit 1

 

    
        update person
        set name = #{name}, age = #{age}
        where id = #{id}
    

    
        delete from person
        where id = #{id}
    

mybatis generatorConfig生成mapper和pojo 实现CURD mybatis-pagehelper实现分页 自定义mapper实现 xml形式的sql形式有利于后期调优 使用包含pagehelper分页的MyBatis的开源框架: https://github.com/abel533/MyBatis-Spring-Boot

事务: 事务隔离级别 default read_uncommitted read_committed repeatable_read serializable

事务传播行为 required 有事务直接用,没有新建事务 supports 有事务直接用,没有也可以 mandatory requires_new not_supported never nested

使用场景

@Transactional(propagation=Propagation.SUPPORTS)查询

@Transactional(propagation=Propagation.REQUIRED)增加,删除,修改

解决devtools与Mapper冲突

添加配置文件 META-INF/spring-devtools.properties

restart.include.hifi=/hifi-[\\w-\\.\\d]+.jar
restart.include.mybatis=/mybatis-[\\w-\\.\\d]+.jar
restart.include.mapper=/mapper-[\\w-\\.\\d]+jar
restart.include.pagehelper=/pagehelper-[\\w-\\.\\d]+jar
八、redis

引入依赖



    org.springframework.boot
    spring-boot-starter-data-redis

配置

############################################################
#
# REDIS
#
############################################################

spring.redis.database=1
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=1000
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=2
spring.redis.timeout=0

使用

package com.example.demo.controller;

import com.example.demo.pojo.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class RedisController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("/redis")
    public JsonResult error() {
        redisTemplate.opsForValue().set("name", "Tom");

        return JsonResult.success(redisTemplate.opsForValue().get("name"));
    }


}
九、定时任务
@EnableScheduling // 开启定时任务
package com.example.demo.task;

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

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

@Component
public class HelloTask {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    // 每3秒执行一次
    @Scheduled(fixedRate = 3000)
    public void echo(){
        System.out.println("echo: " + dateFormat.format(new Date()));
    }

  
}

十、异步任务
@EnableAsync // 开启异步任务
package com.example.demo.task;

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

@Component
public class HelloTask {
 
    @Async
    public void sayHello() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

十一、拦截器

定义拦截器

package com.example.demo.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class HelloInterceptor implements HandlerInterceptor {

    // 请求处理之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");

        if("Tom".equals(request.getParameter("key"))){
            System.out.println("被拦截");
            return false;
        } else{
            System.out.println("放行");
            return true;
        }
    }

    // 请求处理之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

注册拦截器

package com.example.demo.config;

import com.example.demo.interceptor.HelloInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//WebMvcConfigurerAdapter已经被废弃了
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    // 拦截器按照顺序执行
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HelloInterceptor()).addPathPatterns("/**");
    }
}

关注
打赏
1665367115
查看更多评论
立即登录/注册

微信扫码登录

0.1043s