• springboot


    一,Spring Boot 介绍

     

    1,如果使用 Spring 开发一个"HelloWorld"的 web 应用:

     
    • 创建一个 web 项目并且导入相关 jar 包。SpringMVC Servlet
    • 创建一个 web.xml
    • 编写一个控制类(Controller)
    • 需要一个部署 web 应用的服务器 如 tomcat
     

    2,Spring Boot 特点:

     
    • Spring Boot 设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
    • 嵌入的 Tomcat,无需部署 WAR 文件
    • Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方
    式。

    二,构建 Spring Boot 项目及启动器讲解

     

    1.使用 maven 构建 SpringBoot 项目

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
      </parent>
      <groupId>com.bjsxt</groupId>
      <artifactId>01-spring-boot-hello</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      
      <!-- 修改jdk版本 -->
      <properties>
          <java.version>1.7</java.version>
      </properties>
      
      <dependencies>
      <!-- springBoot的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    </project>
    View Code
    package com.bjsxt.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * SpringBoot HelloWorld
     * @author Administrator
     *
     */
    @Controller
    public class HelloWorld {
    
        @RequestMapping("/hello")
        @ResponseBody
        public Map<String, Object> showHelloWorld(){
            Map<String, Object> map = new HashMap<>();
            map.put("msg", "HelloWorld");
            return map;
        }
    }
    View Code
    package com.bjsxt.controller;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * SpringBoot 启动类
     * @author Administrator
     *
     */
    @SpringBootApplication
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    View Code

    2.修改 pom 文件 将 jdk 的版本更新为 1.7

    3.注入 SpringBoot 启动坐标 

     <!-- springBoot的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    4.SpringBoot 启动器。

     
    所谓的 springBoot 启动器其实就是一些 jar 包的集合。SprigBoot 一共提供 44 启动器。
     

    4.1 spring-boot-starter-web

     
    支持全栈式的 web 开发,包括了 romcat 和 springMVC 等 jar
     

    4.2 spring-boot-starter-jdbc

     
    支持 spring 以 jdbc 方式操作数据库的 jar 包的集合
     

    4.3 spring-boot-starter-redis

    支持 redis 
     

    5.关于编写启动器需要注意的问题

     
    启动器存放的位置。启动器可以和 controller 位于同一个包下,或者位于 controller 的上一级
    包中,但是不能放到 controller 的平级以及子包下。
     

    一,整合 Servlet

     
    1,通过注解扫描完成 Servlet 组件的注册
     
    1.1 编写 servlet
    /***SpringBoot 整合 Servlet 方式一 **<servlet> * <servlet-name>FirstServlet</servlet-name> * <servlet-class>com.bjsxt.servlet.FirstServlet</servlet-class> *</servlet> **<servlet-mapping> * <servlet-name>FirstServlet</servlet-name> * <url-pattern>/first</url-pattern> *</servlet-mapping> **/
    package com.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * springboot整合servelt方式一
     * @author Administrator
     *
     */
    @WebServlet(name="FirstServlet",urlPatterns="/first")
    public class FirstServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("servlet执行了");
        }
    }
    View Code
    1.2 编写启动类
    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    @SpringBootApplication
    @ServletComponentScan //在springboot启动时会扫描@WebServlet.并将该类实例化
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    
    }
    View Code
    2,通过方法完成 Servlet 组件的注册
     
    2.1 编写 servlet
    package com.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class SecondServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("SecondServlet...");
        }
    
    }
    View Code
    2.2 编写启动类
    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    
    import com.servlet.SecondServlet;
    
    /**
     * springboot整合Servlet方式二
     * @author Administrator
     *
     */
    @SpringBootApplication
    public class App2 {
        public static void main(String[] args) {
            SpringApplication.run(App2.class, args);
        }
        @Bean
        public ServletRegistrationBean getServletRegistrationBean() {
            ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
            bean.addUrlMappings("/second");
            return bean;
            
        }
    }
    View Code

    二,整合 Filter

    1,通过注解扫描完成 Filter 组件的注册
    1.1 编写 Filter
    package com.bjsxt.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    
    /**
     *SpringBoot整合Filter 方式一
     *<filter>
     *    <filter-name>FirstFilter</filter-name>
     *    <filter-class>com.bjsxt.filter.FirstFilter</filter-class>
     *</filter>
     *<filter-mapping>
     *    <filter-name>FirstFilter</filter-name>
     *    <url-pattern>/first</url-pattern>
     *</filter-mapping>
     */
    //@WebFilter(filterName="FirstFilter",urlPatterns={"*.do","*.jsp"})
    @WebFilter(filterName="FirstFilter",urlPatterns="/first")
    public class FirstFilter implements Filter {
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
    
        }
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
                throws IOException, ServletException {
            System.out.println("进入Filter");
            arg2.doFilter(arg0, arg1);
            System.out.println("离开Filter");
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
            // TODO Auto-generated method stub
        }
    }
    View Code
    1.2 编写启动类
    package com.bjsxt;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    /**
     *SpringBoot整合Filter 方式一
     *
     */
    @SpringBootApplication
    @ServletComponentScan
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
    
        }
    
    }
    View Code
    2,通过方法完成 Filter 组件的注册
     
    2.1 编写 Filter
    package com.bjsxt.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    /**
     * 
     *SpringBoot整合Filter 方式二
     *
     */
    public class SecondFilter implements Filter {
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
        }
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
                throws IOException, ServletException {
            System.out.println("进入SecondFilter");
            arg2.doFilter(arg0, arg1);
            System.out.println("离开SecondFilter");
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
            // TODO Auto-generated method stub
        }
    }
    View Code
    2.2 编写启动类
    package com.bjsxt;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    
    import com.bjsxt.filter.SecondFilter;
    import com.bjsxt.servlet.SecondServlet;
    
    /**
     * SpringBoot整合Filter方式二
     *
     *
     */
    @SpringBootApplication
    public class App2 {
    
        public static void main(String[] args) {
            SpringApplication.run(App2.class, args);
        }
        
        /**
         * 注册Servlet
         * @return
         */
        @Bean
        public ServletRegistrationBean getServletRegistrationBean(){
            ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
            bean.addUrlMappings("/second");
            return bean;
        }
        
        /**
         * 注册Filter
         */
        @Bean
        public FilterRegistrationBean getFilterRegistrationBean(){
            FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
            //bean.addUrlPatterns(new String[]{"*.do","*.jsp"});
            bean.addUrlPatterns("/second");
            return bean;
        }
    }
    View Code

    2.3编写servlet

    package com.bjsxt.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    /**
     *SpringBoot整合Servlet方式一
     *
     *<servlet>
     *    <servlet-name>FirstServlet</servlet-name>
     *    <servlet-class>com.bjsxt.servlet.FirstServlet</servlet-class>
     *</servlet>
     *
     *<servlet-mapping>
     * <servlet-name>FirstServlet</servlet-name>
     * <url-pattern>/first</url-pattern>
     *</servlet-mapping>
     *
     */
    
    @WebServlet(name="FirstServlet",urlPatterns="/first")
    public class FirstServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("FirstServlet............");
        }
    }
    View Code
    package com.bjsxt.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     *SpringBoot整合Servlet方式二
     *
     */
    
    public class SecondServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("SecondServlet..........");
        }
        
    }
    View Code

    三,整合 Listener

     
    1,通过注解扫描完成 Listener 组件的注册
     
    1.1 编写 Listener
     
    package com.listener;
    
    import javax.servlet.ServletContextEvent;
    /**
     * springboot 整合listener
     * <listener>
     *     <listener-class>com.listener.FirstListener</listener-class>
     * </listener>
     * 
     */
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    @WebListener
    public class FirstListener implements ServletContextListener {
    
        @Override
        public void contextDestroyed(ServletContextEvent arg0) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void contextInitialized(ServletContextEvent arg0) {
            System.out.println("listen....init.....");
        }
    
    }
    View Code
    1.2 编写启动类
    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    /**
     * springboot 整合listener方式一
     * @author Administrator
     *
     */
    @SpringBootApplication
    @ServletComponentScan
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    View Code
    2. 通过方法完成 Listener 组件注册
     
    2.1 编写 Listener
    package com.listener;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    /**
     * springBoot整合Listener方式二
     * @author Administrator
     *
     */
    
    public class SecondListener implements ServletContextListener {
    
        @Override
        public void contextDestroyed(ServletContextEvent arg0) {
    
        }
    
        @Override
        public void contextInitialized(ServletContextEvent arg0) {
            System.out.println("secondlistener...init...");
        }
    
    }
    View Code
    2.2 编写启动类
    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    
    import com.filter.SecondFilter;
    import com.listener.SecondListener;
    import com.servlet.SecondServlet;
    
    /**
     * SpringBoot整合listener方式二
     * @author Administrator
     *
     */
    @SpringBootApplication
    public class App2 {
        public static void main(String[] args) {
            SpringApplication.run(App2.class, args);
        }
        /**
         * 注册servlet
         * @return
         *//*
        @Bean
        public ServletRegistrationBean getServletRegistrationBean() {
            ServletRegistrationBean bean=new ServletRegistrationBean(new SecondServlet());
            bean.addUrlMappings("/second");
            return bean;
            
        }*/
        /**
         * 注册filter
         */
        /*@Bean
        public FilterRegistrationBean getFistrationBean() {
             FilterRegistrationBean bean=new FilterRegistrationBean(new SecondFilter());
             //bean.addUrlPatterns(new String[] {"*.do","*.jsp"});
             bean.addUrlPatterns("/second");
            return bean;
            
        }*/
        /**
         * 注册listener
         */
        @Bean
        public ServletListenerRegistrationBean<SecondListener> getServletListenerRegistrationBean(){
            ServletListenerRegistrationBean<SecondListener> bean=new ServletListenerRegistrationBean<>(new SecondListener());
            
            return bean;
            
        }
    }
    View Code

    四,访问静态资源

     
    1. SpringBoot 从 classpath/static 的目录
     
    注意目录名称必须是 static
    2. ServletContext 根目录下 
    package com.app;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * SpringBoot 启动类
     * @author Administrator
     *
     */
    @SpringBootApplication
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    View Code

    五,文件上传

     
    1. 编写 Controller 
    package com.controller;
    
    import java.io.File;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    /**
     * SpringBoot文件上传
     *
     *
     */
    //@Controller
    @RestController //表示该类下的方法的返回值会自动做json格式的转换
    public class FileUploadController {
    
        /*
         * 处理文件上传
         */
        @RequestMapping("/fileUploadController")
        public Map<String, Object> fileUpload(MultipartFile filename)throws Exception{
            System.out.println(filename.getOriginalFilename());
            filename.transferTo(new File("e:/"+filename.getOriginalFilename()));
            Map<String, Object> map = new HashMap<>();
            map.put("msg", "ok");
            return map;
        }
    }
    View Code
    2. 编写启动类 
    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * SpringBoot 启动类
     * Springboot 文件上传
     * @author Administrator
     *
     */
    @SpringBootApplication
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    View Code
    3. 设置上传文件大小的默认值 
    设置单个上传文件的大小
    spring.http.multipart.maxFileSize=200MB
    设置一次请求上传文件的总容量
    spring.http.multipart.maxRequestSize=200MB
     
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html >
      <head>
        <title>upload.html</title>
        
        <meta name="keywords" content="keyword1,keyword2,keyword3">
        <meta name="description" content="this is my page">
       <!--  <meta name="content-type" content="text/html; charset=UTF-8"> -->
        <meta charset="UTF-8">
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
    
      </head>
      
      <body>
            <form action="fileUploadController" method="post" enctype="multipart/form-data">
                上传文件:<input type="file" name="filename"/><br>
                <input type="submit">
            </form>
      </body>
    </html>
    View Code

    Spring Boot 第三章(视图层技术)

     
    课程介绍:
     整合 jsp
     整合 freemarker
     整合 Thymeleaf
     

    一,SpringBoot 整合 jsp 技术

     

    1,创建项目

     

    2,修改 pom 文件,添加坐标

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
      </parent>
       <groupId>com</groupId>
      <artifactId>08-spring-boot-view-jsp</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <!-- jdk1.7 -->
      
      <properties>
          <java.version>1.7</java.version>
      </properties>
      
     <dependencies>
      <!-- springBoot的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
            <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- jasper -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
      
    </project>
    View Code

    3,创建 springBoot 的全局配置文件,application.properties 

     
    spring.mvc.view.prefix=/WEB-INF/jsp/
    spring.mvc.view.suffix=.jsp 
     

    4,创建 Controller 

    package com.controller;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.pojo.Users;
    
    /**
     * springBoot整合jsp
     * @author Administrator
     *
     */
    @Controller
    public class UserController {
        
        /**
         * 处理请求,产生数据
         */
        @RequestMapping("/showUser")
        public String showUser(Model model) {
            List<Users> list=new ArrayList<>();
            list.add(new Users(1,"张三",20));
            list.add(new Users(2,"李四",22));
            list.add(new Users(3,"王五",25));
            
            //需要一个Model对象
            model.addAttribute("list", list);
            //跳转视图
            return "userList";
        }
    }
    View Code

    5,创建 jsp 

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        
        <table border="1" align="center" width="50%">
            <tr>
            <th>ID</th>                     
            <tr>Name</th>
            <th>Age</th>
            </tr>
            <c:forEach items="${list}" var="user">
                <tr>
                    <td>${user.userid}</td>
                    <td>${user.username}</td>
                    <td>${user.userage}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
    </html>
    View Code

    6,创建启动类 

    package com.bjsxt;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * SpringBoot启动类
     *
     *
     */
    @SpringBootApplication
    public class App {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    View Code

    二,SpringBoot 整合 Freemarker

     

    1,创建项目 

    2,修改 pom 添加坐标

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
      </parent>
      <groupId>com</groupId>
      <artifactId>09-spring-boot-view-freemarker</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      
      <properties>
          <java.version>1.7</java.version>
      </properties>
      <dependencies>
      <!-- springBoot的启动器 -->
        <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>
      </dependencies>
    </project>
    View Code

    3,编写视图

     
    注意:springBoot 要求模板形式的视图层技术的文件必须要放到 src/main/resources 目录下必
    须要一个名称为 templates
     
    userList.ftl
    <html>
        <head>
            <title>展示用户数据</title>
            <meta charset="utf-9"></meta>
        </head>
        
        <body>
            
            <table border="1" align="center" width="50%">
                
                <tr>
                    
                    <th>ID</th>
                    <th>Name</th>
                    <th>Age</th>
                </tr>
                
                <#list list as user >
                    <tr>
                        <td>${user.userid}</td>
                        <td>${user.username}</td>
                        <td>${user.userage}</td>
                    </tr>
                </#list>    
            </table>
        </body>
    </html>
    View Code

    4,创建 Controller

    package com.bjsxt.controller;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.bjsxt.pojo.Users;
    
    /**
     * SpringBoot整合jsp
     *
     *
     */
    @Controller
    public class UserController {
        /*
         * 处理请求,产生数据
         */
        @RequestMapping("/showUser")
        public String showUser(Model model){
            List<Users> list = new ArrayList<>();
            list.add(new Users(1,"张三",20));
            list.add(new Users(2,"李四",22));
            list.add(new Users(3,"王五",24));
            
            //需要一个Model对象
            model.addAttribute("list", list);
            //跳转视图
            return "userList";
        }
    }
    View Code

    5,创建启动器

    package com;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    }
    View Code

    三,SpringBoot 整合 Thymeleaf (重点讲解)

     
    1. 创建 Thymeleaf 的入门项目
     
    1.1 创建项目

    1.2 修改 pom 文件添加坐标 

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
       <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
      </parent>
      <groupId>com</groupId>
      <artifactId>10-spring-boot-view-thymeleaf</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      
      <properties>
          <java.version>1.7</java.version>
      </properties>
      <dependencies>
      <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>
      </dependencies>
    </project>
    View Code

    1.3 创建存放视图的目录

     
    目录位置:src/main/resources/templates
    templates:该目录是安全的。意味着该目录下的内容是不允许外界直接访问的。 
     

    2. Thymeleaf 的基本使用

     
    2.1Thymeleaf 特点:
     
    Thymelaef 是通过他特定语法对 html 的标记做渲染。
     
     
    /*** Thymeleaf 入门案例 ***/ @Controller public class DemoController { @RequestMapping("/show") public String showInfo(Model model){ model.addAttribute("msg", "Thymeleaf 第一个案例"); return "index"; } }
    View Code
    2.3 创建视图 .html
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Thymeleaf 入门</title> </head> <body> <span th:text="Hello"></span> <hr/> <span th:text="${msg}"></span> </body> </html>
    View Code
    2.4 编写启动类
    /****Thymeleaf 入门案例 **/ @SpringBootApplication public class App {
    public static void main(String[] args) { SpringApplication.run(App.class, args); } }
    View Code
    2.5 解决异常
    2.5.1 解决异常方式 1
     
    让 html 的标记按照严禁的语法去编写。
     
    2.5.2 解决异常方式 2 
     
    Thymeleaf.jar:更新为 3.0 以上的版本
    thymeleaf-layout-dialect.jar:更新为 2.0 以上的版本 
     
    更换 thymeleaf 的 jar 包的版本 
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>10-spring-boot-view-thymeleaf</artifactId> <version>0.0.1-SNAPSHOT</version>
    <properties> <java.version>1.7</java.version> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.versi on></properties> <dependencies> <!-- springBoot 的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springBoot 的启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> </project>
    View Code

    3. Thymeleaf 语法详解

     
    3.1 变量输出与字符串操作
     

    3.1.1th:text 

     
    th:text
     
    在页面中输出值 
     

    <span th:text="Hello"></span><br/>
    <span th:text="${msg}"></span>

     

    3.1.2th:value

     
    th:value
     
    可以将一个值放入到 input 标签的 value 中
     
     <input type="text" th:value="${msg}"/>
    <input type="text" th:value="ss"/>
     

    3.1.3 判断字符串是否为空

     
    Thymeleaf 内置对象
     
    注意语法:
    1,调用内置对象一定要用#
    2,大部分的内置对象都以 s 结尾 strings、numbers、dates
     
     
    ${#strings.isEmpty(key)}
     
    判断字符串是否为空,如果为空返回 true,否则返回 false
     
     
    ${#strings.contains(msg,'T')}
     
    判断字符串是否包含指定的子串,如果包含返回 true,否则返回 false
     
     
    ${#strings.startsWith(msg,'a')}
     
    判断当前字符串是否以子串开头,如果是返回 true,否则返回 false
     
     
    ${#strings.endsWith(msg,'a')}
     
    判断当前字符串是否以子串结尾,如果是返回 true,否则返回 false
     
     
     
    ${#strings.length(msg)}
     
    返回字符串的长度
     
     
     
    ${#strings.indexOf(msg,'h')}
     
    查找子串的位置,并返回该子串的下标,如果没找到则返回-1
     
     
     
    ${#strings.substring(msg,13)}
    ${#strings.substring(msg,13,15)}
     
    截取子串,用户与 jdk String 类下 SubString 方法相同
     
     
     
    ${#strings.toUpperCase(msg)}
    ${#strings.toLowerCase(msg)}
     
    字符串转大小写。
     
     
     

    3.2 日期格式化处理

     
    ${#dates.format(key)}
     
    格式化日期,默认的以浏览器默认语言为格式化标准
     
     
     
    ${#dates.format(key,'yyy/MM/dd')}
     
    按照自定义的格式做日期转换
     
     
    ${#dates.year(key)}
    ${#dates.month(key)}
    ${#dates.day(key)}
     
     
    year:取年
    Month:取月
    Day:取日
     
     
     

    3.3 条件判断

     

    3.3.1th:if

     
    <span th:if="${sex} == '男'">
    性别:男
    </span>
    <span th:if="${sex} == '女'">
    性别:女
    </span>
     
     

    3.3.2th:switch

     
    <div th:switch="${id}">
    <span th:case="1">ID 为 1</span>
    <span th:case="2">ID 为 2</span><span th:case="3">ID 为 3</span>
    </div>
     
     

    3.4 迭代遍历

     
     
    3.4.1th:each 
     
    @RequestMapping("/show3")
     public String showInfo3(Model model){ 
    List<Users> list = new ArrayList<>();
     list.add(new Users(1,"张三",20)); 
     list.add(new Users(2,"李四",22)); 
    list.add(new Users(3,"王五",24));
     model.addAttribute("list", 
    list); return "index3"; 
    }
    <table border="1"> 
    <tr>
    <th>ID</th> 
    <th>Name</th> 
    <th>Age</th> 
    </tr> 
    <tr th:each="u : ${list}"> 
    <td th:text="${u.userid}"></td>
     <td th:text="${u.username}"></td> 
    <td th:text="${u.userage}"></td>
     </tr> 
     </table>

    3.4.2ht:each 状态变量

    @RequestMapping("/show3") 
    public String showInfo3(Model model){ 
    List<Users> list = new ArrayList<>(); 
    list.add(new Users(1,"张三",20));
     list.add(new Users(2,"李四",22)); 
    list.add(new Users(3,"王五",24));
     model.addAttribute("list", list);
     return "index3";
    }
    View Code
    <table border="1"> 
    <tr>
    <th>ID</th>
     <th>Name</th> 
     <th>Age</th> 
    <th>Index</th>
     <th>Count</th>
     <th>Size</th> 
     <th>Even</th> 
    <th>Odd</th>
     <th>First</th> 
     <th>lase</th> 
     </tr> <tr th:each="u,var : ${list}"> 
     <td th:text="${u.userid}"></td> 
     <td th:text="${u.username}"></td> 
     <td th:text="${u.userage}"></td> 
    <td th:text="${var.index}"></td>
     <td th:text="${var.count}"></td>
     <td th:text="${var.size}"></td> 
    <td th:text="${var.even}"></td> 
    <td th:text="${var.odd}"></td> 
    <td th:text="${var.first}"></td> 
    <td th:text="${var.last}"></td> 
    </tr>
    </table>
    View Code
    状态变量属性
    1,index:当前迭代器的索引 从 0 开始
    2,count:当前迭代对象的计数 从 1 开始
    3,size:被迭代对象的长度
    4,even/odd:布尔值,当前循环是否是偶数/奇数 从 0 开始
    5,first:布尔值,当前循环的是否是第一条,如果是返回 true 否则返回 false
    6,last:布尔值,当前循环的是否是最后一条,如果是则返回 true 否则返回 false
     

    3.4.3th:each 迭代 Map

    @RequestMapping("/show4")
     public String showInfo4(Model model){ 
    Map<String, Users> map = new HashMap<>(); 
    map.put("u1", new Users(1,"张三",20)); 
    map.put("u2", new Users(2,"李四",22));
    map.put("u3", new Users(3,"王五",24)); 
    model.addAttribute("map", map);
     return "index4"; }
    <table border="1"> 
    <tr>
    <th>ID</th> 
    <th>Name</th> 
    <th>Age</th> 
    </tr> 
    <tr th:each="maps : ${map}">
     <td th:text="${maps}"></td> 
    </tr> 
    </table> 
    <th/>
     <table border="1"> 
     <tr><th>ID</th> 
    <th>Name</th>
     <th>Age</th> 
     </tr> <tr th:each="maps : ${map}"> 
    <td th:each="entry:${maps}" th:text="${entry.value.userid}" ></td>
     <td th:each="entry:${maps}" th:text="${entry.value.username}">
    </td> 
    <td th:each="entry:${maps}" th:text="${entry.value.userage}"></td> 
    </tr> 
    </table>

    3.5 域对象操作

     

    3.5.1HttpServletRequest

    request.setAttribute("req", "HttpServletRequest");
     
    Request:<span 
    th:text="${#httpServletRequest.getAttribute('req')}"></span><br/>
     
     

    3.5.2HttpSession

     
    request.getSession().setAttribute("sess", "HttpSession");
     
    Session:<span th:text="${session.sess}"></span><br/>
     

    3.5.3ServletContext

     
    request.getSession().getServletContext().setAttribute("app",
    "Application");
    Application:<span th:text="${application.app}"></span> 
     

    3.6 URL 表达式

     
    th:href
    th:src
     

    3.6.1url 表达式语法

     
    基本语法:@{}
     

    3.6.2URL 类型

     

    3.6.2.1 绝对路径 

     
    <a th:href="@{http://www.baidu.com}">绝对路径</a><br/>
     

    3.6.2.2 相对路径

     
    1)相对于当前项目的根
    相对于项目的上下文的相对路径
    <a th:href="@{/show}">相对路径</a>
     
    2) 相对于服务器路径的根
     
    <a th:href="@{~/project2/resourcename}">相对于服务器的根</a>3.6.3 在 url 中实现参数传递
    <a th:href="@{/show(id=1,name=zhagnsan)}">相对路径-传参</a>
     

    3.6.4 在 url 中通过 restful 风格进行参数传递

     
    <a th:href="@{/path/{id}/show(id=1,name=zhagnsan)}"> 相 对 路 径 - 传 参-restful</a>
     
     
     

    SpringBoot 第四章

     
    (SpringBoot 整合 SpringMVC+MyBatis)需求分析:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一
    个对数据库中的 users 表的 CRUD 的操作
     

    一、 创建项目

     

    1 修改 pom 文件

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>12-spring-boot-springmvc-mybatis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.ve
    rsion>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- web 启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- Mybatis 启动器 --><dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
    </dependency>
    <!-- mysql 数据库驱动 -->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- druid 数据库连接池 -->
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.9</version>
    </dependency>
    </dependencies>
    </project>
     

    2 添加 application.properties 全局配置文件

     
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/ssm
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    mybatis.type-aliases-package=com.bjsxt.pojo
     

    3 数据库表设计

     
    CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `age` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     

    二、 添加用户

     

    1 创建实体类

     
    public class Users {
    private Integer id;
    private String name;
    private Integer age;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    }
     

    2 创建 mapper 接口以及映射配置文件

     
    import com.bjsxt.pojo.Users;
    public interface UsersMapper {
    void insertUser(Users users);
    }
    <?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.bjsxt.mapper.UsersMapper">
    <insert id="insertUser" parameterType="users">
    insert into users(name,age) values(#{name},#{age})
    </insert>
    </mapper>
     

    3 创建业务层

     
    @Service
    @Transactional
    public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public void addUser(Users users) {
    this.usersMapper.insertUser(users);
    }
    }
     

    4 创建 Controller

     
    @Controller
    @RequestMapping("/users")
    public class UsersController {
    @Autowired
    private UsersService usersService;
    /**
    * 页面跳转
    */
    @RequestMapping("/{page}")
    public String showPage(@PathVariable String page){
    return page;
    }
    /*** 添加用户
    */
    @RequestMapping("/addUser")
    public String addUser(Users users){
    this.usersService.addUser(users);
    return "ok";
    }
    }
     

    5 编写页面

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>添加用户</title>
    </head>
    <body>
    <form th:action="@{/users/addUser}" method="post">
    用户姓名:<input type="text" name="name"/><br/>
    用户年龄:<input type="text" name="age"/><br/>
    <input type="submit" value="确定"/><br/>
    </form>
    </body>
    </html>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>操作提示页面</title>
    </head>
    <body>
    操作成功!!!
    </body>
    </html>
     

    6 启动类

     
    @SpringBootApplication
    @MapperScan("com.bjsxt.mapper") //@MapperScan 用户扫描MyBatis的Mapper接口
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
     

    三、 查询用户

     
    1 在 mapper 接口中以及映射配置文件中添加相关代码
    List<Users> selectUsersAll();
    <select id="selectUsersAll" resultType="users">
    select id,name,age from users
    </select>
    2 在业务层中添加查询方法
    @Override
    public List<Users> findUserAll() {
    return this.usersMapper.selectUsersAll();
    }
    3 在 Controller 中添加方法
    /**
    * 查询全部用户
    */
    @RequestMapping("/findUserAll")
    public String findUserAll(Model model){
    List<Users> list = this.usersService.findUserAll();
    model.addAttribute("list", list);
    return "showUsers";
    }

    4 添加页面

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>展示用户数据</title>
    </head>
    <body>
    <table border="1" style="300px;">
    <tr>
    <th>用户 ID</th>
    <th>用户姓名</th>
    <th>用户年龄</th>
    </tr>
    <tr th:each="user : ${list}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    </tr>
    </table>
    </body>
    </html>
     

    四、 用户更新

     
    1 更新用户之前的查询,并将数据在页面中回显
    1.1修改 mapper 接口以及映射配置文件
    Users selectUsersById(Integer id);
    <select id="selectUsersById" resultType="users">
    select id,name,age from users where id = #{value}
    </select>
     

    1.2修改业务层代码

     
    @Override
    public Users findUserById(Integer id) {
    return this.usersMapper.selectUsersById(id);
    }1.3修改 Controller
    /**
    * 根据用户 id 查询用户
    */
    @RequestMapping("/findUserById")
    public String findUserById(Integer id,Model model){
    Users user = this.usersService.findUserById(id);
    model.addAttribute("user", user);
    return "updateUser";
    }

    1.4添加页面 updateUsers.html

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <form th:action="@{/users/editUser}" method="post">
    <input type="hidden" name="id" th:field="${user.id}"/>
    用户姓名:<input type="text" name="name"
    th:field="${user.name}"/><br/>
    用户年龄:<input type="text" name="age"
    th:field="${user.age}"/><br/>
    <input type="submit" value="确定"/><br/>
    </form>
    </body>
    </html>
     

    1.5修改 showUsers.html 页面添加操作功能

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>展示用户数据</title>
    </head>
    <body>
    <table border="1" style="300px;"><tr>
    <th>用户 ID</th>
    <th>用户姓名</th>
    <th>用户年龄</th>
    <th>操作</th>
    </tr>
    <tr th:each="user : ${list}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    <td>
    <a th:href="@{/users/findUserById(id=${user.id})}">更
    新用户</a>
    </td>
    </tr>
    </table>
    </body>
    </html>
     

    2 用户更新

     

    2.1修改 mapper 接口以及映射配置文件

     
    void updateUser(Users users);
    <update id="updateUser" parameterType="users">
    update users set name=#{name} ,age=#{age} where id=#{id}
    </update>
     

    2.2修改业务层代码

     
    @Override
    public void updateUser(Users users) {
    this.usersMapper.updateUser(users);
    }
     

    2.3修改 Controller

     
    /**
    * 更新用户
    */@RequestMapping("/editUser")
    public String editUser(Users users){
    this.usersService.updateUser(users);
    return "ok";
    }
     

    五、 删除用户

     

    1 修改 mapper 接口以及映射配置文件

     
    void deleteUserById(Integer id);
    <delete id="deleteUserById">
    delete from users where id = #{value}
    </delete>
     

    2 修改业务层代码

     
    @Override
    public void deleteUserById(Integer id) {
    this.usersMapper.deleteUserById(id);
    }
     

    3 修改 Controller

     
    /**
    * 删除用户
    */
    @RequestMapping("/delUser")
    public String delUser(Integer id){
    this.usersService.deleteUserById(id);
    return "redirect:/users/findUserAll";
    }

    4 修改 showUsers.html

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>展示用户数据</title></head>
    <body>
    <table border="1" style="300px;">
    <tr>
    <th>用户 ID</th>
    <th>用户姓名</th>
    <th>用户年龄</th>
    <th>操作</th>
    </tr>
    <tr th:each="user : ${list}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    <td>
    <a th:href="@{/users/findUserById(id=${user.id})}">更
    新用户</a>
    <a th:href="@{/users/delUser(id=${user.id})}">删除用户
    </a>
    </td>
    </tr>
    </table>
    </body>
    </html>
     
     
     
     
     
     

    SpringBoot 第一章服务端表单数据校验

     

    (SpringBoot 高级)

     

    一、 实现添加用户功能

     
    1 创建项目

    2 修改 POM 文件

    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent><groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>13-spring-boot-validate</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.ve
    rsion>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- thymeleaf 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    </dependencies>
    </project>
    View Code
     
    3 编写添加用户功能创建实体类
    public class Users {
    private String name;
    private String password;
    private Integer age;
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getPassword() {return password;
    }
    public void setPassword(String password) {
    this.password = password;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    @Override
    public String toString() {
    return "Users [name=" + name + ", password=" + password + ", age="
    + age + "]";
    }
    }
    View Code

    3.1编写 Controller

     
    /**
    * SpringBoot 表单数据校验
    *
    *
    */
    @Controller
    public class UsersController {
    @RequestMapping("/addUser")
    public String showPage(){
    return "add";
    }
    /**
    * 完成用户添加
    */
    @RequestMapping("/save")
    public String saveUser(Users users){
    System.out.println(users);
    return "ok";
    }}
    View Code
     
     
     

    3.2编写页面 add.html ok.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>添加用户</title>
    </head>
    <body>
    <form th:action="@{/save}" method="post">
    用户姓名:<input type="text" name="name"/><br/>
    用户密码:<input type="password" name="password" /><br/>
    用户年龄:<input type="text" name="age" /><br/>
    <input type="submit" value="OK"/>
    </form>
    </body>
    </html>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>操作成功</title>
    </head>
    <body>
    OK。。。。
    </body>
    </html>
    View Code
     

    二、 SpringBoot 对表单做数据校验

     

    1 SpringBoot 对表单数据校验的技术特点

     

    1.1SpringBoot 中使用了 Hibernate-validate 校验框架

     

    2 SpringBoot 表单数据校验步骤

     

    2.1在实体类中添加校验规则

    public class Users {
    @NotBlank //非空校验
    private String name;
    @NotBlank //密码非空校验
    private String password;
    private Integer age;
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getPassword() {
    return password;
    }
    public void setPassword(String password) {
    this.password = password;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    @Override
    public String toString() {
    return "Users [name=" + name + ", password=" + password + ", age="
    + age + "]";
    }
    }
    View Code
     
     

    2.2在 Controller 中开启校验

     
    /**
    * 完成用户添加
    *@Valid 开启对 Users 对象的数据校验
    *BindingResult:封装了校验的结果
    */
    @RequestMapping("/save")
    public String saveUser(@Valid Users users,BindingResult result){
    if(result.hasErrors()){
    return "add";
    }
    System.out.println(users);
    return "ok";
    }
    View Code

    2.3在页面中获取提示信息

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>添加用户</title>
    </head>
    <body>
    <form th:action="@{/save}" method="post">
    用户姓名:<input type="text" name="name"/><font color="red"
    th:errors="${users.name}"></font><br/>
    用户密码:<input type="password" name="password" /><font
    color="red" th:errors="${users.password}"></font><br/>
    用户年龄:<input type="text" name="age" /><font color="red"
    th:errors="${users.age}"></font><br/>
    <input type="submit" value="OK"/>
    </form>
    </body>
    </html> 
    View Code

    2.4遇到异常

     

    三、 解决数据校验时的异常问题

     
    解决异常的方法,在跳转页面的方法中注入一个对象,来解决问题。要求参数对象的
    变量名必须是对象的类名的全称首字母小写。
     
    代码
    /** * 解决异常的方式。可以在跳转页面的方法中注入一个 Uesrs 对象。 * 注意:由于 springmvc 会将该对象放入到 
    Model 中传递。key 的名称会使用 该对象的驼峰式的命名规则来作为 key。 * 
    参数的变量名需要与对象的名称相同。将首字母小写。 ** @param users * @return */ @RequestMapping("/addUser") 
    public String showPage( Users users){ return "add"; } /** * 完成用户添加 *@Valid 开启对 Users 
    对象的数据校验 *BindingResult:封装了校验的结果 */ @RequestMapping("/save") public String saveUser( @Valid 
    Users users,BindingResult result){ if(result.hasErrors()){ return "add"; }System.out.println(users); 
    return "ok"; }
    View Code
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>添加用户</title> </head> <body> <form th:action="@{/save}" method="post"> 用户姓名:<input type="text" name="name"/><font color="red" th:errors="${users.name}"></font><br/> 用户密码:<input type="password" name="password" /><font color="red" th:errors="${users.password}"></font><br/>
    用户年龄:<input type="text" name="age" /><font color="red" th:errors="${users.age}"></font><br/> <input type="submit" value="OK"/> </form> </body> </html>
    View Code

    如果参数的名称需要做改变 

    /**** 如果想为传递的对象更改名称,可以使用@ModelAttribute("aa")这表示当 前传递的对象的 key 为 aa。 * 那么我们在页面中获取该对象的 key 也需要修改为 aa * @param users * @return */ @RequestMapping("/addUser") public String showPage(@ModelAttribute("aa") Users users){ return "add"; } /** * 完成用户添加 *@Valid 开启对 Users 对象的数据校验 *BindingResult:封装了校验的结果 */ @RequestMapping("/save") public String saveUser(@ModelAttribute("aa") @Valid Users users,BindingResult result){ if(result.hasErrors()){ return "add"; }System.out.println(users); return "ok"; }
    View Code
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>添加用户</title> </head> <body> <form th:action="@{/save}" method="post"> 用户姓名:<input type="text" name="name"/><font color="red"
    th:errors="${aa.name}"></font><br/> 用户密码:<input type="password" name="password" /><font color="red" th:errors="${aa.password}"></font><br/> 用户年龄:<input type="text" name="age" /><font color="red" th:errors="${aa.age}"></font><br/> <input type="submit" value="OK"/> </form> </body> </html>
    View Code

    四、 其他校验规则

     
    @NotBlank: 判断字符串是否为 null 或者是空串(去掉首尾空格)。
    @NotEmpty: 判断字符串是否 null 或者是空串。
    @Length: 判断字符的长度(最大或者最小)
    @Min: 判断数值最小值
    @Max: 判断数值最大值
    @Email: 判断邮箱是否合法
     
     

    Spring Boot 第二章异常处理与单元测试

     
    (SpringBoot 高级)
     
    @RestControllerAdvice
    @Slf4j
    public class CustomExceptionHandler {
    
        @ExceptionHandler(value = Exception.class)
        public DataResult exception(Exception e){
            log.error("Exception,{},{}",e.getLocalizedMessage(),e);
            return DataResult.getResult(BaseResponseCode.SYSTEM_ERROR);
        }
    
        @ExceptionHandler(value = BusinessException.class)
        public DataResult businessException(BusinessException e){
            log.error("businessException,{},{}",e.getLocalizedMessage(),e);
            return DataResult.getResult(e.getCode(), e.getDefaultMessage());
        }
        /**
         * 处理validation 框架异常
         * @Author:      小霍
         * @UpdateUser:
         * @Version:     0.0.1
         * @param e
         * @return       com.yingxue.lesson.utils.DataResult<T>
         * @throws
         */
        @ExceptionHandler(MethodArgumentNotValidException.class)
        <T> DataResult<T> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
    
            log.error("methodArgumentNotValidExceptionHandler bindingResult.allErrors():{},exception:{}", e.getBindingResult().getAllErrors(), e);
            List<ObjectError> errors = e.getBindingResult().getAllErrors();
            return createValidExceptionResp(errors);
        }
        private <T> DataResult<T> createValidExceptionResp(List<ObjectError> errors) {
            String[] msgs = new String[errors.size()];
            int i = 0;
            for (ObjectError error : errors) {
                msgs[i] = error.getDefaultMessage();
                log.info("msg={}",msgs[i]);
                i++;
            }
            return DataResult.getResult(BaseResponseCode.METHOD_IDENTITY_ERROR.getCode(), msgs[0]);
        }
        @ExceptionHandler(UnauthorizedException.class)
        public DataResult unauthorizedException(UnauthorizedException e){
            log.error("UnauthorizedException,{},{}",e.getLocalizedMessage(),e);
            return DataResult.getResult(BaseResponseCode.NOT_PERMISSION);
        }
    
    
    }
    View Code

    一、 SpringBoot 中异常处理方式

     
    1 SpringBoot 中对于异常处理提供了五种处理方式
    1.1自定义错误页面
    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
    一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个
    叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常
    信息。
     
     
     
    如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再
    src/main/resources/templates 目录下创建 error.html 页面。注意:名称必须叫 error 
     
     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>错误提示页面</title>
    </head>
    <body>
    出错了,请与管理员联系。。。
    <span th:text="${exception}"></span>
    </body>
    </html>
    View Code
    1.2@ExceptionHandle 注解处理异常
    1.2.1 Controller
    /**
    * SpringBoot 处理异常方式一:自定义错误页面
    *
    *
    */
    @Controller
    public class DemoController {
    @RequestMapping("/show")
    public String showInfo(){
    String str = null;
    str.length();
    return "index";
    }
    @RequestMapping("/show2")
    public String showInfo2(){
    int a = 10/0;
    return "index";
    }
    /**
    * java.lang.ArithmeticException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error1");
    return mv;
    }
    /**
    * java.lang.NullPointerException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定* 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public ModelAndView nullPointerExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error2");
    return mv;
    }
    } 
    View Code
    1.2.2 页面
     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>错误提示页面-ArithmeticException</title>
    </head>
    <body>
    出错了,请与管理员联系。。。
    <span th:text="${error}"></span>
    </body>
    </html> 
    View Code
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>错误提示页面-NullPointerException</title> </head> <body> 出错了,请与管理员联系。。。 <span th:text="${error}"></span> </body> </html>
    View Code

    1.3@ControllerAdvice+@ExceptionHandler 注解处理异常

     

    1.3.1 需要创建一个能够处理异常的全局异常类。在该类上需要添加@ControllerAdvice 注解

    /**
    * 全局异常处理类
    *
    *
    */
    @ControllerAdvice
    public class GlobalException {
    /**
    * java.lang.ArithmeticException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error1");
    return mv;
    }
    /**
    * java.lang.NullPointerException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public ModelAndView nullPointerExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error2");
    return mv;
    }
    }
    View Code

    1.4配置 SimpleMappingExceptionResolver 处理异常

     

    1.4.1 在全局异常类中添加一个方法完成异常的同一处理

     
    /**
    * 通过 SimpleMappingExceptionResolver 做全局异常处理
    *
    *
    */
    
    @Configuration
    public class GlobalException {
    /**
    * 该方法必须要有返回值。返回值类型必须是:
    SimpleMappingExceptionResolver
    */
    @Bean
    public SimpleMappingExceptionResolver
    getSimpleMappingExceptionResolver(){
    SimpleMappingExceptionResolver resolver = new
    SimpleMappingExceptionResolver();
    Properties mappings = new Properties();
    /**
    * 参数一:异常的类型,注意必须是异常类型的全名
    * 参数二:视图名称
    */
    mappings.put("java.lang.ArithmeticException", "error1");
    mappings.put("java.lang.NullPointerException","error2");
    //设置异常与视图映射信息的
    resolver.setExceptionMappings(mappings);
    return resolver;
    }
    }
    View Code
     
    1.5自定义 HandlerExceptionResolver 类处理异常
    1.5.1 需 要 再 全 局 异 常 处 理 类 中 实 现
    HandlerExceptionResolver 接口
     
    /**
    * 通过实现 HandlerExceptionResolver 接口做全局异常处理
    *
    *
    */
    @Configuration
    public class GlobalException implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response, Object handler,
    Exception ex) {
    ModelAndView mv = new ModelAndView();
    //判断不同异常类型,做不同视图跳转
    if(ex instanceof ArithmeticException){
    mv.setViewName("error1");
    }
    if(ex instanceof NullPointerException){
    mv.setViewName("error2");
    }
    mv.addObject("error", ex.toString());
    return mv;
    }
    }
    View Code
     
     
    二、 Spring Boot 整合 Junit 单元测试
     
    1 创建项目 
     
     

    2 修改 pom 文件

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>19-spring-boot-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties><java.version>1.7</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 添加 junit 环境的 jar 包 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    </dependencies>
    </project>
    View Code
    3 编写业务代码
    3.1Dao
     
    @Repository
    public class UserDaoImpl {
    public void saveUser(){
    System.out.println("insert into users.....");
    }
    }
    View Code
    3.2业务层
    @Service
    public class UserServiceImpl {
    @Autowired
    private UserDaoImpl userDaoImpl;
    public void addUser(){
    this.userDaoImpl.saveUser();
    }
    }
    View Code
    3.3编写启动类
    @SpringBootApplication
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
    View Code
     
     
    4 使用 SpringBoot 整合 Junit 做单元测试
     
    4.1编写测试类
     
    /**
    * SpringBoot 测试类
    *@RunWith:启动器
    *SpringJUnit4ClassRunner.class:让 junit 与 spring 环境进行整合
    *
    *@SpringBootTest(classes={App.class}) 1,当前类为 springBoot 的测试类
    *@SpringBootTest(classes={App.class}) 2,加载 SpringBoot 启动类。启动
    springBoot
    *
    *junit 与 spring 整合
    @Contextconfiguartion("classpath:applicationContext.xml")
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes={App.class})
    public class UserServiceTest {
    @Autowired
    private UserServiceImpl userServiceImpl;
    @Test
    public void testAddUser(){
    this.userServiceImpl.addUser();
    }
    }
     
    View Code
    (SpringBoot 高级)
    一、 SpringBoot 中异常处理方式
    1 SpringBoot 中对于异常处理提供了五种处理方式
    1.1自定义错误页面
    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
    一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个
    叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常
    信息。
     
     
    如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再
    src/main/resources/templates 目录下创建 error.html 页面。注意:名称必须叫 error
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>错误提示页面</title>
    </head>
    <body>
    出错了,请与管理员联系。。。
    <span th:text="${exception}"></span>
    </body>
    </html>1.2@ExceptionHandle 注解处理异常
    1.2.1 Controller
    /**
    * SpringBoot 处理异常方式一:自定义错误页面
    *
    *
    */
    @Controller
    public class DemoController {
    @RequestMapping("/show")
    public String showInfo(){
    String str = null;
    str.length();
    return "index";
    }
    @RequestMapping("/show2")
    public String showInfo2(){
    int a = 10/0;
    return "index";
    }
    /**
    * java.lang.ArithmeticException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error1");
    return mv;
    }
    /**
    * java.lang.NullPointerException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定* 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public ModelAndView nullPointerExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error2");
    return mv;
    }
    }
    1.2.2 页面
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>错误提示页面-ArithmeticException</title>
    </head>
    <body>
    出错了,请与管理员联系。。。
    <span th:text="${error}"></span>
    </body>
    </html>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>错误提示页面-NullPointerException</title>
    </head>
    <body>
    出错了,请与管理员联系。。。
    <span th:text="${error}"></span>
    </body>
    </html>1.3@ControllerAdvice+@ExceptionHandler 注解处理异常
    1.3.1 需要创建一个能够处理异常的全局异常类。在该类上需
    要添加@ControllerAdvice 注解/**
    * 全局异常处理类
    *
    *
    */
    @ControllerAdvice
    public class GlobalException {
    /**
    * java.lang.ArithmeticException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error1");
    return mv;
    }
    /**
    * java.lang.NullPointerException
    * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视
    图的指定
    * 参数 Exception e:会将产生异常对象注入到方法中
    */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public ModelAndView nullPointerExceptionHandler(Exception e){
    ModelAndView mv = new ModelAndView();
    mv.addObject("error", e.toString());
    mv.setViewName("error2");
    return mv;
    }
    }1.4配置 SimpleMappingExceptionResolver 处理异常
    1.4.1 在全局异常类中添加一个方法完成异常的同一处理
    /**
    * 通过 SimpleMappingExceptionResolver 做全局异常处理
    *
    *
    */
    @Configuration
    public class GlobalException {
    /**
    * 该方法必须要有返回值。返回值类型必须是:
    SimpleMappingExceptionResolver
    */
    @Bean
    public SimpleMappingExceptionResolver
    getSimpleMappingExceptionResolver(){
    SimpleMappingExceptionResolver resolver = new
    SimpleMappingExceptionResolver();
    Properties mappings = new Properties();
    /**
    * 参数一:异常的类型,注意必须是异常类型的全名
    * 参数二:视图名称
    */
    mappings.put("java.lang.ArithmeticException", "error1");
    mappings.put("java.lang.NullPointerException","error2");
    //设置异常与视图映射信息的
    resolver.setExceptionMappings(mappings);
    return resolver;
    }
    }1.5自定义 HandlerExceptionResolver 类处理异常
    1.5.1 需 要 再 全 局 异 常 处 理 类 中 实 现
    HandlerExceptionResolver 接口
    /**
    * 通过实现 HandlerExceptionResolver 接口做全局异常处理
    *
    *
    */
    @Configuration
    public class GlobalException implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response, Object handler,
    Exception ex) {
    ModelAndView mv = new ModelAndView();
    //判断不同异常类型,做不同视图跳转
    if(ex instanceof ArithmeticException){
    mv.setViewName("error1");
    }
    if(ex instanceof NullPointerException){
    mv.setViewName("error2");
    }
    mv.addObject("error", ex.toString());
    return mv;
    }
    }
    二、 Spring Boot 整合 Junit 单元测试
     
    1 创建项目 
     
    2 修改 pom 文件
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>19-spring-boot-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties><java.version>1.7</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 添加 junit 环境的 jar 包 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    </dependencies>
    </project>
    3 编写业务代码
    3.1Dao
    @Repository
    public class UserDaoImpl {
    public void saveUser(){
    System.out.println("insert into users.....");
    }
    }
    3.2业务层
    @Service
    public class UserServiceImpl {
    @Autowired
    private UserDaoImpl userDaoImpl;
    public void addUser(){
    this.userDaoImpl.saveUser();
    }
    }3.3编写启动类
    @SpringBootApplication
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
    4 使用 SpringBoot 整合 Junit 做单元测试
    4.1编写测试类
    /**
    * SpringBoot 测试类
    *@RunWith:启动器
    *SpringJUnit4ClassRunner.class:让 junit 与 spring 环境进行整合
    *
    *@SpringBootTest(classes={App.class}) 1,当前类为 springBoot 的测试类
    *@SpringBootTest(classes={App.class}) 2,加载 SpringBoot 启动类。启动
    springBoot
    *
    *junit 与 spring 整合
    @Contextconfiguartion("classpath:applicationContext.xml")
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes={App.class})
    public class UserServiceTest {
    @Autowired
    private UserServiceImpl userServiceImpl;
    @Test
    public void testAddUser(){
    this.userServiceImpl.addUser();
    }
    }
     
     
     
     
     

    Spring Boot 第三章 SpringBoot 热部署

     
    (SpringBoot 高级)
     
    SprigBoot 的热部署方式分为两种
     
     SpringLoader 插件
     DevTools 工具
     

    一、 SpringLoader 插件的使用

     
    1 创建项目

    2 修改 pom 文件

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>20-spring-boot-springloader</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.versi
    on>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- thymeleaf 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    </dependencies>
    </project>
     

    3 创建 Controller

     
    /**
    * SpringBoot----SpringLoader
    *
    **/
    @Controller
    public class UsersController {
    @RequestMapping("/show")
    public String showPage(){
    return "index";
    }
    }
     

    4 编写页面

     
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <span th:text="Hello...."></span>
    </body>
    </html>
     

    5 创建启动类

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

    6 使用 SpringLoader 进行项目的热部署

     
    6.1方式一:以 maven 插件方式使用 SpringLoader
    6.1.1 在 pom 文件中添加插件配置
     
    <!-- springloader 插件 -->
    <build>
    <plugins><plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>springloaded</artifactId>
    <version>1.2.5.RELEASE</version>
    </dependency>
    </dependencies>
    </plugin>
    </plugins>
    </build>
     

    6.1.2 使用 maven 的命令起来启动

     
    spring-boot:run 
    SpringLoader 缺陷:就是 Java 代码做部署处理。但是对页面无能为力。6.1.3 注意:这种方式的缺点是 Springloader 热部署程序是在
    系统后台以进程的形式来运行。需要手动关闭该进程
     
     

    7 方式二:在项目中直接使用 jar 包的方式

     

    7.1添加 springloader 的 jar 包 

    7.2启动方式

    启动命令:
    -javaagent:.libspringloaded-1.2.5.RELEASE.jar -noverify
     

    二、 DevTools 工具

     

    1 SpringLoader 与 DevTools 的区别:

     
    SpringLoader:SpringLoader 在部署项目时使用的是热部署的方式。
    DevTools:DevTools 在部署项目时使用的是重新部署的方式
     

    2 修改项目的 pom 文件添加 devtools 的依赖

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>21-spring-boot-devtools</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.versi
    on>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- thymeleaf 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- DevTools 的坐标 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
    </dependency>
    </dependencies>
    </project>
    View Code
    第四章节 Spring Boot 整合 Spring Data JPA
    (SpringBoot 高级)
     

    一、 Spring Data JPA 介绍

     
    Spring Data:其实 Spring Data 就是 spring 提供了一个操作数据的框架。而 Spring Data JPA
    只是 Spring Data 框架下的一个基于 JPA 标准操作数据的模块。
    Spring Data JPA:基于 JPA 的标准对数据进行操作。简化操作持久层的代码。只需要编
    写接口就可以。
     

    二、 Spring Boot 整合 Spring Data JPA

     
    1 搭建整合环境

    2 修改 POM 文件添加坐标

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>22-spring-boot-jpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.ve
    rsion>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- mysql -->
    <dependency><groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- druid 连接池 -->
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.9</version>
    </dependency>
    </dependencies>
    </project>
    View Code
    3 在项目中添加 application.properties 文件
     
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/ssm
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.jpa.hibernate.ddl-auto=update
    spring.jpa.show-sql=true
    View Code
    4 添加实体类
    @Entity
    @Table(name="t_users")
    public class Users {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;
    @Column(name="name")
    private String name;@Column(name="age")
    private Integer age;
    @Column(name="address")
    private String address;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    @Override
    public String toString() {
    return "Users [id=" + id + ", name=" + name + ", age=" + age +
    ", address=" + address + "]";
    }
    }
    View Code
    5 编写 Dao 接口
     
    /**
    * 参数一 T :当前需要映射的实体
    * 参数二 ID :当前映射的实体中的 OID 的类型
    *
    */
    public interface UsersRepository extends JpaRepository<Users,Integer>
    {
    }
    View Code
    6 在 pom 文件中添加测试启动器的坐标
     
    <!-- 测试工具的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    7 创建启动类
    @SpringBootApplication
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
    View Code
    8 编写测试代码
     
    /**
    * 测试类
    *
    *
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class UsersRepositoryTest {
    @Autowiredprivate UsersRepository usersRepository;
    @Test
    public void testSave(){
    Users users = new Users();
    users.setAddress("北京市海淀");
    users.setAge(20);
    users.setName("张三");
    this.usersRepository.save(users);
    }
    }
    View Code

    三、 Spring Data JPA 提供的核心接口

     
    1 Repository 接口
    2 CrudRepository 接口
    3 PagingAndSortingRepository 接口
    4 JpaRepository 接口
    5 JPASpecificationExecutor 接口
     

    四、 Repository 接口的使用

     
    提供了方法名称命名查询方式
    提供了基于@Query 注解查询与更新
     

    1 方法名称命名查询方式

     

    1.1编写接口

    /**
    * Repository 接口的方法名称命名查询*
    *
    */
    public interface UsersRepositoryByName extends Repository<Users,
    Integer> {
    //方法的名称必须要遵循驼峰式命名规则。findBy(关键字)+属性名称(首字母要
    大写)+查询条件(首字母大写)
    List<Users> findByName(String name);
    List<Users> findByNameAndAge(String name,Integer age);
    List<Users> findByNameLike(String name);
    }
     

    1.2测试代码

     
    /**
    * Repository--方法名称命名测试
    */
    @Test
    public void testFindByName(){
    List<Users> list = this.usersRepositoryByName.findByName("张三
    ");
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * Repository--方法名称命名测试
    */
    @Test
    public void testFindByNameAndAge(){
    List<Users> list =
    this.usersRepositoryByName.findByNameAndAge("张三", 20);
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * Repository--方法名称命名测试*/
    @Test
    public void testFindByNameLike(){
    List<Users> list = this.usersRepositoryByName.findByNameLike("
    张%");
    for (Users users : list) {
    System.out.println(users);
    }
    }
    View Code
    2 基于@Query 注解查询与更新
    2.1编写接口
    /**
    * Repository @Query
    *
    *
    */
    public interface UsersRepositoryQueryAnnotation extends
    Repository<Users, Integer> {
    @Query("from Users where name = ?")
    List<Users> queryByNameUseHQL(String name);
    @Query(value="select * from t_users where name
    = ?",nativeQuery=true)
    List<Users> queryByNameUseSQL(String name);
    @Query("update Users set name = ? where id = ?")
    @Modifying //需要执行一个更新操作
    void updateUsersNameById(String name,Integer id);
    }
    View Code
    2.2测试代码
     
    /**
    * Repository--@Query 测试
    */@Test
    public void testQueryByNameUseHQL() {
    List<Users> list =
    this.usersRepositoryQueryAnnotation.queryByNameUseHQL("张三");
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * Repository--@Query 测试
    */
    @Test
    public void testQueryByNameUseSQL() {
    List<Users> list =
    this.usersRepositoryQueryAnnotation.queryByNameUseSQL("张三");
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * Repository--@Query 测试
    */
    @Test
    @Transactional //@Transactional 与@Test 一起使用时 事务是自动回滚的。
    @Rollback(false) //取消自动回滚
    public void testUpdateUsersNameById() {
    this.usersRepositoryQueryAnnotation.updateUsersNameById("张三", 1);
    }
    View Code

    五、 CrudRepository 接口

     
    1 CrudRepository 接口,主要是完成一些增删改查的操作。
     
    注意:
    CredRepository 接口继承 Repository 接口
     

    2 编写接口 

    2 编写接口

     
    /**
    * CrudRepository 接口
    *
    *
    */
    public interface UsersRepositoryCrudRepository extends
    CrudRepository<Users, Integer> {
    }
    View Code

    3 测试代码

    /**
    * CrudRepository 测试
    */
    @Test
    public void testCrudRepositorySave() {
    Users user = new Users();
    user.setAddress("天津");
    user.setAge(32);
    user.setName("张三丰");
    this.usersRepositoryCrudRepository.save(user);
    }
    /**
    * CrudRepository 测试*/
    @Test
    public void testCrudRepositoryUpdate() {
    Users user = new Users();
    user.setId(4);
    user.setAddress("南京");
    user.setAge(40);
    user.setName("张三丰");
    this.usersRepositoryCrudRepository.save(user);
    }
    /**
    * CrudRepository 测试
    */
    @Test
    public void testCrudRepositoryFindOne() {
    Users users = this.usersRepositoryCrudRepository.findOne(4);
    System.out.println(users);
    }
    /**
    * CrudRepository 测试
    */
    @Test
    public void testCrudRepositoryFindAll() {
    List<Users> list =
    (List<Users>)this.usersRepositoryCrudRepository.findAll();
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * CrudRepository 测试
    */
    @Test
    public void testCrudRepositoryDeleteById() {
    this.usersRepositoryCrudRepository.delete(4);
    }
    View Code
    六、 PagingAndSortingRepository 接口
     
    1 该 接 口 提 供 了 分 页 与 排 序 的 炒 作 。 注 意 : 该 接 口 集 成 了
    CrudRepository 接口 
     

    2 编写接口

     
    /**
    *
    *PagingAndSortingRepository 接口
    *
    */
    public interface UsersRepositoryPagingAndSorting extends
    PagingAndSortingRepository<Users,Integer> {
    }
    View Code
     
    3 测试代码
    /**
    * PagingAndSortingRepository 排序测试
    */
    @Test
    public void testPagingAndSortingRepositorySort() {
    //Order 定义排序规则
    Order order = new Order(Direction.DESC,"id");
    //Sort 对象封装了排序规则
    Sort sort = new Sort(order);List<Users> list =
    (List<Users>)this.usersRepositoryPagingAndSorting.findAll(sort);
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * PagingAndSortingRepository 分页测试
    */
    @Test
    public void testPagingAndSortingRepositoryPaging() {
    //Pageable:封装了分页的参数,当前页,每页显示的条数。注意:他的当前
    页是从 0 开始。
    //PageRequest(page,size) page:当前页。size:每页显示的条数
    Pageable pageable = new PageRequest(1, 2);
    Page<Users> page =
    this.usersRepositoryPagingAndSorting.findAll(pageable);
    System.out.println("总条数:"+page.getTotalElements());
    System.out.println("总页数"+page.getTotalPages());
    List<Users> list = page.getContent();
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * PagingAndSortingRepository 排序+分页
    */
    @Test
    public void testPagingAndSortingRepositorySortAndPaging() {
    Sort sort = new Sort(new Order(Direction.DESC, "id"));
    Pageable pageable = new PageRequest(1, 2, sort);
    Page<Users> page =
    this.usersRepositoryPagingAndSorting.findAll(pageable);
    System.out.println("总条数:"+page.getTotalElements());
    System.out.println("总页数"+page.getTotalPages());
    List<Users> list = page.getContent();
    for (Users users : list) {
    System.out.println(users);
    }}
    七、 JpaRepository 接口
    1 该接口继承了 PagingAndSortingRepository 接口。对继承的父接口
    中的方法的返回值进行适配。
    2 编写接口
    /**
    * 参数一 T :当前需要映射的实体
    * 参数二 ID :当前映射的实体中的 OID 的类型
    *
    */
    public interface UsersRepository extends JpaRepository<Users,Integer>{
    }
    3 测试代码
    /**
    * JapRepository 排序测试
    */
    @Test
    public void testJpaRepositorySort() {
    //Order 定义排序规则
    Order order = new Order(Direction.DESC,"id");
    //Sort 对象封装了排序规则
    Sort sort = new Sort(order);
    List<Users> list = this.usersRepository.findAll(sort);
    for (Users users : list) {
    System.out.println(users);
    }
    }
     

    八、 JPASpecificationExecutor 接口

     
    1 该接口主要是提供了多条件查询的支持,并且可以在查询中添加
    分页与排序。注意:JPASpecificationExecutor 是单独存在。完全独
    立。 
     
     

    2 编写接口

     
    /**
    *
    *JpaSpecificationExecutor
    *
    */
    public interface UsersRepositorySpecification extends
    JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
    }
    3 测试代码
    /**
    * JpaSpecificationExecutor 单条件测试
    */
    @Testpublic void testJpaSpecificationExecutor1() {
    /**
    * Specification<Users>:用于封装查询条件
    */
    Specification<Users> spec = new Specification<Users>() {
    //Predicate:封装了 单个的查询条件
    /**
    * Root<Users> root:查询对象的属性的封装。
    * CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分
    的信息,select from order by
    * CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
    */
    @Override
    public Predicate toPredicate(Root<Users> root,
    CriteriaQuery<?> query, CriteriaBuilder cb) {
    // where name = '张三三'
    /**
    * 参数一:查询的条件属性
    * 参数二:条件的值
    */
    Predicate pre = cb.equal(root.get("name"), "张三三");
    return pre;
    }
    };
    List<Users> list =
    this.usersRepositorySpecification.findAll(spec);
    for (Users users : list) {
    System.out.println(users);
    }
    }
    /**
    * JpaSpecificationExecutor 多条件测试
    */
    @Test
    public void testJpaSpecificationExecutor2() {
    /**
    * Specification<Users>:用于封装查询条件
    */
    Specification<Users> spec = new Specification<Users>() {//Predicate:封装了 单个的查询条件
    /**
    * Root<Users> root:查询对象的属性的封装。
    * CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分
    的信息,select from order by
    * CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
    */
    @Override
    public Predicate toPredicate(Root<Users> root,
    CriteriaQuery<?> query, CriteriaBuilder cb) {
    // where name = '张三三' and age = 20
    List<Predicate> list = new ArrayList<>();
    list.add(cb.equal(root.get("name"),"张三三"));
    list.add(cb.equal(root.get("age"),20));
    Predicate[] arr = new Predicate[list.size()];
    return cb.and(list.toArray(arr));
    }
    };
    List<Users> list =
    this.usersRepositorySpecification.findAll(spec);
    for (Users users : list) {
    System.out.println(users);
    }
    }
    4 多条件查询的第二种写法
    /**
    * JpaSpecificationExecutor 多条件测试第二种写法
    */
    @Test
    public void testJpaSpecificationExecutor3() {
    /**
    * Specification<Users>:用于封装查询条件
    */
    Specification<Users> spec = new Specification<Users>() {
    //Predicate:封装了 单个的查询条件
    /**
    * Root<Users> root:查询对象的属性的封装。
    * CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分的信息,select from order by
    * CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
    */
    @Override
    public Predicate toPredicate(Root<Users> root,
    CriteriaQuery<?> query, CriteriaBuilder cb) {
    // where name = '张三三' and age = 20
    /*List<Predicate> list = new ArrayList<>();
    list.add(cb.equal(root.get("name"),"张三三"));
    list.add(cb.equal(root.get("age"),20));
    Predicate[] arr = new Predicate[list.size()];*/
    //(name = '张三' and age = 20) or id = 2
    return cb.or(cb.and(cb.equal(root.get("name"),"张三三
    "),cb.equal(root.get("age"),20)),cb.equal(root.get("id"), 2));
    }
    };
    Sort sort = new Sort(new Order(Direction.DESC,"id"));
    List<Users> list =
    this.usersRepositorySpecification.findAll(spec,sort);
    for (Users users : list) {
    System.out.println(users);
    }
    }
    九、 关联映射操作
    1 一对多的关联关系
    需求:角色与用户的一对多的关联关系。
    角色:一方
    用户:多方
    1.1Users
    @Entity
    @Table(name="t_users")
    public class Users {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="id")
    private Integer id;
    @Column(name="name")
    private String name;
    @Column(name="age")
    private Integer age;
    @Column(name="address")
    private String address;
    @ManyToOne
    //@JoinColumn:维护外键
    @JoinColumn(name="roles_id")
    private Roles roles;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public String getAddress() {
    return address;
    }public void setAddress(String address) {
    this.address = address;
    }
    @Override
    public String toString() {
    return "Users [id=" + id + ", name=" + name + ", age=" + age +
    ", address=" + address + "]";
    }
    public Roles getRoles() {
    return roles;
    }
    public void setRoles(Roles roles) {
    this.roles = roles;
    }
    }
    1.2Roles
    @Entity
    @Table(name="t_roles")
    public class Roles {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="roleid")
    private Integer roleid;
    @Column(name="rolename")
    private String rolename;
    @OneToMany(mappedBy="roles")
    private Set<Users> users = new HashSet<>();
    public Integer getRoleid() {
    return roleid;
    }public void setRoleid(Integer roleid) {
    this.roleid = roleid;
    }
    public String getRolename() {
    return rolename;
    }
    public void setRolename(String rolename) {
    this.rolename = rolename;
    }
    public Set<Users> getUsers() {
    return users;
    }
    public void setUsers(Set<Users> users) {
    this.users = users;
    }
    }
    1.3测试一对多的关联关系
    /**
    * 一对多关联关系测试
    *
    *
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class OneToManyTest {
    @Autowired
    private UsersRepository usersRepository;
    /**
    * 一对多关联关系的添加
    */
    @Test
    public void testSave(){//创建一个用户
    Users users = new Users();
    users.setAddress("天津");
    users.setAge(32);
    users.setName("小刚");
    //创建一个角色
    Roles roles = new Roles();
    roles.setRolename("管理员");
    //关联
    roles.getUsers().add(users);
    users.setRoles(roles);
    //保存
    this.usersRepository.save(users);
    }
    /**
    * 一对多关联关系的查询
    */
    @Test
    public void testFind(){
    Users findOne = this.usersRepository.findOne(4);
    System.out.println(findOne);
    Roles roles = findOne.getRoles();
    System.out.println(roles.getRolename());
    }
     
     
    2 多对多的关联关系
    需求:角色与菜单多对多关联关系
    角色:多方
    菜单:多方
    2.1Roles
    @Entity
    @Table(name="t_roles")
    public class Roles {@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="roleid")
    private Integer roleid;
    @Column(name="rolename")
    private String rolename;
    @OneToMany(mappedBy="roles")
    private Set<Users> users = new HashSet<>();
    @ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.EAGER)
    //@JoinTable:映射中间表
    //joinColumns:当前表中的主键所关联的中间表中的外键字段
    @JoinTable(name="t_roles_menus",joinColumns=@JoinColumn(name="ro
    le_id"),inverseJoinColumns=@JoinColumn(name="menu_id"))
    private Set<Menus> menus = new HashSet<>();
    public Integer getRoleid() {
    return roleid;
    }
    public void setRoleid(Integer roleid) {
    this.roleid = roleid;
    }
    public String getRolename() {
    return rolename;
    }
    public void setRolename(String rolename) {
    this.rolename = rolename;
    }
    public Set<Users> getUsers() {
    return users;
    }
    public void setUsers(Set<Users> users) {
    this.users = users;
    }
    public Set<Menus> getMenus() {return menus;
    }
    public void setMenus(Set<Menus> menus) {
    this.menus = menus;
    }
    }
    2.2Menus
    @Entity
    @Table(name="t_menus")
    public class Menus {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="menusid")
    private Integer menusid;
    @Column(name="menusname")
    private String menusname;
    @Column(name="menusurl")
    private String menusurl;
    @Column(name="fatherid")
    private Integer fatherid;
    @ManyToMany(mappedBy="menus")
    private Set<Roles> roles = new HashSet<>();
    public Integer getMenusid() {
    return menusid;
    }
    public void setMenusid(Integer menusid) {
    this.menusid = menusid;
    }
    public String getMenusname() {
    return menusname;}
    public void setMenusname(String menusname) {
    this.menusname = menusname;
    }
    public String getMenusurl() {
    return menusurl;
    }
    public void setMenusurl(String menusurl) {
    this.menusurl = menusurl;
    }
    public Integer getFatherid() {
    return fatherid;
    }
    public void setFatherid(Integer fatherid) {
    this.fatherid = fatherid;
    }
    public Set<Roles> getRoles() {
    return roles;
    }
    public void setRoles(Set<Roles> roles) {
    this.roles = roles;
    }
    @Override
    public String toString() {
    return "Menus [menusid=" + menusid + ", menusname=" + menusname
    + ", menusurl=" + menusurl + ", fatherid="
    + fatherid + "]";
    }
    }2.3测试多对多的关联关系
    /**
    * 多对多的关联关系的测试
    *
    *
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class ManyToManyTest {
    @Autowired
    private RolesRepository rolesRepository;
    /**
    * 添加测试
    */
    @Test
    public void testSave(){
    //创建角色对象
    Roles r = new Roles();
    r.setRolename("项目经理");
    //创建菜单对象
    Menus menus = new Menus();
    menus.setMenusname("xxxx 管理系统");
    menus.setFatherid(0);
    Menus menus2 = new Menus();
    menus2.setFatherid(1);
    menus2.setMenusname("项目管理");
    //关联
    r.getMenus().add(menus);
    r.getMenus().add(menus2);
    menus.getRoles().add(r);
    menus2.getRoles().add(r);
    //保存
    this.rolesRepository.save(r);
    }
    /**
    * 查询操作
    */
    @Testpublic void testFind(){
    Roles roles = this.rolesRepository.findOne(2);
    System.out.println(roles.getRolename());
    Set<Menus> menus = roles.getMenus();
    for (Menus menus2 : menus) {
    System.out.println(menus2);
    }
    }
    }
     
     

    第五章节 Spring Boot 缓存技术

     
    (SpringBoot 高级)
    课程内容
     Spring Boot 整合 Ehcache
     Spring Boot 整合 Spring Data Redis
    一、 Spring Boot 整合 Ehcache
    1 修改 pom 文件
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>23-spring-boot-ehcache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.ve
    rsion>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency><groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- 测试工具的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!-- mysql -->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- druid 连接池 -->
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.9</version>
    </dependency>
    <!-- Spring Boot 缓存支持启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <!-- Ehcache 坐标 -->
    <dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId></dependency>
    </dependencies>
    </project>
    2 创建 Ehcache 的配置文件
    文件名:ehcache.xml
    位置:src/main/resources/ehcache.xml
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore path="java.io.tmpdir"/>
    <!--defaultCache:echcache 的默认缓存策略 -->
    <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    maxElementsOnDisk="10000000"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
    </defaultCache>
    <!-- 自定义缓存策略 -->
    <cache name="users"
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    maxElementsOnDisk="10000000"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
    </cache>
    </ehcache>
    3 修改 application.properties 文件
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/ssm
    spring.datasource.username=rootspring.datasource.password=root
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.jpa.hibernate.ddl-auto=update
    spring.jpa.show-sql=true
    spring.cache.ehcache.cofnig=ehcache.xml
    4 修改启动类
    @SpringBootApplication
    @EnableCaching
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
    5 创建业务层
    /**
    * UsersService 接口实现类
    *
    *
    */
    @Service
    public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersRepository usersRepository;
    @Override
    public List<Users> findUserAll() {
    return this.usersRepository.findAll();
    }
    @Override
    //@Cacheable:对当前查询的对象做缓存处理
    @Cacheable(value="users")public Users findUserById(Integer id) {
    return this.usersRepository.findOne(id);
    }
    @Override
    public Page<Users> findUserByPage(Pageable pageable) {
    return this.usersRepository.findAll(pageable);
    }
    @Override
    public void saveUsers(Users users) {
    this.usersRepository.save(users);
    }
    }
    6 修改实体类 Users
    @Entity
    @Table(name="t_users")
    public class Users implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;
    @Column(name="name")
    private String name;
    @Column(name="age")
    private Integer age;
    @Column(name="address")
    private String address;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    @Override
    public String toString() {
    return "Users [id=" + id + ", name=" + name + ", age=" + age +
    ", address=" + address + "]";
    }
    }
    7 测试
    /**
    * UsersService 测试
    *
    *
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class UsersServiceTest {
    @Autowiredprivate UsersService usersService;
    @Test
    public void testFindUserById(){
    //第一次查询
    System.out.println(this.usersService.findUserById(1));
    //第二次查询
    System.out.println(this.usersService.findUserById(1));
    }
    }
    二、 @Cacheable 与@CacheEvict
    1 @Cacheable
    @Cacheable 作用:把方法的返回值添加到 Ehcache 中做缓存
    Value 属性:指定一个 Ehcache 配置文件中的缓存策略,如果么有给定 value,name 则
    表示使用默认的缓存策略。 
     
     
    Key 属性:给存储的值起个名称。在查询时如果有名称相同的,那么则知己从缓存中将
    数据返回
    1.1业务层
    @Override
    @Cacheable(value="users",key="#pageable.pageSize")
    public Page<Users> findUserByPage(Pageable pageable) {
    return this.usersRepository.findAll(pageable);
    }1.2测试代码
    @Test
    public void testFindUserByPage(){
    Pageable pageable = new PageRequest(0, 2);
    //第一次查询
    System.out.println(this.usersService.findUserByPage(pageable).getTot
    alElements());
    //第二次查询
    System.out.println(this.usersService.findUserByPage(pageable).getTot
    alElements());
    //第三次查询
    pageable = new PageRequest(1, 2);
    System.out.println(this.usersService.findUserByPage(pageable).getTot
    alElements());
    }
    }
    2 @CacheEvict
    @CacheEvict 作用:清除缓存
    2.1业务层
    /**
    * UsersService 接口实现类
    *
    *
    */
    @Service
    public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersRepository usersRepository;
    @Override
    @Cacheable(value="users")public List<Users> findUserAll() {
    return this.usersRepository.findAll();
    }
    @Override
    //@Cacheable:对当前查询的对象做缓存处理
    @Cacheable(value="users")
    public Users findUserById(Integer id) {
    return this.usersRepository.findOne(id);
    }
    @Override
    @Cacheable(value="users",key="#pageable.pageSize")
    public Page<Users> findUserByPage(Pageable pageable) {
    return this.usersRepository.findAll(pageable);
    }
    @Override
    //@CacheEvict(value="users",allEntries=true) 清除缓存中以 users 缓
    存策略缓存的对象
    @CacheEvict(value="users",allEntries=true)
    public void saveUsers(Users users) {
    this.usersRepository.save(users);
    }
    }
    2.2测试代码
    @Test
    public void testFindAll(){
    //第一次查询
    System.out.println(this.usersService.findUserAll().size());
    Users users = new Users();
    users.setAddress("南京");
    users.setAge(43);
    users.setName("朱七");
    this.usersService.saveUsers(users);
    //第二次查询
    System.out.println(this.usersService.findUserAll().size());
    }
     

    三、 Spring Boot 整合 Spring Data Redis

     
    Redis 版本:3.0.0
    运行环境:Linux
    1 安装 Redis
    1.1安装 gcc
    Yum install gcc-c++
    1.2解压 redis.3.0.0.tar.gz 压缩包
    tar -zxvf redis-3.0.0.tar.gz
    1.3进入解压后的目录进行编译
    cd redis-3.0.0
    a e
    1.4将 Redis 安装到指定目录
    make PREFIX=/usr/local/redis install
    1.5启动 Redis
    ./redis-server
    2 Spring Boot 整合 Spring Data Redis
    Spring Data Redis 是属于 Spring Data 下的一个模块。作用就是简化对于 redis 的操做
    2.1修改 pom 文件添加 Spring Data Redis 的坐标
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>24-spring-boot-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.versi
    on>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- thymeleaf 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- Spring Data Redis 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    </dependencies>
    </project>
    2.2编写 Spring Data Redis 的配置类(重点)
    /**
    * 完成对 Redis 的整合的一些配置*
    *
    */
    @Configuration
    public class RedisConfig {
    /**
    * 1.创建 JedisPoolConfig 对象。在该对象中完成一些链接池配置
    *
    */
    @Bean
    public JedisPoolConfig jedisPoolConfig(){
    JedisPoolConfig config = new JedisPoolConfig();
    //最大空闲数
    config.setMaxIdle(10);
    //最小空闲数
    config.setMinIdle(5);
    //最大链接数
    config.setMaxTotal(20);
    return config;
    }
    /**
    * 2.创建 JedisConnectionFactory:配置 redis 链接信息
    */
    @Bean
    public JedisConnectionFactory
    jedisConnectionFactory(JedisPoolConfig config){
    JedisConnectionFactory factory = new JedisConnectionFactory();
    //关联链接池的配置对象
    factory.setPoolConfig(config);
    //配置链接 Redis 的信息
    //主机地址
    factory.setHostName("192.168.70.128");
    //端口
    factory.setPort(6379);
    return factory;
    }
    /**
    * 3.创建 RedisTemplate:用于执行 Redis 操作的方法
    */@Bean
    public RedisTemplate<String,Object>
    redisTemplate(JedisConnectionFactory factory){
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    //关联
    template.setConnectionFactory(factory);
    //为 key 设置序列化器
    template.setKeySerializer(new StringRedisSerializer());
    //为 value 设置序列化器
    template.setValueSerializer(new StringRedisSerializer());
    return template;
    }
    }
    2.3编写测试代码,测试整合环境
    2.3.1 修改 pom 文件添加测试启动器坐标
    <!-- Test 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    2.3.2 编写测试类
    /**
    * Spring Data Redis 测试
    *
    *
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=App.class)
    public class RedisTest {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    /**
    * 添加一个字符串
    */@Test
    public void testSet(){
    this.redisTemplate.opsForValue().set("key", "北京尚学堂");
    }
    /**
    * 获取一个字符串
    */
    @Test
    public void testGet(){
    String value =
    (String)this.redisTemplate.opsForValue().get("key");
    System.out.println(value);
    }
    }
    3 提取 redis 的配置信息
    3.1在 src/main/resource/ 目 录 下 新 建 一 个 配 置 文
    件:application.properties
    spring.redis.pool.max-idle=10
    spring.redis.pool.min-idle=5
    spring.redis.pool.max-total=20
    spring.redis.hostName=192.168.70.128
    spring.redis.port=6379
    3.2修改配置类
    /**
    * 完成对 Redis 的整合的一些配置
    *
    *
    */
    @Configuration
    public class RedisConfig {
    /**
    * 1.创建 JedisPoolConfig 对象。在该对象中完成一些链接池配置
    * @ConfigurationProperties:会将前缀相同的内容创建一个实体。*/
    @Bean
    @ConfigurationProperties(prefix="spring.redis.pool")
    public JedisPoolConfig jedisPoolConfig(){
    JedisPoolConfig config = new JedisPoolConfig();
    /*//最大空闲数
    config.setMaxIdle(10);
    //最小空闲数
    config.setMinIdle(5);
    //最大链接数
    config.setMaxTotal(20);*/
    System.out.println("默认值:"+config.getMaxIdle());
    System.out.println("默认值:"+config.getMinIdle());
    System.out.println("默认值:"+config.getMaxTotal());
    return config;
    }
    /**
    * 2.创建 JedisConnectionFactory:配置 redis 链接信息
    */
    @Bean
    @ConfigurationProperties(prefix="spring.redis")
    public JedisConnectionFactory
    jedisConnectionFactory(JedisPoolConfig config){
    System.out.println("配置完毕:"+config.getMaxIdle());
    System.out.println("配置完毕:"+config.getMinIdle());
    System.out.println("配置完毕:"+config.getMaxTotal());
    JedisConnectionFactory factory = new JedisConnectionFactory();
    //关联链接池的配置对象
    factory.setPoolConfig(config);
    //配置链接 Redis 的信息
    //主机地址
    /*factory.setHostName("192.168.70.128");
    //端口
    factory.setPort(6379);*/
    return factory;
    }
    /**
    * 3.创建 RedisTemplate:用于执行 Redis 操作的方法
    */
    @Bean
    public RedisTemplate<String,Object>redisTemplate(JedisConnectionFactory factory){
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    //关联
    template.setConnectionFactory(factory);
    //为 key 设置序列化器
    template.setKeySerializer(new StringRedisSerializer());
    //为 value 设置序列化器
    template.setValueSerializer(new StringRedisSerializer());
    return template;
    }
    }
    4 Spring Data Redis 操作实体对象
    4.1.1 创建实体类
    public class Users implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
    public Integer getId() {
    return id;
    }
    public void setId(Integer id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }@Override
    public String toString() {
    return "Users [id=" + id + ", name=" + name + ", age=" + age +
    "]";
    }
    }
    4.1.2 测试代码
    /**
    * 添加 Users 对象
    */
    @Test
    public void testSetUesrs(){
    Users users = new Users();
    users.setAge(20);
    users.setName("张三丰");
    users.setId(1);
    //重新设置序列化器
    this.redisTemplate.setValueSerializer(new
    JdkSerializationRedisSerializer());
    this.redisTemplate.opsForValue().set("users", users);
    }
    /**
    * 取 Users 对象
    */
    @Test
    public void testGetUsers(){
    //重新设置序列化器
    this.redisTemplate.setValueSerializer(new
    JdkSerializationRedisSerializer());
    Users users =
    (Users)this.redisTemplate.opsForValue().get("users");
    System.out.println(users);
    }5 Spring Data Redis 以 JSON 格式存储实体对象
    5.1测试代码
    /**
    * 基于 JSON 格式存 Users 对象
    */
    @Test
    public void testSetUsersUseJSON(){
    Users users = new Users();
    users.setAge(20);
    users.setName("李四丰");
    users.setId(1);
    this.redisTemplate.setValueSerializer(new
    Jackson2JsonRedisSerializer<>(Users.class));
    this.redisTemplate.opsForValue().set("users_json", users);
    }
    /**
    * 基于 JSON 格式取 Users 对象
    */
    @Test
    public void testGetUseJSON(){
    this.redisTemplate.setValueSerializer(new
    Jackson2JsonRedisSerializer<>(Users.class));
    Users users =
    (Users)this.redisTemplate.opsForValue().get("users_json");
    System.out.println(users);
    }
     
     
     

    第六章节 Spring Boot 定时任务

     
    (SpringBoot 高级)
    课程内容
     Scheduled 定时任务器
     整合 Quartz 定时任务框架
     

    一、 Scheduled 定时任务器

     
    Scheduled 定时任务器:是 Spring3.0 以后自带的一个定时任务器。
     
     

    1 在 pom 文件中添加 Scheduled 的坐标

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>25-spring-boot-scheduled</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
    <java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.versi
    on>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency><groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- 添加 Scheduled 坐标 -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    </dependency>
    </dependencies>
    </project>
    View Code

    2 编写定时任务类

    /**
    * Scheduled 定时任务
    *
    *
    */
    @Component
    public class ScheduledDemo {
    /**
    * 定时任务方法
    * @Scheduled:设置定时任务
    * cron 属性:cron 表达式。定时任务触发是时间的一个字符串表达形式
    */
    @Scheduled(cron="0/2 * * * * ?")
    public void scheduledMethod(){
    System.out.println("定时器被触发"+new Date());
    }
    }
     

    3 在启动类中开启定时任务的使用

     
    /**
    *
    *Scheduled*
    */
    @SpringBootApplication
    @EnableScheduling
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }

    4 cron 表达式讲解

     
    Cron 表达式是一个字符串,分为 6 或 7 个域,每一个域代表一个含义
    Cron 有如下两种语法格式:
    (1) Seconds Minutes Hours Day Month Week Year
    (2)Seconds Minutes Hours Day Month Week
     

    一、结构

     
    corn 从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
     

    二、各字段的含义

     
    位置 时间域名 允许值 允许的特殊字符
     
    1 秒 0-59 , - * /
    2 分钟 0-59 , - * /
    3 小时 0-23 , - * /
    4 日 1-31 , - * / L W C
    5 月 1-12 , - * /
    6 星期 1-7 , - * ? / L C #
    7 年(可选) 1970-2099 , - * /
     
    Cron 表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功
    能,细说如下:●星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;
     
     
    ●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符;
     
    ●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从 10 到 12 点,即 10,11,12;
     
    ●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;
     
    ●斜杠(/):x/y 表达一个等步长序列,x 为起始值,y 为增量步长值。如在分钟字段中使用 0/15,则
    表示为 0,15,30 和 45 秒,而 5/15 在分钟字段中表示 5,20,35,50,你也可以使用*/y,它等同于 0/y;
     
    ●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L 在日期
    字段中,表示这个月份的最后一天,如一月的 31 号,非闰年二月的 28 号;如果 L 用在星期中,则表示星
    期六,等同于 7。但是,如果 L 出现在星期字段里,而且在前面有一个数值 X,则表示“这个月的最后 X 天”,
    例如,6L 表示该月的最后星期五;
     
    ●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如 15W
    表示离该月 15 号最近的工作日,如果该月 15 号是星期六,则匹配 14 号星期五;如果 15 日是星期日,
    则匹配 16 号星期一;如果 15 号是星期二,那结果就是 15 号星期二。但必须注意关联的匹配日期不能够
    跨月,如你指定 1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那天。W 字符串
    只能指定单一日期,而不能指定日期范围;
     
    ●LW 组合:在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日;
     
    ●井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如 6#3 表示当月的第三个星期五(6
    表示星期五,#3 表示当前的第三个),而 4#5 表示当月的第五个星期三,假设当月没有第五个星期三,
    忽略不触发;
     
    ● C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,
    如果日期没有被关联,则相当于日历中所有日期。例如 5C 在日期字段中就相当于日历 5 日以后的第一天。
    1C 在星期字段中相当于星期日后的第一天。
      Cron 表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。
    例子:
    @Scheduled(cron = "0 0 1 1 1 ?")//每年一月的一号的 1:00:00 执行一次
    @Scheduled(cron = "0 0 1 1 1,6 ?") //一月和六月的一号的 1:00:00 执行一次
    @Scheduled(cron = "0 0 1 1 1,4,7,10 ?") //每个季度的第一个月的一号的 1:00:00 执行一次
    @Scheduled(cron = "0 0 1 1 * ?")//每月一号 1:00:00 执行一次
    @Scheduled(cron="0 0 1 * * *") //每天凌晨 1 点执行一次二、
     
     

    Spring Boot 整合 Quartz 定时任务框架

     
    1 Quartz 的介绍以及 Quartz 的使用思路
     
    1.1Quartz 的介绍
     
    1.2Quartz 的使用思路
     
    1)job - 任务 - 你要做什么事?
    2)Trigger - 触发器 - 你什么时候去做?
    3)Scheduler - 任务调度 - 你什么时候需要去做什么事?
     

    2 Quartz 的基本使用方式

     

    2.1创建项目 

     
     
     
     

    2.2修改 pom 文件添加 Quartz 的坐标

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bjsxt</groupId>
    <artifactId>26-quartz-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
    <!-- Quartz 坐标 --><dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    </dependency>
    </dependencies>
    </project>
    View Code

    2.3创建 Job 类

     
    /**
    * 定义任务类
    *
    *
    */
    public class QuartzDemo implements Job {
    /**
    * 任务被触发时所执行的方法
    */
    public void execute(JobExecutionContext arg0) throws
    JobExecutionException {
    System.out.println("Execute...."+new Date());
    }
    }
     

    2.4编写测试代码

    public class QuartzMain {
    public static void main(String[] args) throws Exception {
    // 1.创建 Job 对象:你要做什么事?
    JobDetail job = JobBuilder.newJob(QuartzDemo.class).build();
    /**
    * 简单的 trigger 触发时间:通过 Quartz 提供一个方法来完成简单的重复
    调用 cron
    * Trigger:按照 Cron 的表达式来给定触发的时间
    */
    // 2.创建 Trigger 对象:在什么时间做?
    /*Trigger trigger =TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSe
    condlyForever())
    .build();*/
    Trigger trigger =
    TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedu
    le("0/2 * * * * ?"))
    .build();
    // 3.创建 Scheduler 对象:在什么时间做什么事?
    Scheduler scheduler =
    StdSchedulerFactory.getDefaultScheduler();
    scheduler.scheduleJob(job, trigger);
    //启动
    scheduler.start();
    }
    }
     
     
     

    3 .Spring Boot 整合 Quartz 定时框架

     

    3.1修改 pom 文件添加坐标

     
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    </parent>
    <groupId>com.bjsxt</groupId>
    <artifactId>27-spring-boot-quartz</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties><java.version>1.7</java.version>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.ve
    rsion>
    </properties>
    <dependencies>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- springBoot 的启动器 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- Quartz 坐标 -->
    <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    <exclusions>
    <exclusion>
    <artifactId>slf4j-api</artifactId>
    <groupId>org.slf4j</groupId>
    </exclusion>
    </exclusions>
    </dependency>
    <!-- 添加 Scheduled 坐标 -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    </dependency>
    <!-- Sprng tx 坐标 -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    </dependency>
    </dependencies></project>
    View Code

    3.2编写 Quartz 的启动类

     
    /**
    * Quartz 配置类
    *
    *
    */
    
    @Configuration
    public class QuartzConfig {
    /**
    * 1.创建 Job 对象
    */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
    JobDetailFactoryBean factory = new JobDetailFactoryBean();
    //关联我们自己的 Job 类
    factory.setJobClass(QuartzDemo.class);
    return factory;
    }
    /**
    * 2.创建 Trigger 对象
    * 简单的 Trigger
    */
    @Bean
    public SimpleTriggerFactoryBean
    simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
    SimpleTriggerFactoryBean factory = new
    SimpleTriggerFactoryBean();
    //关联 JobDetail 对象
    factory.setJobDetail(jobDetailFactoryBean.getObject());
    //该参数表示一个执行的毫秒数
    factory.setRepeatInterval(2000);
    //重复次数
    factory.setRepeatCount(5);
    return factory;
    }/**
    * 3.创建 Scheduler 对象
    */
    @Bean
    public SchedulerFactoryBean
    schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
    SchedulerFactoryBean factory = new SchedulerFactoryBean();
    //关联 trigger
    factory.setTriggers(simpleTriggerFactoryBean.getObject());
    return factory;
    }
    }

    3.3修改启动类

     
    /**
    *
    *spring Boot 整合 Quartz 案例
    *
    */
    @SpringBootApplication
    @EnableScheduling
    public class App {
    public static void main(String[] args) {
    SpringApplication.run(App.class, args);
    }
    }
     

    4 Job 类中注入对象

     

    4.1注入时会产生异常4.2编写一个 MyAdaptableJobFactory

     
     

    4.2编写一个 MyAdaptableJobFactory 解决该问题

     
    @Component("myAdaptableJobFactory")
    public class MyAdaptableJobFactory extends AdaptableJobFactory {
    //AutowireCapableBeanFactory 可以将一个对象添加到 SpringIOC 容器中,
    并且完成该对象注入
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;
    /**
    * 该方法需要将实例化的任务对象手动的添加到 springIOC 容器中并且完成对
    象的注入
    */
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle)
    throws Exception {
    Object obj = super.createJobInstance(bundle);
    //将 obj 对象添加 Spring IOC 容器中,并完成注入
    this.autowireCapableBeanFactory.autowireBean(obj);
    return obj;
    }
    }
     

    4.3修改 QuartzConfig 类

    /**
    * Quartz 配置类
    *
    *
    */
    @Configuration
    public class QuartzConfig {
    /**
    * 1.创建 Job 对象
    */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
    JobDetailFactoryBean factory = new JobDetailFactoryBean();//关联我们自己的 Job 类
    factory.setJobClass(QuartzDemo.class);
    return factory;
    }
    /**
    * 2.创建 Trigger 对象
    * 简单的 Trigger
    */
    /*@Bean
    public SimpleTriggerFactoryBean
    simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
    SimpleTriggerFactoryBean factory = new
    SimpleTriggerFactoryBean();
    //关联 JobDetail 对象
    factory.setJobDetail(jobDetailFactoryBean.getObject());
    //该参数表示一个执行的毫秒数
    factory.setRepeatInterval(2000);
    //重复次数
    factory.setRepeatCount(5);
    return factory;
    }*/
    /**
    * Cron Trigger
    */
    @Bean
    public CronTriggerFactoryBean
    cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
    CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
    factory.setJobDetail(jobDetailFactoryBean.getObject());
    //设置触发时间
    factory.setCronExpression("0/2 * * * * ?");
    return factory;
    }
    /**
    * 3.创建 Scheduler 对象
    */
    @Bean
    public SchedulerFactoryBean
    schedulerFactoryBean(CronTriggerFactoryBean
    cronTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
    SchedulerFactoryBean factory = new SchedulerFactoryBean();//关联 trigger
    factory.setTriggers(cronTriggerFactoryBean.getObject());
    factory.setJobFactory(myAdaptableJobFactory);
    return factory;
    }
    }
    View Code
     
     
  • 相关阅读:
    优化不易,且写且珍惜
    作为过来人的感悟:进了小公司的程序员如何翻身进入大公司
    腾讯/阿里/百度 BAT人才体系的职位层级、薪酬、晋升标准
    校招生向京东发起的“攻势”,做到他这样,你,也可以
    通过Java 线程堆栈进行性能瓶颈分析
    基于Spring Cloud的微服务落地
    多线程技术使用指南
    Android 处理含有EditText的Activity虚拟键盘
    Android ListView的监听事件
    Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用
  • 原文地址:https://www.cnblogs.com/wq-9/p/11094880.html
Copyright © 2020-2023  润新知