美文网首页Spring cloud
Springboot5 开发常用技术整合--笔记

Springboot5 开发常用技术整合--笔记

作者: 牵手生活 | 来源:发表于2019-03-31 23:50 被阅读133次

    前言

    现在公司比较流行SpringCloud或阿里的dobbo,这2个技术都需要Springboot,因为Springboot在微服务的基础。

    微框架,与Spring4一起诞生,比如SpringMVC中的@RestController,使用它可以在web页面直接放回一个json到web页面或app
    Springboot可以快速上手,整合了一下子项目(开源框架或第三方开源库)
    Springboot可以依赖很少的配置,就可以十分快速的搭建并运行项目。
    

    这里主要采用的基础项目
    Spring Boot 2多模块 Spring Boot 项目--之多模块重构
    项目下载地址

    https://yunpan.360.cn/surl_yFtZK2c74HC (提取码:a184)
    

    涉及到的知识点

    • 构建Springboot项目
    • Springboot接口返回json及jackson使用
    • Springboot热部署
    • Springboot资源属性配置
    • Springboot模板引擎--thymeleaf
    • springboot异常处理

    Springboot特点

    • 基于Spring,使开发者快速入门,门槛很低。spring的全家桶提供了非常强大的功能。
    • Springboot可以创建独立运行的应用,而不依赖与容器。
    • 不需要打包成war包,可以放入tomcat中直接运行
    • Springboot提供manven极简配置,不用在看过多的xml(默认配置),切点是会引入狠多你不需要的包
    • Springboot提供可视化的相关功能,方便监控,比如性能,应用的健康程度。
    • Springboot微微服务SpringCloud铺路,SpringBoot可以整合很多各式各样的框架来构建微服务,比如dubbo,thrift

    构建Springboot项目(参考之前的文章)

    Spring Boot 1第一个项目-helloWorld

    #官方地址
    https://spring.io/
    

    SpringBoot接口返回json及Jackson的基本演绎

    Jackson快速入门-csdn

    #添加数据web api方式返回POST
    localhost:8080/person/saveApi?name=牵手生活22&age=18&password=123456
    #获取模拟数据返回GET
    localhost:8080/person/getUserDemo
    

    先看看实现的效果时什么样的,实现中功能修改了2个文件User.java、UserController.java,并增加了Api接口外的类IYounghareJsonResult.java(来自github的LeeJSONResult.java)

    saveApi 以api的方式返回--没有jackson saveApi 以api的方式返回--没有jackson

    修改的User.java实体如下

    public class User {
        private int id;
        private String name;
        private int age;  //年龄
        @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss a",locale = "zh",timezone = "GMT+8")
        private  Date birthday;  //出生年月
    
        @JsonIgnore //json返回时,忽略
        private String password; //密码
    
        @JsonInclude(JsonInclude.Include.NON_NULL)  //当数据为空时不返回
        private String desc;  //描述
    
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    ", birthday=" + birthday +
                    ", password='" + password + '\'' +
                    ", desc='" + desc + '\'' +
                    '}';
        }
    
    }
    
    

    UserController.java增加了saveApi接口

    
    @RestController  //表示是一个Rest接口  ==@Controller+ @ResponseBody(方法位置)
    public class UserController {
    
        private  final UserRepostory userRepostory;  //没有初始化,这里采用构造器注入的方式
    
        @Autowired
        public UserController(UserRepostory userRepostory){
            this.userRepostory = userRepostory;
    
        }
    
        @PostMapping("/person/save")
        //@RequestBody  ==采用@RestController 不再需要这个
        public User save(@RequestParam String name,@RequestParam int age,@RequestParam String password){
    
            User user = new User();
            user.setName(name);
            user.setAge(age);
            user.setPassword(password);
    
            user.setBirthday(new Date());
    
            user.setDesc(null);
    
            if (userRepostory.save(user)){
                System.out.printf("用户对象:%s 保存成功\n",user);
            }
            return user;
        }
    
    
        @PostMapping("/person/saveApi")
        public IYounghareJSONResult saveApi(@RequestParam String name,@RequestParam int age){
    
            User user = new User();
            user.setName(name);
            user.setAge(age);
    
            user.setBirthday(new Date());
    
            user.setDesc(null);
    
            if (userRepostory.save(user)){
                System.out.printf("用户对象:%s 保存成功\n",user);
            }
            //return user;
            return IYounghareJSONResult.ok(user);
        }
    
        @GetMapping("/person/getUserDemo")
        //@RequestBody  ==采用@RestController 不再需要这个
        public User getUserDemo(){
    
            User user = new User();
            user.setName("牵手");
            user.setAge(18);
            user.setPassword("123456");
    
            user.setBirthday(new Date());
    
            user.setDesc(null);
    
    
            return user;
        }
    
    }
    
    
    
    
    
    Get模拟User数据返回

    IYounghareJsonResult.java 工具类代码

    
    /**
     *
     * @Title: LeeJSONResult.java
     * @Package com.lee.utils
     * @Description: 自定义响应数据结构
     *              这个类是提供给门户,ios,安卓,微信商城用的
     *              门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
     *              其他自行处理
     *              200:表示成功
     *              500:表示错误,错误信息在msg字段中
     *              501:bean验证错误,不管多少个错误都以map形式返回
     *              502:拦截器拦截到用户token出错
     *              555:异常抛出信息
     * Copyright: Copyright (c) 2016
     * Company:Nathan.Lee.Salvatore
     *
     * @author leechenxiang
     * @date 2016年4月22日 下午8:33:36
     * @version V1.0
     */
    
    public class IYounghareJSONResult {
    
        // 定义jackson对象
        private static final ObjectMapper MAPPER = new ObjectMapper();
    
        // 响应业务状态
        private Integer status;
    
        // 响应消息
        private String msg;
    
        // 响应中的数据
        private Object data;
    
        private String ok;  // 不使用
    
        public static IYounghareJSONResult build(Integer status, String msg, Object data) {
            return new IYounghareJSONResult(status, msg, data);
        }
    
        public static IYounghareJSONResult ok(Object data) {
            return new IYounghareJSONResult(data);
        }
    
        public static IYounghareJSONResult ok() {
            return new IYounghareJSONResult(null);
        }
    
        public static IYounghareJSONResult errorMsg(String msg) {
            return new IYounghareJSONResult(500, msg, null);
        }
    
        public static IYounghareJSONResult errorMap(Object data) {
            return new IYounghareJSONResult(501, "error", data);
        }
    
        public static IYounghareJSONResult errorTokenMsg(String msg) {
            return new IYounghareJSONResult(502, msg, null);
        }
    
        public static IYounghareJSONResult errorException(String msg) {
            return new IYounghareJSONResult(555, msg, null);
        }
    
        public IYounghareJSONResult() {
    
        }
    
    //    public static LeeJSONResult build(Integer status, String msg) {
    //        return new LeeJSONResult(status, msg, null);
    //    }
    
        public IYounghareJSONResult(Integer status, String msg, Object data) {
            this.status = status;
            this.msg = msg;
            this.data = data;
        }
    
        public IYounghareJSONResult(Object data) {
            this.status = 200;
            this.msg = "OK";
            this.data = data;
        }
    
        public Boolean isOK() {
            return this.status == 200;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
        /**
         *
         * @Description: 将json结果集转化为LeeJSONResult对象
         *              需要转换的对象是一个类
         * @param jsonData
         * @param clazz
         * @return
         *
         * @author leechenxiang
         * @date 2016年4月22日 下午8:34:58
         */
        public static IYounghareJSONResult formatToPojo(String jsonData, Class<?> clazz) {
            try {
                if (clazz == null) {
                    return MAPPER.readValue(jsonData, IYounghareJSONResult.class);
                }
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("data");
                Object obj = null;
                if (clazz != null) {
                    if (data.isObject()) {
                        obj = MAPPER.readValue(data.traverse(), clazz);
                    } else if (data.isTextual()) {
                        obj = MAPPER.readValue(data.asText(), clazz);
                    }
                }
                return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
            } catch (Exception e) {
                return null;
            }
        }
    
        /**
         *
         * @Description: 没有object对象的转化
         * @param json
         * @return
         *
         * @author leechenxiang
         * @date 2016年4月22日 下午8:35:21
         */
        public static IYounghareJSONResult format(String json) {
            try {
                return MAPPER.readValue(json, IYounghareJSONResult.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         *
         * @Description: Object是集合转化
         *              需要转换的对象是一个list
         * @param jsonData
         * @param clazz
         * @return
         *
         * @author leechenxiang
         * @date 2016年4月22日 下午8:35:31
         */
        public static IYounghareJSONResult formatToList(String jsonData, Class<?> clazz) {
            try {
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("data");
                Object obj = null;
                if (data.isArray() && data.size() > 0) {
                    obj = MAPPER.readValue(data.traverse(),
                            MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
                }
                return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
            } catch (Exception e) {
                return null;
            }
        }
    
        public String getOk() {
            return ok;
        }
    
        public void setOk(String ok) {
            this.ok = ok;
        }
    }
    
    

    代码先保存,方便之后修改或提前
    https://yunpan.360.cn/surl_yFtcg3T5PvF (提取码:7df9)


    SpringBoot开发环境热部署(可行我好像没有热部署成功)

    开发环境中,如果修改某个文件,如修改User或、UserController需要重启服务器
    Springboot使用devtools进行热部署

    idea中配置Springboot热部署

    在pom.xml文件中添加

    <!-- 热部署 -->
            <!-- devtools可以实现页面热部署(即页面修改后会立即生效,
                这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现) -->
            <!-- 实现类文件热部署(类文件修改后不会立即生效),实现对属性文件的热部署。 -->
            <!-- 即devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机),
                注意:因为其采用的虚拟机机制,该项重启是很快的 -->
            <!-- (1)base classloader (Base类加载器):加载不改变的Class,例如:第三方提供的jar包。 -->
            <!-- (2)restart classloader(Restart类加载器):加载正在开发的Class。 -->
            <!-- 为什么重启很快,因为重启的时候只是加载了在开发的Class,没有重新加载第三方的jar包。 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <!-- optional=true, 依赖不会传递, 该项目依赖devtools; 
                    之后依赖boot项目的项目如果想要使用devtools, 需要重新引入 -->
                <optional>true</optional>
            </dependency>
    

    修改application.properties 添加如下内容(#开始的是注释)

    #热部署生效
    spring.devtools.restart.enabled=true
    #设置重启的目录,添加哪个目录的文件需要重启
    spring.devtools.restart.additional-paths=src/main/java
    # 为amybatis设置,生成环境可以删除
    #restart.include.mapper=/mapper-[\\w-\\.]+jar
    #restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
    #排除哪个目录的文件不需要重启
    #spring.devtools.restart.exclude=static/**,public/**
    #classpath目录下的WEB-INF文件夹内容修改不重启(静态文件的修改不需要重启)
    #spring.devtools.restart.exclude=WEB-INF/**
    
    idea设置热部署

    SpringBoot 资源文件属性配置application.properties

    在pom.xml文件中添加依赖

            <!--#资源文件属性配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
    

    我在使用@configurationProperties注解时 idea弹出 Spring Boot Annotion processor not found in classpath

    创建czgResource.properties资源文件、创建Resouce.java类、创建ResourceController.java类


    添加类及资源文件

    访问路径及效果

    localhost:8080/resouce/getResouce
    
    访问的效果

    czgResource.properties

    
    com.younghare.opensource.name=牵手生活--简书
    com.younghare.opensource.website=https://www.jianshu.com/u/e09dc5872735
    com.younghare.opensource.desc=笔记整理。分享是一种美德,牵手生活,携手前行
    

    CzgResouce.java

    
    @Configuration  //表示要引用资源文件的配置
    @ConfigurationProperties(prefix="com.younghare.opensource")
    @PropertySource(value= "classpath:czgResource.properties")
    
    public class CzgResouce {
        private String name;
        private String webSite;
    
    
    
        private String desc;
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getWebSite() {
            return webSite;
        }
    
        public void setWebSite(String webSite) {
            this.webSite = webSite;
        }
    
    }
    
    

    ResourceController.java

    @RestController  //表示是一个Rest接口  ==@Controller+ @ResponseBody(方法位置)
    public class ResourceController {
    
        @Autowired
        private CzgResouce czgResouce;
        @RequestMapping("/resouce/getResouce")
        public IYounghareJSONResult getCzgResouce(){
            CzgResouce bean_Czg_resouce = new CzgResouce();
            BeanUtils.copyProperties(czgResouce, bean_Czg_resouce);
            return IYounghareJSONResult.ok(bean_Czg_resouce);
    
        }
    }
    
    

    SpringBoot 资源文件配置server以及tomcat及端口

    Springboot默认是使用tomcat,更多细节参考

    SpringBoot配置属性之Server

    修改application.properties文件如下:

    #####################################################
    #
    # Server 服务器端相关配置
    #####################################################
    #配置api端口
    server.port=8081
    #设定应用的context-path,一般来说这个配置在正式发布的时候不配置
    #server.servlet.context-path=/IYounghare
    #错误页面,指定发生错误时,跳转的URL -->BasicErrorController
    server.error.path=/error
    #session最大超时时间(分钟),默认30分钟
    server.servlet.session.timeout=60
    #该服务器绑定IP地址,启动服务器时如果本机不是该IP地址则抛出异常,启动失败,
    #只有特殊需求的情况下才配置,具体根据各自的业务来设置
    
    #####################################################
    #
    # Server --tomcat服务器端相关配置
    #####################################################
    #tomcat最大的线程数,默认200
    #server.tomcat.max-threads=180
    #tomcat的URI编码
    server.tomcat.uri-encoding=UTF-8
    #存放tomcat的日志,dump等文件的临时文件夹,默认为系统的tmp文件夹
    #如:c:\users\younghare\AppData\Local\Temp\
    server.tomcat.accesslog.enabled=true
    #server.tomcat.accesslog.pattern=
    #accesslog目录,默认在basedir/logs
    #server.tomcat.accesslog.directory=
    #日志文件目录
    logging.path= D:/czg/czgTemp/springboot-tomcat-tmp
    #日志文件名称,默认为spring.log
    #logging.file= myapp.log
    
    日志文件名及日志文件路径

    SpringBoot 整合模板引擎freemarker(略)、thyemleaf

    在resources资源下创建templates文件夹


    创建templates文件夹
    整合thymeleaf

    在pom.xml中添加依赖

            <!-- 引入 thymeleaf 模板依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    

    在application.properties 添加thymeleaf的配置信息

    
    #####################################################
    #
    #thymeleaf 静态资源配置
    #
    #####################################################
    #前缀,默认文件夹
    spring.thymeleaf.prefix=classpath:/templates/
    #后缀时.html
    spring.thymeleaf.suffix=.html
    #模式使用html5
    spring.thymeleaf.mode=HTML5
    spring.thymeleaf.encoding=UTF-8
    #deprecated configuration property spring.thymeleaf.content-type 意思是这个属性已经过时不被使用
    #spring.thymeleaf.content-type=text/html
    #content-type 是text和html
    spring.thymeleaf.servlet.content-type=text/html 
    # 关闭缓存,即时刷新,上线生成环境需要改为true
    spring.thymeleaf.cache=false
    
    

    springboot集成themeleaf报Namespace 'th' is not bound

    thymeleaf增加的文件

    ThymeleafController.java

    @Controller
    @RequestMapping("th_czg") //设置访问路径
    public class ThymeleafController {
    
    
    
        @RequestMapping("dynamicThymeleaf")
        public String dynamicThymeleaf(ModelMap map) {
            map.addAttribute("name", "thymeleaf-为什么进不了这个断点");
            return "thymeleaf/dynamicThymeleaf/dynamicThymeleafDemo";
        }
        @RequestMapping("staticThymeleaf")
        public String staticThymeleaf() {
            return "thymeleaf/staticThymeleaf/thymeleafDemo";
        }
    }
    
    

    thymeleafDemo.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    Thymeleaf模板引擎--静态demo
    <h1>thymeleafDemo page</h1>
    
    </body>
    </html>
    

    dynamicThymeleafDemo.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
    <head >
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    Thymeleaf模板引擎
    
    <!-- 注意: th 等thymeleaf表达式 ,在直接用浏览器打开该html文件时,不会被加载,只有后台有返回对应的值时才有对应的内容-->
    
    <h1 th:text="${name}">hello world~~~~~~~</h1>
    </body>
    </html>
    

    测试地址

    #测试静态地址
    http://localhost:8080/th_czg/staticThymeleaf
    #加载动态
    http://localhost:8080/th_czg/dynamicThymeleaf
    
    成功加载静态thymeleaf 加载动态thymeleaf失败--需要查原因
    Whitelabel Error Page
    This application has no configured error view, so you are seeing this as a fallback.
    
    Sun Mar 31 23:30:21 CST 2019
    There was an unexpected error (type=Internal Server Error, status=500).
    Failed to invoke handler method with resolved arguments: [0][type=org.springframework.validation.support.BindingAwareConcurrentModel][value={}] on public java.lang.String com.younghare.springBoothelloworld.controller.ThymeleafController.dynamicThymeleaf(org.springframework.ui.ModelMap)
    

    网络解决方案--好像也没办法解决----有哪位大神帮我留言一下
    http://javaetmoi.com/2017/12/migration-spring-web-mvc-vers-spring-webflux/
    【spring boot学习】Model&ModelMap&ModelAndView--csdn

    在pom.xml中引入SpringMVC的支持,就解决了

            <!--添加springmvc的支持-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    

    thymeleaf常用标签的使用方法

    thymeleaf的简单用法-常用标签-csdm

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

    thymeleaf综合例子test.html,来自github

    #测试路径
    http://localhost:8080/th_czg/test
    
    <!DOCTYPE html>
    <html xmlns:th="http://www.w3.org/1999/xhtml">
    <head lang="en">
        <meta charset="UTF-8" />
        <title></title>
    
        <!--    <script th:src="@{/static/js/test.js}"></script> -->
    
    </head>
    <body>
    
    <div>
        用户姓名:<input th:id="${user.name}" th:name="${user.name}" th:value="${user.name}"/>
        <br/>
        用户年龄:<input th:value="${user.age}"/>
        <br/>
        用户生日:<input th:value="${user.birthday}"/>
        <br/>
        用户生日:<input th:value="${#dates.format(user.birthday, 'yyyy-MM-dd')}"/>
        <br/>
    </div>
    
    <br/>
    
    <div th:object="${user}">
        用户姓名:<input th:id="*{name}" th:name="*{name}" th:value="*{name}"/>
        <br/>
        用户年龄:<input th:value="*{age}"/>
        <br/>
        用户生日:<input th:value="*{#dates.format(birthday, 'yyyy-MM-dd hh:mm:ss')}"/>
        <br/>
    </div>
    
    <br/>
    
    text 与 utext :<br/>
    <span th:text="${user.desc}">abc</span>
    <br/>
    <span th:utext="${user.desc}">abc</span>
    <br/>
    <br/>
    
    URL:<br/>
    <a href="" th:href="@{http://www.imooc.com}">网站地址</a>
    <br/>
    
    <br/>
    <form th:action="@{/th/postform}" th:object="${user}" method="post" th:method="post">
        <input type="text" th:field="*{name}"/>
        <input type="text" th:field="*{age}"/>
        <input type="submit"/>
    </form>
    <br/>
    
    <br/>
    <div th:if="${user.age} == 18">十八岁的天空</div>
    <div th:if="${user.age} gt 18">你老了</div>
    <div th:if="${user.age} lt 18">你很年轻</div>
    <div th:if="${user.age} ge 18">大于等于</div>
    <div th:if="${user.age} le 18">小于等于</div>
    <br/>
    
    <br/>
    <select>
        <option >选择框</option>
        <option th:selected="${user.name eq 'lee'}">lee</option>
        <option th:selected="${user.name eq 'imooc'}">imooc</option>
        <option th:selected="${user.name eq 'LeeCX'}">LeeCX</option>
    </select>
    <br/>
    
    <br/>
    <table>
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>年龄备注</th>
            <th>生日</th>
        </tr>
        <tr th:each="person:${userList}">
            <td th:text="${person.name}"></td>
            <td th:text="${person.age}"></td>
            <td th:text="${person.age gt 18} ? 你老了 : 你很年轻">18岁</td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd hh:mm:ss')}"></td>
        </tr>
    </table>
    <br/>
    
    <br/>
    <div th:switch="${user.name}">
        <p th:case="'lee'">lee</p>
        <p th:case="#{roles.manager}">普通管理员</p>
        <p th:case="#{roles.superadmin}">超级管理员</p>
        <p th:case="*">其他用户</p>
    </div>
    <br/>
    
    </body>
    </html>
    

    Springboot异常处理

    Springboot配置全局的异常捕获--web页面跳转

    页面跳转形式
    ajax形式
    统一返回异常的形式

    创建模拟异常的ErrorController.java

    
    @Controller
    @RequestMapping("err")
    public class ErrorController {
    
        @RequestMapping("/error")
        public String error() {
    
            int a = 1 / 0;    //除零错误
    
            return "thymeleaf/error";//不存在的地址
        }
    
        @RequestMapping("/ajaxerror")
        public String ajaxerror() {
    
            return "thymeleaf/ajaxerror";
        }
    
        @RequestMapping("/getAjaxerror")
        @ResponseBody
        public IYounghareJSONResult getAjaxerror() {
    
            int a = 1 / 0;
    
            return IYounghareJSONResult.ok();
        }
    }
    
    #故意除零异常
    http://localhost:8080/err/error
    

    springMVC出现Cannot resolve symbol 'HttpServletRequest

    在pom.xml中引入SpringMVC的支持

            <!--添加springmvc的支持-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    

    访问网页http://localhost:8080//err/error 发现错误如下图

    除零错误提示

    编写我们自己的异常处理类IYounghareExceptionHandler.java
    注意注解部分

    @ControllerAdvice  //spring mvc提供了ControllerAdvice注解对异常进行统一的处理,拿到这些异常信息后,可以做一些处理,比如提供一个统一的web界
    public class IYounghareExceptionHandler {
    
        public static final String YOUNGHARE_ERROR_VIEW = "thymeleaf/error";
    
        @ExceptionHandler(value = Exception.class)
        public Object errorHandler(HttpServletRequest reqest,
                                   HttpServletResponse response, Exception e) throws Exception {
    
            e.printStackTrace();
    
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", reqest.getRequestURL());  //发生错误的地址
            mav.setViewName(YOUNGHARE_ERROR_VIEW);  //设置错误页面
            return mav;
        }
    
    }
    
    

    编写自己的error.html提示页面

    <!DOCTYPE html>
    <html xmlns:th="http://www.w3.org/1999/xhtml">
    <head lang="en">
        <meta charset="UTF-8" />
        <title>捕获全局异常</title>
    </head>
    <body>
    
    拦截到了我们捕获的异常,我们可以根据项目需要美化该页面
    <h1 style="color: red">发生错误:</h1>
    <div th:text="${url}"></div>
    <div th:text="${exception.message}"></div>
    </body>
    </html>
    

    Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理

    i自定义异常处理页面的显示效果
    SpringBoot配置全局的异常捕获 - ajax形式
    测试地址:
    http://localhost:8080//err/ajaxerror
    

    在application.properties文件中为SpringMVC 设置static地址

    #Spring Boot的默认静态资源的路径为:
    #spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
    #优先级从从高到低。
    spring.mvc.static-path-pattern=/static/**
    
    在chrome中开发者选项中设置debug 断点

    整合MyBatis - 使用generatorConfig生成mapper以及pojo

    • 使用generatorConfig生成mapper以及pojo ???
    • 实现基于mybatis的CRUD功能 ???
    • 整合mybatis-pagehelper实现分页
      自定义mapper的实现
    #github的项目
    https://github.com/leechenxiang/imooc-springboot-starter
    #Spring Boot 集成 MyBatis, 分页插件 PageHelper, 通用 Mapper
    https://github.com/abel533/MyBatis-Spring-Boot
    #PageHelper-Spring-Boot-Starter 帮助你集成分页插件到 Spring Boot。
    https://github.com/pagehelper/pagehelper-spring-boot
    
    用Navicat创建mysql数据库 leecx

    并执行sql脚本leecx.sql,执行后的


    执行leecx.sql脚本之后情况
    /*
    Navicat MySQL Data Transfer
    
    Source Server         : .
    Source Server Version : 50505
    Source Host           : localhost:3306
    Source Database       : leecx
    
    Target Server Type    : MYSQL
    Target Server Version : 50505
    File Encoding         : 65001
    
    Date: 2018-03-29 16:29:17
    */
    
    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for data_dict
    -- ----------------------------
    DROP TABLE IF EXISTS `data_dict`;
    CREATE TABLE `data_dict` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `type_name` varchar(64) NOT NULL COMMENT '数据字典类型名称',
      `type_code` varchar(64) DEFAULT NULL COMMENT '数据字典类型代码',
      `ddkey` varchar(6) NOT NULL COMMENT '数据键',
      `ddvalue` varchar(12) NOT NULL COMMENT '数据值',
      `is_show` int(1) NOT NULL COMMENT '是否显示,1:显示;2:不显示',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COMMENT='数据字典表';
    
    -- ----------------------------
    -- Records of data_dict
    -- ----------------------------
    INSERT INTO `data_dict` VALUES ('1', '性别', 'sex', '0', '女', '1');
    INSERT INTO `data_dict` VALUES ('2', '性别', 'sex', '1', '男', '1');
    INSERT INTO `data_dict` VALUES ('3', '性别', 'sex', '2', '保密', '1');
    INSERT INTO `data_dict` VALUES ('4', '汽车类型', 'carType', '2', '公交车', '1');
    INSERT INTO `data_dict` VALUES ('5', '汽车类型', 'carType', '1', '轿车', '1');
    INSERT INTO `data_dict` VALUES ('6', '职业', 'job', '1', 'Java开发', '1');
    INSERT INTO `data_dict` VALUES ('7', '职业', 'job', '2', '前端开发', '1');
    INSERT INTO `data_dict` VALUES ('8', '职业', 'job', '3', '大数据开发', '1');
    INSERT INTO `data_dict` VALUES ('9', '职业', 'job', '4', 'ios开发', '1');
    INSERT INTO `data_dict` VALUES ('10', '职业', 'job', '5', 'Android开发', '1');
    INSERT INTO `data_dict` VALUES ('11', '职业', 'job', '6', 'Linux系统工程师', '1');
    INSERT INTO `data_dict` VALUES ('12', '职业', 'job', '7', 'PHP开发', '1');
    INSERT INTO `data_dict` VALUES ('13', '职业', 'job', '8', '.net开发', '1');
    INSERT INTO `data_dict` VALUES ('14', '职业', 'job', '9', 'C/C++', '1');
    INSERT INTO `data_dict` VALUES ('15', '职业', 'job', '10', '学生', '0');
    INSERT INTO `data_dict` VALUES ('16', '职业', 'job', '11', '其它', '1');
    INSERT INTO `data_dict` VALUES ('17', '职业', 'job', '12', '全栈牛逼架构师', '1');
    INSERT INTO `data_dict` VALUES ('18', '汽车类型', 'carType', '3', '海陆两用', '1');
    
    -- ----------------------------
    -- Table structure for demo_item
    -- ----------------------------
    DROP TABLE IF EXISTS `demo_item`;
    CREATE TABLE `demo_item` (
      `id` varchar(20) NOT NULL,
      `name` varchar(255) NOT NULL,
      `amount` int(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of demo_item
    -- ----------------------------
    INSERT INTO `demo_item` VALUES ('170909FRA2NB7TR4', '红翼 red wing', '215000');
    INSERT INTO `demo_item` VALUES ('170909FRB9DPXY5P', '红翼 9111', '210000');
    INSERT INTO `demo_item` VALUES ('170909FRCAT15XGC', '红翼 875', '215000');
    INSERT INTO `demo_item` VALUES ('170909FRF2P18ARP', 'cat', '185000');
    INSERT INTO `demo_item` VALUES ('170909FRG6R75PZC', 'dog', '195000');
    INSERT INTO `demo_item` VALUES ('170909FRHBS3K680', '马丁靴', '150000');
    INSERT INTO `demo_item` VALUES ('170909FRPWA5HCPH', '天木兰 经典 船鞋', '65000');
    INSERT INTO `demo_item` VALUES ('170909FRS6SBHH00', '天木兰 踢不烂', '65000');
    INSERT INTO `demo_item` VALUES ('170909FRX22HKCDP', '其乐 袋鼠靴', '70000');
    
    -- ----------------------------
    -- Table structure for sys_permission
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_permission`;
    CREATE TABLE `sys_permission` (
      `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `name` varchar(128) NOT NULL COMMENT '资源名称',
      `type` int(2) NOT NULL COMMENT '资源类型:\r\n0:顶级根权限\r\n1:菜单,间接代表就是 isParent=true\r\n2:普通链接(按钮,link等)',
      `url` varchar(128) DEFAULT NULL COMMENT '访问url地址',
      `percode` varchar(128) DEFAULT NULL COMMENT '权限代码字符串',
      `parentid` int(11) DEFAULT NULL COMMENT '父结点id\r\n为0代表根节点',
      `parentids` varchar(128) DEFAULT NULL COMMENT '父结点id列表串',
      `sort` int(3) DEFAULT NULL COMMENT '排序号',
      `available` int(1) NOT NULL COMMENT '是否可用,1:可用,0不可用',
      `description` varchar(128) DEFAULT NULL COMMENT '当前资源描述',
      `create_time` datetime NOT NULL,
      `update_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `percode` (`percode`)
    ) ENGINE=InnoDB AUTO_INCREMENT=258 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of sys_permission
    -- ----------------------------
    INSERT INTO `sys_permission` VALUES ('237', '个人会员', '1', '/appuser/mng', 'appuser:mng', '216', null, null, '1', '会员管理 - 个人会员 菜单按钮', '2016-10-24 14:28:31', '2016-10-24 14:28:31');
    INSERT INTO `sys_permission` VALUES ('238', '查看', '2', '/appuser/getPersonal', 'appuser:getPersonal', '237', null, null, '1', '会员管理 - 个人会员 下属按钮', '2016-10-24 14:36:42', '2016-10-24 14:36:55');
    INSERT INTO `sys_permission` VALUES ('239', '审核', '2', '/appuser/toCheck', 'appuser:toCheck', '237', null, null, '1', '会员管理 - 个人会员 下属按钮', '2016-10-24 14:37:37', '2016-10-24 14:37:45');
    INSERT INTO `sys_permission` VALUES ('240', '提交审核', '2', '/appuser/check', 'appuser:check', '237', null, null, '1', '会员管理 - 个人会员 菜单按钮', '2016-10-24 14:39:10', '2016-10-24 14:39:10');
    INSERT INTO `sys_permission` VALUES ('241', '企业会员', '1', '/company/mng', 'company:mng', '216', null, null, '1', '会员管理 - 企业会员', '2016-10-24 14:41:52', '2016-10-24 14:42:11');
    INSERT INTO `sys_permission` VALUES ('242', '查看', '2', '/company/getCompany', 'company:getCompany', '241', null, null, '1', '会员管理 - 企业会员 下查看资源', '2016-10-24 14:43:38', '2016-10-24 14:43:43');
    INSERT INTO `sys_permission` VALUES ('243', '审核', '2', '/company/toCheck', 'company:toCheck', '241', null, null, '1', '会员管理 - 企业会员', '2016-10-24 14:44:23', '2016-10-24 14:44:23');
    INSERT INTO `sys_permission` VALUES ('244', '提交审核', '2', '/company/check', 'company:check', '241', null, null, '1', '会员管理 - 企业会员', '2016-10-24 14:44:52', '2016-10-24 14:44:59');
    INSERT INTO `sys_permission` VALUES ('245', '车辆管理', '1', '/cars/toCarsList', 'cars:toCarsList', '216', null, null, '1', '车辆管理菜单', '2016-10-26 13:51:20', '2016-10-26 13:51:20');
    INSERT INTO `sys_permission` VALUES ('246', '查看', '2', '/cars/queryCars', 'cars:queryCars', '245', null, null, '1', '车辆管理菜单 - 查看按钮', '2016-10-26 13:52:34', '2016-10-26 13:52:42');
    INSERT INTO `sys_permission` VALUES ('247', '审核', '2', '/cars/toCarsCheck', 'cars:toCarsCheck', '245', null, null, '1', '车辆管理菜单 - 审核按钮', '2016-10-26 13:53:19', '2016-10-26 13:53:19');
    INSERT INTO `sys_permission` VALUES ('248', '提交审核', '2', '/cars/carsCheck', 'cars:carsCheck', '245', null, null, '1', '车辆管理菜单 - 提交审核', '2016-10-26 13:54:08', '2016-10-26 13:54:08');
    INSERT INTO `sys_permission` VALUES ('249', '车源管理', '1', '/carsource/mng', 'carsource:mng', '216', null, null, '1', '货源/车源管理 - 车源管理', '2016-10-26 13:55:28', '2016-10-26 13:55:28');
    INSERT INTO `sys_permission` VALUES ('250', '货源管理', '1', '/cargosource/mng', 'cargosource:mng', '216', null, null, '1', '车源/货源管理菜单 - 货源管理', '2016-10-26 13:56:52', '2016-10-26 13:56:52');
    INSERT INTO `sys_permission` VALUES ('252', '搜索车源', '2', '/carsource/getAll', 'carsource:getAll', '249', null, null, '1', '货源/车源管理 - 车源管理 - 搜索', '2016-10-26 13:59:19', '2016-10-26 13:59:19');
    INSERT INTO `sys_permission` VALUES ('254', '新增车源', '2', '/carsource/add', 'carsource:add', '249', null, null, '1', '货源/车源管理 - 车源管理 - 新增车源', '2016-10-26 14:03:36', '2016-10-26 14:03:36');
    INSERT INTO `sys_permission` VALUES ('255', '车源详情', '2', '/carsource/detail', 'carsource:detail', '249', null, null, '1', '货源/车源管理 - 车源管理 - 车源详情', '2016-10-26 14:04:03', '2016-10-26 14:04:03');
    INSERT INTO `sys_permission` VALUES ('256', '删除车源', '2', '/carsource/del', 'carsource:del', '249', null, null, '1', '货源/车源管理 - 车源管理 - 删除车源', '2016-10-26 14:05:26', '2016-10-26 14:05:35');
    INSERT INTO `sys_permission` VALUES ('257', '保存新增的车源', '2', '/carsource/save', 'carsource:save', '249', null, null, '1', '货源/车源管理 - 车源管理 - 保存新增的车源', '2016-10-26 14:06:52', '2016-10-26 14:06:58');
    
    -- ----------------------------
    -- Table structure for sys_role
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_role`;
    CREATE TABLE `sys_role` (
      `id` int(20) NOT NULL AUTO_INCREMENT,
      `name` varchar(128) NOT NULL,
      `available` int(1) DEFAULT NULL COMMENT '是否可用,1:可用,0不可用',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of sys_role
    -- ----------------------------
    INSERT INTO `sys_role` VALUES ('1', '超级管理员', '1');
    INSERT INTO `sys_role` VALUES ('2', '总经理', '1');
    INSERT INTO `sys_role` VALUES ('3', '客服', '1');
    INSERT INTO `sys_role` VALUES ('4', '销售/市场专员', '1');
    INSERT INTO `sys_role` VALUES ('5', '产品团队', '1');
    INSERT INTO `sys_role` VALUES ('6', '技术团队', '1');
    
    -- ----------------------------
    -- Table structure for sys_role_permission
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_role_permission`;
    CREATE TABLE `sys_role_permission` (
      `id` int(20) NOT NULL AUTO_INCREMENT,
      `sys_role_id` int(20) NOT NULL COMMENT '角色id',
      `sys_permission_id` int(20) NOT NULL COMMENT '权限id',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of sys_role_permission
    -- ----------------------------
    INSERT INTO `sys_role_permission` VALUES ('1', '1', '237');
    INSERT INTO `sys_role_permission` VALUES ('2', '1', '238');
    INSERT INTO `sys_role_permission` VALUES ('3', '1', '239');
    INSERT INTO `sys_role_permission` VALUES ('4', '1', '240');
    INSERT INTO `sys_role_permission` VALUES ('5', '1', '241');
    INSERT INTO `sys_role_permission` VALUES ('6', '6', '250');
    INSERT INTO `sys_role_permission` VALUES ('7', '6', '251');
    INSERT INTO `sys_role_permission` VALUES ('8', '6', '252');
    INSERT INTO `sys_role_permission` VALUES ('9', '6', '253');
    INSERT INTO `sys_role_permission` VALUES ('10', '6', '254');
    INSERT INTO `sys_role_permission` VALUES ('11', '6', '255');
    
    -- ----------------------------
    -- Table structure for sys_user
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_user`;
    CREATE TABLE `sys_user` (
      `id` varchar(20) NOT NULL,
      `username` varchar(60) NOT NULL COMMENT '用户名,登录名',
      `password` varchar(64) NOT NULL COMMENT '密码',
      `nickname` varchar(60) NOT NULL COMMENT '昵称',
      `age` int(3) DEFAULT NULL COMMENT '年龄',
      `sex` int(1) DEFAULT NULL COMMENT '性别\r\n0:女\r\n1:男\r\n2:保密 ',
      `job` int(10) DEFAULT NULL COMMENT '职业类型:\r\n1:Java开发\r\n2:前端开发\r\n3:大数据开发\r\n4:ios开发\r\n5:Android开发\r\n6:Linux系统工程师\r\n7:PHP开发\r\n8:.net开发\r\n9:C/C++\r\n10:学生\r\n11:其它',
      `face_image` varchar(255) DEFAULT NULL COMMENT '头像地址',
      `province` varchar(12) DEFAULT NULL COMMENT '省',
      `city` varchar(12) DEFAULT NULL COMMENT '市',
      `district` varchar(12) DEFAULT NULL COMMENT '区',
      `address` varchar(128) DEFAULT NULL COMMENT '详细地址',
      `auth_salt` varchar(16) DEFAULT NULL COMMENT '用于权限的“盐”',
      `last_login_ip` varchar(20) DEFAULT NULL COMMENT '最后一次登录IP',
      `last_login_time` datetime DEFAULT NULL COMMENT '最后一次登录时间',
      `is_delete` int(1) NOT NULL,
      `regist_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `username` (`username`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统后台用户';
    
    -- ----------------------------
    -- Records of sys_user
    -- ----------------------------
    INSERT INTO `sys_user` VALUES ('1001', 'test', '72e1242b855fb038212135e0ad348842', 'lee123', null, null, null, null, null, null, null, null, 'test', null, null, '0', '2017-11-06 10:20:36');
    INSERT INTO `sys_user` VALUES ('1709067GM45GAF5P', 'jack', 'afee05e30d029ac3b61a2dc6c08d7b27', 'jack', '22', '0', '3', null, '上海市', '上海市市辖区', '静安区', '上海老薛', 'abcd', null, null, '0', '2017-09-06 10:35:28');
    INSERT INTO `sys_user` VALUES ('170908G65M59XWH0', 'test003', 'afee05e30d029ac3b61a2dc6c08d7b27', 'test003', '20', '0', '3', null, '上海市', '上海市市辖区', '黄浦区', '老薛家', 'tx5D', null, null, '1', '2017-09-08 21:19:40');
    INSERT INTO `sys_user` VALUES ('170918GDXW2DNP4H', 'test001', 'afee05e30d029ac3b61a2dc6c08d7b27', 'test0016', '18', '1', '9', null, '湖北省', '鄂州市', '华容区', '123', 'W5k4', null, null, '0', '2017-09-18 21:42:51');
    INSERT INTO `sys_user` VALUES ('171020FWN55RS5AW', 'test1001', '75a5298456daeb532320fdd4a9eacec0', 'test1001', null, null, null, null, null, null, null, null, '3883', null, null, '0', '2017-10-20 20:51:05');
    INSERT INTO `sys_user` VALUES ('1803269654BP2428', 'imoocMon Mar 26 12:55:11 CST 2018', 'abc123', 'imoocMon Mar 26 12:55:11 CST 2018', null, null, null, null, null, null, null, null, null, null, null, '0', '2018-03-26 12:55:11');
    
    -- ----------------------------
    -- Table structure for sys_user_role
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_user_role`;
    CREATE TABLE `sys_user_role` (
      `id` int(20) NOT NULL AUTO_INCREMENT,
      `sys_user_id` varchar(20) NOT NULL,
      `sys_role_id` int(20) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of sys_user_role
    -- ----------------------------
    INSERT INTO `sys_user_role` VALUES ('21', '1709067GM45GAF5P', '1');
    
    -- ----------------------------
    -- Table structure for t_test
    -- ----------------------------
    DROP TABLE IF EXISTS `t_test`;
    CREATE TABLE `t_test` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
    
    -- ----------------------------
    -- Records of t_test
    -- ----------------------------
    INSERT INTO `t_test` VALUES ('1', '111');
    INSERT INTO `t_test` VALUES ('2', '222');
    INSERT INTO `t_test` VALUES ('3', '333');
    
    
    根据MyBatis-Spring-Boot说明在pom.xml中引入依赖包
    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.1</version>
    </dependency>
    <!--mapper-->
    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>1.2.4</version>
    </dependency>
    <!--pagehelper-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.3</version>
    </dependency>
    
    在pom.xml中引入阿里的druid及mysql-connector-java
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.41</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.3.2</version>
                <scope>compile</scope>
                <optional>true</optional>
            </dependency>
            
            <!-- 引入 redis 依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    在application.properties配置(生成环境可以不需要,主要时热部署功能)
    #https://github.com/abel533/MyBatis-Spring-Boot 为mybatis设置,生成环境可以删除
    restart.include.mapper=/mapper-[\\w-\\.]+jar
    restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
    
    集成 MyBatis Generator
    #通过 Maven 插件集成的,所以运行插件使用下面的命令:
    
    > mvn mybatis-generator:generate
    
    #Mybatis Geneator 详解:
    
    > http://blog.csdn.net/isea533/article/details/42102297
    
    
    application.properties 配置数据源
    #####################################################
    #
    #配置数据源相关,使用阿里巴巴的druid数据源
    #
    #####################################################
    
    #spring.datasource.url=jdbc:mysql://localhost:3306/leecx
    spring.datasource.url=jdbc:mysql://39.97.171.***:3306/leecx
    spring.datasource.username=root
    #mysql数据root用户密码
    spring.datasource.password=root的密码
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.initial-size=1
    spring.datasource.druid.min-idle=1
    spring.datasource.druid.max-active=20
    spring.datasource.druid.test-on-borrow=true
    spring.datasource.druid.stat-view-servlet.allow=true
    
    application.properties 配置--mybatis
    #####################################################
    #
    #mybatis配置
    #
    #####################################################
    #mybatis
    #mybatis.type-aliases-package=tk.mybatis.springboot.model   这是mybatis生成model或pojo路径
    mybatis.type-aliases-package=com.younghare.pojo
    #在classpath目录下建立一个mapper文件夹,这个文件夹下将会生成一些xml文件
    mybatis.mapper-locations=classpath:mapper/*.xml
    
    #通用mapper 的配置
    #mappers 多个接口时逗号隔开
    #mapper.mappers=tk.mybatis.springboot.util.MyMapper
    
    mapper.mappers=com.younghare.util.MyMapper
    mapper.not-empty=false
    mapper.identity=MYSQL
    
    #pagehelper
    pagehelper.helperDialect=mysql
    pagehelper.reasonable=true
    pagehelper.supportMethodsArguments=true
    pagehelper.params=count=countSql
    
    

    创建MyMapper.java类,路径与application.properties中配置一致

    /**
     * 继承自己的MyMapper
     */
    public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
        //TODO
        //FIXME 特别注意,该接口不能被扫描到,否则会出错
    }
    
    
    MyMapper.java存放路径
    MyBatis工具 http://www.mybatis.tk
    下面添加generatorConfig.xml 和GeneratorDisplay.java文件逆向生成Dao、Model、Mapping相关文件

    使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件(转)
    mybatis-generator自动生成代码插件使用详解

    自动生成pojo、 mapper对应的java映射类 直接运行GeneratorDisplay中的main方法
    !Mybatis数据库连接报错](https://img.haomeiwen.com/i5438896/0c3493c0a2162095.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) XMLParserException: XML Parser Error on line 14: 元素类型为 "plugin" 的内容必须匹配 "(property)

    到generatorConfig.xml的对应行中看看哪里出错了

    配置generatorConfig.xml(与官方一致)
    URI is not registered
    解决办法
    https://www.cnblogs.com/ttflove/p/6341469.html 添加URI到Schemas and DTDs
    添加generatorConfig.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
            <property name="beginningDelimiter" value="`"/>
            <property name="endingDelimiter" value="`"/>
    
            <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
                <!--注意MyMapper的路径-->
                <property name="mappers" value="com.younghare.springBoothelloworld.utils.MyMapper"/>tian
            </plugin>
    
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://39.97.171.***:3306/leecx"
                            userId="root"
                            password="root对应的密码">
            </jdbcConnection>
    
            <!-- 对于生成的pojo所在包 -->
            <javaModelGenerator targetPackage="com.younghare.pojo" targetProject="src/main/java"/>
    
            <!-- 对于生成的mapper所在目录 -->
            <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
    
            <!-- 配置mapper对应的java映射 类-->
            <javaClientGenerator targetPackage="com.younghare.mapper" targetProject="src/main/java"
                                 type="XMLMAPPER"/>
    
    
            <!--需要逆向生成的mysql数据库名字-->
            <table tableName="sys_user"></table>
             
        </context>
    </generatorConfiguration>
    
    添加GeneratorDisplay.java 文件
    package com.younghare.springBoothelloworld.utils;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    public class GeneratorDisplay {
    
        public void generator() throws Exception{
    
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            //指定 逆向工程配置文件
            File configFile = new File("generatorConfig.xml");   //配置文件在根目录下
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = cp.parseConfiguration(configFile);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                    callback, warnings);
            myBatisGenerator.generate(null);
    
        } 
        
        public static void main(String[] args) throws Exception {
            try {
                GeneratorDisplay generatorSqlmap = new GeneratorDisplay();
                generatorSqlmap.generator();
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    }
    
    
    ConfigurationParser类找不到 ConfigurationParser类找不到

    ConfigurationParser类找不到的解决办法,在 pom.xml文件中添加依赖

    <!--添加mybatis的generator-->
            <dependency>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-core</artifactId>
                <version>1.3.2</version>
                <scope>compile</scope>
                <optional>true</optional>
            </dependency>
    

    相关文章

      网友评论

        本文标题:Springboot5 开发常用技术整合--笔记

        本文链接:https://www.haomeiwen.com/subject/yzpybqtx.html