SpringBoot + Vue

springboot

Banner

在线生成地址

// 在springboot项目 resources 目录下新建 banner.txt 文件
// 将结果拷贝
    #     #          #         #                      #   #   #        #        #
    ##   ###         ##  ########                     ##  ##  ##       ###########          ##
    ##   ##          ##       ##                      ##  ##  ##       ##  ##  ##          ####
   ##   ##    #     ##       ##                       ##  ##  ##       ##########          ####
   #    ########    ## #    #                         ##  ##  ## #     ##  ##  ##          ####
  ###  ## #  ##   #######   ##                      ###############    ##########          ####
  ### #   ## #      ## ##   ## #                      ##  ##  ##       #   ##  #           ####
 # ##   # ##        ## ##########                     ##  ##  ##         ##  ##             ##
   ##   #####      ## ##    ##        ##              ##  ##  ##        ##    ###           ##
   ##  ##### #     ## ##    ##       ####             ##  ##  ##       ####   # ####        ##
   ##  ## ## ##     ###     ##       ####             ##  ######     ##  ##   ## ##
   ## ##  ##  ##     ###    ##        ##              ##  #   #          ##   ##            ##
   ###    ##  #     ## ##   ##         #              ##                 ##   ##           ####
   ##     ##       ##  ## # ##        #               ##        #       ##    ##            ##
   ##   ####       #   #   ###       #               #############      #     ##
   #      #       #         #                         #                #      #

运行后
在这里插入图片描述

// 修改启动类可操作显示/关闭banner
SpringApplicationBuilder builder = new SpringApplicationBuilder(D1Application.class);
        builder.bannerMode(Banner.Mode.LOG).run(args); // 关闭/显示 banner

编码

<!--pom.xml-->
<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
</properties>
# yaml 配置
#解决返回乱码问题
server:
	servlet:
		encoding:
			charset: UTF-8
			force: true
			enabled: true

配置https

// jdk 安装目录 /bin 打开cmd
	   -alias 别名
    -keypass 指定生成密钥的密码
    -keyalg 指定密钥使用的加密算法(如 RSA)
    -keysize 密钥大小
    -validity 过期时间,单位天
    -keystore 指定存储密钥的密钥库的生成路径、名称
    -storepass 指定访问密钥库的密码


keytool -genkeypair -alias tomcat_https -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore d:/tomcat_https.keystore -storepass 123456

// 生成的文件放在 resources 目录下
# 配置
#https默认端口:443,http默认端口:80
server:
	port: 4439
	http-port: 8082
	#开启https,配置跟证书一一对应
	ssl:
		enabled: true
		#指定证书
		key-store: classpath:tomcat_https.keystore
		key-store-type: JKS
		#密码
		key-store-password: 123456

可能有报错,maven执行clear再运行

// 配置http重指向https
@Configuration
public class SSLUtils {
    
    
    @Bean
    TomcatServletWebServerFactory tomcatServletWebServerFactory(){
    
    
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
    
    
            @Override
            protected void postProcessContext(Context context){
    
    
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        factory.addAdditionalTomcatConnectors(createTomcatConnertor());
        return factory;
    }
    private Connector createTomcatConnertor(){
    
    
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http0");
        connector.setPort(8082);
        connector.setSecure(false);
        connector.setRedirectPort(4439);
        return connector;
    }
}

区分开发/生产环境

# application.yaml
spring:
  profiles:
  	# 区分开发 / 生产
    active: dev  # prod
  application:
	# 应用名称
    name: d1
#https默认端口:443,http默认端口:80
server:
  # http/https 端口
  port: 4439
  http-port: 8082
  #开启https,配置跟证书一一对应
  ssl:
    enabled: true
    #指定证书
    key-store: classpath:tomcat_https.keystore.old
    key-store-type: JKS
    #密码
    key-store-password: 123456
  servlet:
    # utf-8 配置
    encoding:
      charset: UTF-8
      force: true
      enabled: true
book: # 自定义配置
  name: 测试
  author: 999



# application-dev.yaml
server:
  servlet:
    # 请求前缀
    context-path: /dev-api



# application-prod.yaml
server:
  servlet:
    # 请求前缀
    context-path: /prod-api

自定义配置读取

@Component
@ConfigurationProperties(prefix = "book")
public class BookConfig {
    
    
    private String name;
    private String author;
	// get,set,tostring
}


// 使用
@Autowired
BookConfig bookConfig;

整合 Thymeleaf

<!--pom.xml中-->
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
spring:
  # thymeleaf 配置
  thymeleaf:
    # 是否开启缓存,开发时可设置为false,默认true
    cache: true
    # 检查模板是否存在,默认true
    check-template: true
    # 检查模板位置是否存在,默认true
    check-template-location: true
    # 模板文件编码
    encoding: UTF-8
    # 模板位置
    prefix: classpath:/templates/
    # Content-Type 配置
    servlet:
      content-type: text/html
    # 模板文件后缀
    suffix: .html
// 新建 User
public class User {
    
    
    private Integer id;
    private String username;
    private String password;
	// get,set
}
 // Controller
  @GetMapping("/users")
    public ModelAndView users(){
    
    
        List<User> users = new ArrayList<>();
        User u = new User(1,"搜索","123455");
        User u1 = new User(2,"刚刚","321123");
        User u2 = new User(3,"哈哈","555551");
        users.add(u);
        users.add(u1);
        users.add(u2);
        ModelAndView mv = new ModelAndView();
        mv.addObject("users",users);
        mv.setViewName("users");
        return mv;
    }
<!--resources/templates/users.html   新建文件--> 
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <div th:each="user:${users}">
        <span th:text="${user.id}"></span>
        <span th:text="${user.username}"></span>
        <span th:text="${user.password}"></span>
    </div>
</div>
</body>
</html>

整合 FreeMarker

<!--pom.xml中-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
spring:
  freemarker:
    # HttpServletRequest 的属性是否可以覆盖 controller 中的 model 的同明项
    allow-request-override: false
    # HttpSession 的属性是否可以覆盖 controller 中的 model 的同明项
    allow-session-override: false
    # 是否开启缓存,开发时可设置为false,默认true
    cache: false
    # 模板文件编码
    charset: UTF-8
    # 检查模板位置是否存在,默认true
    check-template-location: true
    # Content-Type 配置
    content-type: text/html
    # HttpServletRequest 的属性是否添加到 model
    expose-request-attributes: false
    # HttpSession 的属性是否添加到 model
    expose-session-attributes: false
    # 模板文件后缀
    suffix: .ftl
    # 模板位置
    template-loader-path: classpath:/templates/
 // Controller 同上
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <#if users ??&& (users?size>0)>
        <#list users as user>

            <span>${user.id}</span>
            <span>${user.username}</span>
            <span>${user.password}</span>

        </#list>

    </#if>
</div>
</body>
</html>

整合 Web 开发

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

返回JSON

1.这个依赖默认加入了 json 处理器
在方法上加注解 @ResponseBody 或 在类上使用 @ResponseController
@ResponseController 等同于 @ResponseBody @Controller
2. 自定义json处理器
Gson
fastjson

静态访问

  1. 在 resources/static 新建文件夹下面放静态文件
  2. 自定义静态文件策略
spring:
  mvc:
    static-path-pattern: /static/**
  resources:
    static-locations: classpath:/static/

单文件上传

# yaml 配置
spring:
  servlet:
    multipart:
      # 单文件上传最大
      max-file-size: 10MB
      # 多文件上传最大
      max-request-size: 100MB
<!--upload.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单文件上传</title>
</head>
<body>
<form action="/dev-api/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="uploadFile" value="选择文件" />
  <input type="submit" value="上传" />
</form>
</body>
</html>
@RestController
public class FileUploadController {
    
    
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
    private String uploadPath = "/target/classes/static/uploadFile/";
    @PostMapping("/upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest req) {
    
    
        String realPath = System.getProperty("user.dir")+uploadPath;
        String format = sdf.format(new Date());
        File folder = new File(realPath + format);
        System.out.println(folder.isDirectory());
        if (!folder.isDirectory()) {
    
    
            folder.mkdirs();
        }
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
    
    
            uploadFile.transferTo(new File(folder, newName));
            String filePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/dev-api/static/uploadFile/" + format + newName;
            return filePath;
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return "失败";
    }
}

多文件上传

<!--uploads.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多文件上传</title>
</head>
<body>
<form action="/dev-api/uploads" method="post" enctype="multipart/form-data">
  <input type="file" name="uploadFiles" value="选择文件" multiple/>
  <input type="submit" value="上传" />

</form>
</body>
</html>

    @PostMapping("/uploads")
    public List<String> uploads(MultipartFile[] uploadFiles, HttpServletRequest req) {
    
    
        List<String> strings = new ArrayList<>();
        for (MultipartFile uploadFile : uploadFiles) {
    
    
            strings.add(this.upload(uploadFile, req)); // 调用单文件上传
        }
        return strings;
    }

全局异常处理

@ControllerAdvice
public class CustomExceptionHandler {
    
    
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void upload(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
    
    
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.write("上传文件大小限制");
        out.flush();
        out.close();
    }
}

全局数据

@ControllerAdvice
public class GlobalConfig {
    
    
    @ModelAttribute(value = "info")
    public Map<String,String> userInfo(){
    
    
        HashMap<String,String> map = new HashMap<>();
        map.put("id","0");
        map.put("ids","01");
        return map;
    }
}
@GetMapping("/hello")
    public String hello(Model model){
    
    
        Map<String,Object> map = model.asMap();
        Map<String,Object> maps = model.asMap();
        Set<String> ket = map.keySet();
        Iterator<String> its = ket.iterator();
        Map s = null;
        while (its.hasNext()){
    
    
            String k = its.next();
            Object v = map.get(k);
            if (k.equals("info")){
    
    
                s = (Map) v;
            }
        }
        return (String) s.get("id");
    }

请求参数预处理

/ccc?u.id=1&b.id=9

    @GetMapping("/ccc")
    public String ccc(@ModelAttribute("u") User user,@ModelAttribute("b") Bian bian){
    
    
        return user.toString()+">>"+bian.toString();
    }
@ControllerAdvice
public class GlobalConfig {
    
    
    @InitBinder("u")
    public void init(WebDataBinder webDataBinder){
    
    
        webDataBinder.setFieldDefaultPrefix("u.");
    }
    @InitBinder("b")
    public void init2(WebDataBinder webDataBinder){
    
    
        webDataBinder.setFieldDefaultPrefix("b.");
    }
}

错误页

1.在 resources/static 下新建error
在这里插入图片描述
2. 自定义 error数据

@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
    
    
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
    
    
        Map<String,Object> errorAttr = super.getErrorAttributes(webRequest,options);
        errorAttr.put("zdy","错误了");
        errorAttr.remove("error");
        return errorAttr;
    }
}
  1. 自定义视图
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
    
    
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
    
    
        ModelAndView mv = new ModelAndView("errorPage");
        mv.addObject("zdy","错误了");
        mv.addAllObjects(model);
        return mv;
    }
}
<!--resources/templates/errorPage.html-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>error</title>
</head>
<body>
<div>
  自定义视图
  <div>timestamp: <span th:text="${timestamp}"></span></div>
  <div>status: <span th:text="${status}"></span></div>
  <div>error: <span th:text="${error}"></span></div>
  <div>messages: <span th:text="${#messages}"></span></div>
  <div>path: <span th:text="${path}"></span></div>
  <div>zdy: <span th:text="${zdy}"></span></div>
</div>
</body>
</html>

  1. 完全自定义 (包含2,3)
@Controller
public class MyErrorController extends BasicErrorController {
    
    
    @Autowired
    public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,List<ErrorViewResolver> errorViewResolvers) {
    
    
        super(errorAttributes, serverProperties.getError(),errorViewResolvers);
    }

    @Override
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
    
    
        HttpStatus status = getStatus(request);
        Map<String,Object> model = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.TEXT_HTML));
        model.put("zdy","错误了???????");
        ModelAndView modelAndView = new ModelAndView("errorPage",model,status);
        return modelAndView;
    }

    @Override
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    
    
        Map<String,Object> body = getErrorAttributes(request,isIncludeStackTrace(request,MediaType.ALL));
        body.put("zdy","错误了?????123123??");
        HttpStatus status = getStatus(request);
        
        return new ResponseEntity<>(body,status);
    }
}

CORS 支持

Controller 类加注解 @CrossOrigin

xml 配置

public class Hello {
    
    
    public String sayHellos(String name){
    
    
        return "hellos "+name;
    }
}
<!--resources/beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.Hello" id="hello"></bean>
</beans>
    @Autowired
    Hello hello;
    @GetMapping("/beans")
    public String beans(){
    
    
        return hello.sayHellos("啊啊啊啊啊");
    }

拦截器

public class MyInterceptor1 implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("MyInterceptor1---preHandle");
        return true; // true 才会往下执行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("MyInterceptor1---postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("MyInterceptor1---afterCompletion");
    }
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(new MyInterceptor1())
                .addPathPatterns("/**")   // 拦截的路径
                .excludePathPatterns("/hello");  // 排除路径
    }
}

启动系统任务

  1. CommandLineRunner
    启动任务是加入
    123 3565 999
@Component
@Order(1) // 执行顺序
public class MyCommandLineRunner2 implements CommandLineRunner {
    
    
    @Override
    public void run(String... args) throws Exception {
    
    
        System.out.println("MyCommandLineRunner2---"+ Arrays.toString(args));
    }
}



@Component
@Order(2) // 执行顺序
public class MyCommandLineRunner1 implements CommandLineRunner {
    
    
    @Override
    public void run(String... args) throws Exception {
    
    
        System.out.println("MyCommandLineRunner1---"+ Arrays.toString(args));
    }
}
  1. ApplicationRunner
    启动任务是加入
    –a=a --b=b 123 3565 999
@Component
@Order(1)
public class MyApplicationRunner2 implements ApplicationRunner {
    
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
    
    
        List<String> nonOptionArgs = args.getNonOptionArgs();
        System.out.println("2-nonOptionArgs"+nonOptionArgs);
        Set<String> optionsNames = args.getOptionNames();
        for (String optionsName : optionsNames){
    
    
            System.out.println("2-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
        }
    }
}



@Component
@Order(2)
public class MyApplicationRunner1 implements ApplicationRunner {
    
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
    
    
        List<String> nonOptionArgs = args.getNonOptionArgs();
        System.out.println("1-nonOptionArgs"+nonOptionArgs);
        Set<String> optionsNames = args.getOptionNames();
        for (String optionsName : optionsNames){
    
    
            System.out.println("1-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
        }
    }
}

整合 Servlet Filter Listener

// 启动类上加注解
@ServletComponentScan
@WebServlet("/my")
public class MyServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("name>>>>>"+req.getParameter("name"));
    }
}



@WebFilter("/*")
public class MyFilter implements Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        System.out.println("MyFilter>>init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        System.out.println("MyFilter>>doFilter");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
    
    
        System.out.println("MyFilter>>destroy");
    }
}



@WebListener
public class MyListener implements ServletRequestListener {
    
    
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
    
    
        System.out.println("MyListener>>>>>requestDestroyed");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
    
    
        System.out.println("MyListener>>>>>requestInitialized");
    }
}

路径映射

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    
    
        registry.addViewController("/sun").setViewName("999"); // 第一个:路径  第二个:模板  
    }
}
<!--resources/templates/999.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
999999
</body>
</html>

配置 AOP

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
// service 
@Service
public class UserService {
    
    
    public List<User> users(User user){
    
    
        List<User> users = new ArrayList<>();
        users.add(user);
        return users;
    }
}



@Component
@Aspect
public class LogAspect {
    
    

    @Pointcut("execution(* com.example.d1.service.*.*(..))")
    public void pcl(){
    
    }

    @Before(value = "pcl()")
    public void before(JoinPoint jp){
    
    
        String name = jp.getSignature().getName();
        System.out.println(name+"方法执行开始");
    }

    @After(value = "pcl()")
    public void after(JoinPoint jp){
    
    
        String name = jp.getSignature().getName();
        System.out.println(name+"方法执行结束");
    }

    @AfterReturning(value = "pcl()",returning = "result")
    public void afterReturning(JoinPoint jp,Object result){
    
    
        String name = jp.getSignature().getName();
        System.out.println(name+"方法返回值为:"+result);
    }

    @AfterThrowing(value = "pcl()",throwing = "e")
    public void afterThrowing(JoinPoint jp,Exception e){
    
    
        String name = jp.getSignature().getName();
        System.out.println(name+"方法抛异常为:"+e.getMessage());
    }

    @Around("pcl()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    
    
        return pjp.proceed();
    }

}



@CrossOrigin
@RestController
public class UserController {
    
    
    @Autowired
    UserService userService;

    @GetMapping("/ceshilog")
    public List<User> getUserService() {
    
    
        return userService.users(new User(1,"ceshi","9999"));
    }
}

ico

在 resources/static/ 添加 favicon.ico

去除某个自动配置

启动类上添加注解 @EnableAutoConfiguration(exclude = {某个类.class})

持久层技术

JdbcTemplate

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency> <!--数据库驱动-->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
         <dependency><!--  数据库连接池-->
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
# 数据库配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql:///ssm
    username: root
    password: 521314

在这里插入图片描述

public class Ccc {
    
    
    private int id;
    private String name;
    private String author;
	// get,set...
}
@Repository
public class CccDao {
    
    
    @Autowired
    JdbcTemplate jdbcTemplate;

    public int addCcc(Ccc ccc){
    
    
        return jdbcTemplate.update("INSERT INTO ccc(name,author) VALUES (?,?)",ccc.getName(),ccc.getAuthor());
    }

    public int updateCcc(Ccc ccc){
    
    
        return jdbcTemplate.update("UPDATE ccc SET name =?,author=? WHERE id=?",ccc.getName(),ccc.getAuthor(),ccc.getId());
    }
    
    public int delCcc(int id){
    
    
        return jdbcTemplate.update("DELETE FROM ccc WHERE id=?",id);
    }

    public Ccc getIdCcc(int id){
    
    
        return jdbcTemplate.queryForObject("select * from ccc book where id=?",new BeanPropertyRowMapper<>(Ccc.class),id);
    }
    
    public List<Ccc> getCcc(int id){
    
    
        return jdbcTemplate.query("select * from ccc",new BeanPropertyRowMapper<>(Ccc.class));
    }
}



@Service
public class CccService {
    
    
    @Autowired
    CccDao cccDao;

    public int addCcc(Ccc ccc){
    
    
        return cccDao.addCcc(ccc);
    }

    public int updateCcc(Ccc ccc){
    
    
        return cccDao.updateCcc(ccc);
    }

    public int delCcc(int id){
    
    
        return cccDao.delCcc(id);
    }

    public Ccc getIdCcc(int id){
    
    
        return cccDao.getIdCcc(id);
    }

    public List<Ccc> getCcc(){
    
    
        return cccDao.getCcc();
    }
}


@Autowired
    CccService cccService;
    @GetMapping("/ceshi")
    public String indexs(){
    
    
        System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
        System.out.println("修改:::"+cccService.updateCcc(new Ccc(1,"11111","gasfasfafa")));
        System.out.println("删除:::"+cccService.delCcc(1));
        System.out.println("id:::"+cccService.getIdCcc(2));
        System.out.println("List:::"+cccService.getCcc());
        return "999";
    }

多数据源配置

spring:
  datasource:
    one:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql:///ssm
        username: root
        password: 521314
    two:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql:///bk
        username: root
        password: 521314
// 根据配置生成两个数据源
@Configuration
public class DataSourceConfig {
    
    
    @Bean
    @ConfigurationProperties("spring.datasource.one")
    DataSource dsOne(){
    
    
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.two")
    DataSource dsTwo(){
    
    
        return DruidDataSourceBuilder.create().build();
    }
}
// 配置jdbcTemplate
@Configuration
public class JdbcTemplateConfig {
    
    
    @Bean
    JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne")DataSource dataSource){
    
    
        return new JdbcTemplate(dataSource);
    }
    @Bean
    JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo")DataSource dataSource){
    
    
        return new JdbcTemplate(dataSource);
    }
}
	// Dao 注入JdbcTemplate 时切换
    @Resource(name = "jdbcTemplateTwo")
    JdbcTemplate jdbcTemplate;

MyBatis

类/表与上面一样

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>	<!--mybatis-->
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency> <!--数据库驱动-->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency><!--        数据库连接池-->
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql:///ssm
    username: root
    password: 521314
mybatis:
  mapper-locations: classpath:mapper/*.xml

在这里插入图片描述


@Mapper
public interface CccMapper {
    
    
    int addCcc (Ccc ccc);
    int updateCcc (Ccc ccc);
    int delCcc (int id);
    Ccc getIdCcc (int id);
    List<Ccc> ListCcc ();
}



@Service
public class CccService {
    
    
    @Autowired
    CccMapper cccMapper;

    public int addCcc(Ccc ccc){
    
    
        return cccMapper.addCcc(ccc);
    }

    public int updateCcc(Ccc ccc){
    
    
        return cccMapper.updateCcc(ccc);
    }

    public int delCcc(int id){
    
    
        return cccMapper.delCcc(id);
    }

    public Ccc getIdCcc(int id){
    
    
        return cccMapper.getIdCcc(id);
    }

    public List<Ccc> getCcc(){
    
    
        return cccMapper.ListCcc();
    }
}



@CrossOrigin
@RestController
public class CccController {
    
    
    @Autowired
    CccService cccService;

    @GetMapping("/ceshilog")
    public String cehsi() {
    
    
        System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
        System.out.println("修改:::"+cccService.updateCcc(new Ccc(6,"11111","gasfasfafa")));
        System.out.println("删除:::"+cccService.delCcc(2));
        System.out.println("id:::"+cccService.getIdCcc(6));
        System.out.println("List:::"+cccService.getCcc());
        return "999";
    }
}

<?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.example.d2.mapper.CccMapper">

    <insert id="addCcc" parameterType="com.example.d2.Ccc">
        insert into ccc(name,author) values (#{name},#{author})
    </insert>

    <update id="updateCcc" parameterType="com.example.d2.Ccc">
        UPDATE ccc SET name =#{name},author=#{author} WHERE id=#{id}
    </update>

    <delete id="delCcc" parameterType="int">
        DELETE FROM ccc WHERE id=#{id}
    </delete>

    <select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
        select * from ccc where id=#{id}
    </select>

    <select id="ListCcc" resultType="com.example.d2.Ccc">
        select * from ccc
    </select>
</mapper>

多数据源配置

在这里插入图片描述

spring:
  datasource:
    one:
      type: com.alibaba.druid.pool.DruidDataSource
      jdbc-url: jdbc:mysql:///ssm
      username: root
      password: 521314
    two:
      type: com.alibaba.druid.pool.DruidDataSource
      jdbc-url: jdbc:mysql:///bk
      username: root
      password: 521314
@Configuration
@MapperScan(basePackages = "com.example.d2.mapper", sqlSessionFactoryRef = "OneSqlSessionFactory")//basePackages:接口文件的包路径
public class OneDataSourceConfig {
    
    

    @Bean(name = "OneDataSource")
    // 表示这个数据源是默认数据源
    @Primary//这个一定要加,如果两个数据源都没有@Primary会报错
    @ConfigurationProperties(prefix = "spring.datasource.one")//我们配置文件中的前缀
    public DataSource getOneDateSource() {
    
    
        return DataSourceBuilder.create().build();
    }


    @Bean(name = "OneSqlSessionFactory")
    @Primary
    public SqlSessionFactory OneSqlSessionFactory(@Qualifier("OneDataSource") DataSource datasource)
            throws Exception {
    
    
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper.xml"));
        return bean.getObject();// 设置mybatis的xml所在位置
    }


    @Bean("OneSqlSessionTemplate")
    // 表示这个数据源是默认数据源
    @Primary
    public SqlSessionTemplate OneSqlSessionTemplate(
            @Qualifier("OneSqlSessionFactory") SqlSessionFactory sessionfactory) {
    
    
        return new SqlSessionTemplate(sessionfactory);
    }

}


@Configuration
@MapperScan(basePackages = "com.example.d2.mapperTwo", sqlSessionFactoryRef = "TwoSqlSessionFactory")
public class TwoDataSourceConfig {
    
    

    @Bean(name = "TwoDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.two")
    public DataSource getTwoDataSource() {
    
    
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "TwoSqlSessionFactory")
    public SqlSessionFactory TwoSqlSessionFactory(@Qualifier("TwoDataSource") DataSource datasource)
            throws Exception {
    
    
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper2.xml"));
        return bean.getObject();// 设置mybatis的xml所在位置
    }

    @Bean("TwoSqlSessionTemplate")
    public SqlSessionTemplate TwoSqlSessionTemplate(
            @Qualifier("TwoSqlSessionFactory") SqlSessionFactory sessionfactory) {
    
    
        return new SqlSessionTemplate(sessionfactory);
    }
}


@Mapper
public interface CccMapper {
    
    
    int addCcc (Ccc ccc);
    int updateCcc (Ccc ccc);
    int delCcc (int id);
    Ccc getIdCcc (int id);
    List<Ccc> ListCcc ();
}
<?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.example.d2.mapper.CccMapper">

    <insert id="addCcc" parameterType="com.example.d2.Ccc">
        insert into ccc(name,author) values (#{
    
    name},#{
    
    author})
    </insert>

    <update id="updateCcc" parameterType="com.example.d2.Ccc">
        UPDATE ccc SET name =#{
    
    name},author=#{
    
    author} WHERE id=#{
    
    id}
    </update>

    <delete id="delCcc" parameterType="int">
        DELETE FROM ccc WHERE id=#{
    
    id}
    </delete>

    <select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
        select * from ccc where id=#{
    
    id}
    </select>

    <select id="ListCcc" resultType="com.example.d2.Ccc">
        select * from ccc
    </select>
</mapper>

@Mapper
public interface CccMapper2 {
    
    
    int addCcc (Ccc ccc);
    int updateCcc (Ccc ccc);
    int delCcc (int id);
    Ccc getIdCcc (int id);
    List<Ccc> ListCcc ();
}
<?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.example.d2.mapperTwo.CccMapper2">

    <insert id="addCcc" parameterType="com.example.d2.Ccc">
        insert into ccc(name,author) values (#{
    
    name},#{
    
    author})
    </insert>

    <update id="updateCcc" parameterType="com.example.d2.Ccc">
        UPDATE ccc SET name =#{
    
    name},author=#{
    
    author} WHERE id=#{
    
    id}
    </update>

    <delete id="delCcc" parameterType="int">
        DELETE FROM ccc WHERE id=#{
    
    id}
    </delete>

    <select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
        select * from ccc where id=#{
    
    id}
    </select>

    <select id="ListCcc" resultType="com.example.d2.Ccc">
        select * from ccc
    </select>
</mapper>
@Service
public class CccService {
    
    
//    @Autowired
//    CccMapper cccMapper; // one   这个位置的切换
    @Autowired
CccMapper2 cccMapper;    // two  这个位置的切换

    public int addCcc(Ccc ccc){
    
    
        return cccMapper.addCcc(ccc);
    }

    public int updateCcc(Ccc ccc){
    
    
        return cccMapper.updateCcc(ccc);
    }

    public int delCcc(int id){
    
    
        return cccMapper.delCcc(id);
    }

    public Ccc getIdCcc(int id){
    
    
        return cccMapper.getIdCcc(id);
    }

    public List<Ccc> getCcc(){
    
    
        return cccMapper.ListCcc();
    }
}

@CrossOrigin
@RestController
public class CccController {
    
    
    @Autowired
    CccService cccService;

    @GetMapping("/ceshilog")
    public String cehsi() {
    
    
        System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
        System.out.println("List:::"+cccService.getCcc());
        return "999";
    }
}

Spring Data JPA

新建数据库 demo


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <!--排除springboot2默认的数据源HikariCP,使用druid连接池-->
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: 521314
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    show-sql: true
    database: mysql
    hibernate:
      ddl-auto: update
server:
  port: 9090

//Book
@Entity(name = "s_book")
public class Book {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "book_name",nullable = false)
    private String name;
    @Transient   // 生成数据库表时,不生成该字段
    private String ooo;
    // ...set,get
}

//BookDao
public interface BookDao extends JpaRepository<Book,Integer> {
    
    

    List<Book> getBooksByNameContaining(String name);

    @Query(value = "select * from s_book where id=(select max(id) from s_book)",nativeQuery = true)
    Book getMaxIdBook();

    @Query(value = "select * from s_book where id>:id",nativeQuery = true)
    List<Book> getBookById(@Param("id") Integer id);
}
//BookService
@Service
public class BookService {
    
    
    @Autowired
    BookDao bookDao;
    public Book getMaxIdBook(){
    
    
        return bookDao.getMaxIdBook();
    }
    public List<Book> getBookById(Integer id){
    
    
        return bookDao.getBookById(id);
    }
}
//BookController
@CrossOrigin
@RestController
public class BookController {
    
    
    @Autowired
    BookService bookService;
    @GetMapping("/")
    public String index(){
    
    
        System.out.println("getMaxIdBook:::"+bookService.getMaxIdBook());
        System.out.println("getBookById:::"+bookService.getBookById(1));
        return "99";
    }
}

多数据源配置

在这里插入图片描述

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    primary:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
      username: root
      password: 521314
    secondary:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
      username: root
      password: 521314
  jpa:
    show-sql: true
    database: mysql
    hibernate:
      ddl-auto: update
server:
  port: 9090
//DataSourceConfig
/**
 * 数据库配置
 */
@Configuration
public class DataSourceConfig  {
    
    

    @Primary
    @Bean(value = "primaryDataSource")
    @ConfigurationProperties("spring.datasource.primary") //标红为yml文件中数据源路径:primary
    public DataSource dataSourceOne(){
    
    
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(value = "secondDataSource")
    @ConfigurationProperties("spring.datasource.secondary")//标红为yml文件中数据源路径:secondary
    public DataSource dataSourceTwo(){
    
    
        return DruidDataSourceBuilder.create().build();
    }
}
//PrimaryJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryPrimary",
        transactionManagerRef = "transactionManagerPrimary",
        basePackages = {
    
    "com.example.d3.one"}) //设置Repository所在位置
public class PrimaryJpaConfig {
    
    
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
    
    
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
    
    
        return builder
                .dataSource(primaryDataSource)// 设置数据源
                .properties(jpaProperties.getProperties())// 设置jpa配置
                .properties(getVendorProperties())// 设置hibernate配置
                .packages("com.example.d3.etwo") //设置实体类所在位置
                .persistenceUnit("primaryPersistenceUnit")// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
                .build();
    }

    private Map getVendorProperties() {
    
    
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    @Primary
    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
    
    
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }

}
//SecondJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactorySecond",
        transactionManagerRef = "transactionManagerSecond",
        basePackages = {
    
    "com.example.d3.two"}) //设置Repository所在位置
public class SecondJpaConfig {
    
    
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    @Autowired
    @Qualifier("secondDataSource")
    private DataSource secondDataSource;

    @Bean(name = "secondEntityManager")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
    
    
        return entityManagerFactorySecond(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactorySecond")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond(EntityManagerFactoryBuilder builder) {
    
    
        return builder
                .dataSource(secondDataSource)
                .properties(jpaProperties.getProperties())// 设置jpa配置
                .properties(getVendorProperties())
                .packages("com.example.d3.etwo") //设置实体类所在位置
                .persistenceUnit("secondPersistenceUnit")
                .build();
    }

    private Map getVendorProperties() {
    
    
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    @Bean(name = "transactionManagerSecond")
    public PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {
    
    
        return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());
    }
}
//BookService
@Service
public class BookService {
    
    
    @Autowired
    BookDao bookDao;   // 这个位置切换数据源
    public Book getMaxIdBook(){
    
    
        return bookDao.getMaxIdBook();
    }
    public List<Book> getBookById(Integer id){
    
    
        return bookDao.getBookById(id);
    }
}

整合 redis

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
spring:
  redis:
    # redis 库编号 0-15
    database: 0
    # ip
    host: 192.168.75.129
    # 端口号
    port: 6379
    # 密码
    password: 123456
    jedis:
      pool:
        # 最大连接数
        max-active: 8
        # 最大空闲连接数
        max-idle: 8
        # 最大阻塞等待时间   -1 表示没有限制
        max-wait: -1ms
        # 最小空闲连接数
        min-idle: 0
public class Book implements Serializable {
    
    
    private Integer id;
    private String name;
    private String ooo;
	// get / set
}
	@Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @GetMapping("/redis")
    public String Redis(){
    
    
        ValueOperations<String,String> opsl = stringRedisTemplate.opsForValue();
        opsl.set("id","1");
        System.out.println(opsl.get("id"));
        ValueOperations ops2 = redisTemplate.opsForValue();
        Book b = new Book();
        b.setId(1);
        b.setName("测名称");
        b.setOoo("sadasdasd");
        ops2.set("book",b);
        Book bd = (Book) ops2.get("book");
        System.out.println(bd);
        return "99";
    }

整合 MongoDB

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
spring:
  data:
    mongodb:
      authentication-database: admin
      database: admin
      host: 192.168.75.129
      port: 27017
      username: guoguo
      password: 123456
public class Book implements Serializable {
    
    
    private Integer id;
    private String name;
    private String ooo;
	// get / set
}
public interface BookMongoDB extends MongoRepository<Book,Integer> {
    
    
    List<Book> findByNameContains(String name);
    Book findByNameEquals(String name);
}

@Autowired
    BookMongoDB mongoDB;

    @GetMapping("/mongodb")
    public String mongodb(){
    
    
        List<Book> books = new ArrayList<>();
        Book b1 = new Book();
        b1.setOoo("000");
        b1.setName("名称1");
        b1.setId(1);
        Book b2 = new Book();
        b2.setOoo("22222");
        b2.setName("名称2");
        b2.setId(2);
        books.add(b1);
        books.add(b2);
        mongoDB.insert(books);

        System.out.println(mongoDB.findByNameContains("1"));
        System.out.println(mongoDB.findByNameEquals("名称2"));

        return "99";
    }

Session 共享

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
spring:
  redis:
    # redis 库编号 0-15
    database: 0
    # ip
    host: 192.168.75.129
    # 端口号
    port: 6379
    # 密码
    password: 123456
    jedis:
      pool:
        # 最大连接数
        max-active: 8
        # 最大空闲连接数
        max-idle: 8
        # 最大阻塞等待时间   -1 表示没有限制
        max-wait: -1ms
        # 最小空闲连接数
        min-idle: 0
server:
  port: 9091
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400 * 30)
public class SessionConfig {
    
    
}



/**
 * session共享测试controller
 * 启动两个服务,端口为9090的服务设置session,端口为9091的服务来获取session,测试是否能够获取,实现session共享
 */
@RestController
@RequestMapping("/session")
public class SessionController {
    
    

    @Value("${server.port}")
    private Integer port;

    @GetMapping("/set")
    public String set(HttpSession session) {
    
    
        session.setAttribute("username", "test");
        return String.valueOf(port);
    }
    
    @GetMapping("/get")
    public String get(HttpSession session) {
    
    
        String username = (String) session.getAttribute("username");
        return username + ":" + port;
    }
}

JPA REST

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId> 
        </dependency>
        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--jpa依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--rest依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
spring:
  data:
    rest:
      # 每页查询记录数
      default-page-size: 20
      # 分页查询页码参数名
      page-param-name: page
      # 分页查询记录数参数名
      limit-param-name: size
      # 分页查询排序参数名
      sort-param-name: sort
      # 所有请求加上前缀
      base-path: /api
      # 添加成功是否返回添加内容
      return-body-on-create: true
      # 修改成功是否返回修改内容
      return-body-on-update: true
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: 521314
  jpa:
    show-sql: true
    database: mysql
    hibernate:
      ddl-auto: update
server:
  port: 9090
@Entity(name = "s_book")
public class Book implements Serializable {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "book_name",nullable = false)
    private String name;
    @Transient   // 生成数据库表时,不生成该字段
    private String ooo;
    // get set
}
public interface BookRepository extends JpaRepository<Book,Integer> {
    
    
}
get  http://localhost:9090/books		查询全部  
page=1 size=3 sort=id,desc 第二页  三条记录  id倒叙
get  http://localhost:9090/books/1		根据id查询
post http://localhost:9090/books		新增
put http://localhost:9090/books			修改
delete http://localhost:9090/books/1    根据id删除
@CrossOrigin  // cors
// 自定义路径
@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")//exported = true 暴露出来,false不暴露
public interface BookRepository extends JpaRepository<Book,Integer> {
    
    
//自定义查询方法
// http://localhost:9090/bs/search/name?name=a
    @RestResource(path = "name",rel = "name",exported = true) //exported = true 暴露出来,false不暴露
    List<Book> findByNameContaining(@Param("name")String name);
}

devtools

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
# Idea 需要配置
# devtools 默认不会监听静态文件

在这里插入图片描述

# 按 ctrl + shift + alt + /

在这里插入图片描述
在这里插入图片描述

spring:
  devtools:
    restart:
      # 是否关闭自动重启
      enabled: false

缓存

Ehcache 2.x 缓存

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
// Book
public class Book implements Serializable {
    
    
    private Integer id;
    private String name;
    private String ooo;
    private String uuu;
    // get/set/tostring
}
// BookDao
@Repository
@CacheConfig(cacheNames = "book_cache") // 缓存名称
public class BookDao {
    
    
    @Cacheable
    public Book getBookById(Integer id){
    
    
        System.out.println("getBookById");
        Book b = new Book();
        b.setId(id);
        b.setName("999as十大");
        b.setOoo("1232");
        return  b;
    }
    @CachePut(key = "#book.id")
    public Book updateBookById(Book book){
    
    
        System.out.println("updateBookById");
        book.setOoo("oooooooooo");
        return book;
    }
    @CacheEvict(key = "#id")
    public void delBookById(Integer id){
    
    
        System.out.println("delBookById");
    }
}

// 启动类上添加
@EnableCaching // 开启缓存
spring:
  cache:
    ehcache:
      config: classpath:ehcache.xml # 重命名缓存配置文件位置
<!--ehcache.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!--
       diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
       user.home – 用户主目录
       user.dir  – 用户当前工作目录
       java.io.tmpdir – 默认临时文件路径
     -->
    <diskStore path="java.io.tmpdir/cache"/>
    <!--
       defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
     -->
    <!--
      name:缓存名称。
      maxElementsInMemory:缓存最大数目
      maxElementsOnDisk:硬盘最大缓存个数。
      eternal:对象是否永久有效,一但设置了,timeout将不起作用。
      overflowToDisk:是否保存到磁盘,当系统当机时
      timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
      timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
      diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
      diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
      diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
      memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
      clearOnFlush:内存数量最大时是否清除。
      memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
      FIFO,first in first out,这个是大家最熟的,先进先出。
      LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
      LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
   -->
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"/>
    <cache
            name="book_cache"
            eternal="true"
            maxElementsInMemory="10000"
            overflowToDisk="true"
            diskPersistent="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="600"/>
</ehcache>

@Autowired
BookDao bookDao;
    @Test
    void contextLoads() {
    
    
        bookDao.getBookById(1);
        bookDao.getBookById(1);
        bookDao.delBookById(1);
        Book b3 = bookDao.getBookById(1);
        System.out.println("b3:"+b3);
        Book b = new Book();
        b.setOoo("妗?);
        b.setName("鍐滄潙");
        b.setId(1);
        bookDao.updateBookById(b);
        Book b4 = bookDao.getBookById(1);
        System.out.println("b4--"+b4);
    }

Redis 单机缓存

Vue

猜你喜欢

转载自blog.csdn.net/weixin_45381071/article/details/129654042
今日推荐