SpringBoot总结

目录

1.介绍

2.快递搭建

3.运行原理

3.1.启动器 spring-boot-starter

3.2.启动类

3.3.spring.factories

3.4.启动类的运行

4.配置

4.1.yaml介绍

4.2.yaml注入配置文件

4.3.加载指定的配置文件

4.4.对比@Value

4.6.多环境切换

4.7.自动装配的原理

5.Web开发

5.1.静态资源访问

5.2.首页

5.3.Thymeleaf模板引擎

5.4.Thymeleaf 语法学习

5.5.登录功能

5.6.Demo-员工管理

6.SpringDate

6.1.整合JDBC

6.2.整合Mybatis**

6.3.tk mybatis


1.介绍

spring boot 是spring快速开发脚手架,通过约定大于配置,优化了混乱的依赖管理,和复杂的配置,让我们用java -jar方式,运行启动java web项目

约定大于配置:比如我们引入了springmvc的构件,它就判断你要进行web开发,我们就不需要在xml文件中配置相关的东西了,它自动帮我们配置。

spring的缺点

复杂的配置,项目各种配置是开发时的损耗, 写配置挤占了写应用程序逻辑的时间。

混乱的依赖管理。项目的依赖管理非常的繁琐。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这是一个棘手的问题。并且,一旦选错了依赖的版本,随之而来的就是各种的不兼容的bug。

springboot可以解决上面两个问题

springboot特点

快速开发spring应用的框架

内嵌tomcat和jetty容器,不需要单独安装容器,jar包直接发布一个web应用

简化maven配置,parent这种方式,一站式引入需要的各种依赖

基于注解的零配置思想

和各种流行框架,spring web mvc,mybatis,spring cloud无缝整合

2.快递搭建

导入web依赖

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

编写controller(一定要和启动类在同级目录下,否则识别不到)

@Controller
@RequestMapping("/h")
public class HelloController {
    @GetMapping("/hello")
    @ResponseBody//返回字符串
    public String hello() {
        return "Hello-Spring-Boot";
    }
}

修改端口(application.properties)

运行SpringbootDemoApplication,访问就行

3.运行原理

它主要是依赖一个父项目,主要是管理项目的资源过滤及插件,SpringBoot的版本控制中心

我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了

3.1.启动器 spring-boot-starter

springboot-boot-starter-xxx:就是spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可

3.2.启动类

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

进入这个注解:可以看到上面还有很多其他注解

@ComponentScan

自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@SpringBootConfiguration

SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

继续进去这个注解查看

这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用

@EnableAutoConfiguration:开启自动配置功能

以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

继续点入

@AutoConfigurationPackage:自动配置包

@import :Spring底层注解@import , 给容器中导入一个组件

Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件

AutoConfigurationImportSelector :自动配置导入选择器

3.3.spring.factories

自动配置的核心文件

自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

不是所有的自动配置类都会生效,要判断条件是否成立,只要导入对应的start,就有对应的启动器了,自动装配就会生效

结论:

  1. SpringBoot在启动的时候从类路径下的spring.factories中获取EnableAutoConfiguration指定的值

  2. 将这些值作为自动配置类导入容器 ,自动配置类就生效 ,帮我们进行自动配置工作;

  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;

  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

3.4.启动类的运行

一部分是SpringApplication的实例化,二是run方法的执行

SpringApplication这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

run方法流程分析

  • 初始化 SpringApplication 实例:决定web应用类型、加载初始化器和监听器、推断 main 方法的定义类。
  • 通过 SpringFactoriesLoader 加载的 SpringApplicationRunListener,调用它们的 started 方法。
  • 创建并配置当前 Spring Boot 应用将要使用的 Environment,如 applocation.properties 文件和外部配置。
  • 根据 Web 服务类型创建不同的 Spring 应用上下文,并将之前准备好的 Environment 设置给 Spring 应用上下文 ApplicationContext 使用。
  • 遍历初始化器,对 ApplicationContext 进行初始化操作。
  • 加载所有资源,如 Configuration Class、类名、包名以及 Spring XML 配置资源路径,将所有 BeanDefinition 加载至 ApplicationContext。
  • 初始化上下文 refresh(),进行自动装配,初始化 Ioc 容器等操作。
  • 寻找当前 ApplicationContext 中是否注册有 CommandLineRunner 或者 ApplicationRunner,如果有,则遍历执行它们。

4.配置

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

  • application.properties  语法结构 :key=value

  • application.yml             语法结构 :key:空格 value

配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;

4.1 yaml介绍

以数据作为中心,而不是以标记语言为重点

以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,对比下yaml和xml

xml:

<server>
    <port>8081<port>
</server>

yaml:

server:
  prot: 8080

yaml基础语法

1、空格不能省略,对空格十分严格

2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的

3、属性和值的大小写都是十分敏感的

4.2 yaml注入配置文件

首先添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

以前使用@Value赋值很麻烦,现在可以使用yaml赋值

使用yaml赋值

在实体类上使用@ConfigurationProperties(prefix = "student")

将配置文件中配置的每一个属性的值,映射到这个组件中,​​​告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定

测试

4.3 加载指定的配置文件

@PropertySource :加载指定的配置文件;@PropertySource(value = "classpath:person.properties")

@configurationProperties:默认从全局配置文件中获取值;

@Bean:给容器中添加组件(取代spring的beans.xml)

 运行测试类

4.4 对比@Value

1、@ConfigurationProperties只需要写一次即可,@Value则需要每个字段都添加

2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的,- 后面跟着的字母默认是大写的。这就是松散绑定。

3、JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性

4、复杂类型封装,yml中可以封装对象,使用value就不支持

配置yml和配置properties都可以获取到值 , 强烈推荐 yml

如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

4.5 JSR303数据校验

可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理

@NotNull(message="名字不能为空")

private String userName;

@Max(value=120,message="年龄最大不能查过120")

private int age;

@Email(message="邮箱格式错误")

private String email;

空检查

@Null       验证对象是否为null

@NotNull    验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty   检查约束元素是否为NULL或者是EMPTY.

Booelan检查

@AssertTrue     验证 Boolean 对象是否为 true

@AssertFalse    验证 Boolean 对象是否为 false

长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内

@Length(min=, max=) string is between min and max included.

日期检查

@Past       验证 Date 和 Calendar 对象是否在当前时间之前

@Future     验证 Date 和 Calendar 对象是否在当前时间之后

@Pattern    验证 String 对象是否符合正则表达式的规则

4.6.多环境切换

配置文件加载位置

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:

优先级1:项目路径下的config文件夹配置文件优先级2:项目路径下配置文件优先级3:资源路径下的config文件夹配置文件优先级4:资源路径下配置文件

多配置文件

profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本

例如:

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件

我们需要通过一个配置来选择需要激活的环境

##比如在配置文件中指定使用dev环境
spring.profiles.active=dev

yaml的多文档块

server:
  port: 8081
#选择要激活那个环境块
spring:
  profiles:
    active: prod
 
---
server:
  port: 8083
spring:
  profiles: dev #配置环境的名称
 
---
server:
  port: 8084
spring:
  profiles: prod  #配置环境的名称

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的

4.7 配置文件加载位置及顺序

        spring boot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

– file:./config/

– file:./

– classpath:/config/

– classpath:/

– 以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。

– 我们也可以通过配置spring.config.location来改变默认配置

4.8 自动装配的原理

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxAutoConfigurartion:自动配置类;给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

5.Web开发

5.1.静态资源访问

以下四个目录存放的静态资源可以被我们识别:

"classpath:/META-INF/resources/"

"classpath:/resources/"

"classpath:/static/"

"classpath:/public/"

我们可以在resources根目录下新建对应的文件夹,都可以存放我们的静态文件

优先级:resources > static(默认) > public

我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties中配置

spring.resources.static-locations=classpath:/vv/

旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了

5.2.首页

欢迎页,静态资源文件夹下的所有 index.html 页面;被 /** 映射。

比如我访问  http://localhost:8080/ ,就会找静态资源文件夹下的 index.html

新建一个 index.html ,放到任意一个静态资源目录;然后访问测试  http://localhost:8080/

5.3.Thymeleaf模板引擎

前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

SpringBoot现在默认是不支持jsp

模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的

添加依赖

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

我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。

使用thymeleaf什么都不需要配置,只需要将他放在指定的文件夹下即可,不能直接访问这些资源,需要映射

注意的是用@controller注解不要用@restController,前者是渲染页面用的,后者是返回数据用的

@Controller
public class TestController {
    @RequestMapping("/t")
    public String test(ModelMap map) {
        map.addAttribute("msg","HelloWorld");
        return "test";
    }
}
<!DOCTYPE html >
<html lang="en" xmlns:th="http://www.thymeleaf.org"><!--添加命名空间-->
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--th:text就是将div中的内容设置为它指定的值-->
    <div th:text="${msg}"></div>
</body>
</html>

访问localhost:8080/t,就能访问到templates下的test.html了

5.4.Thymeleaf 语法学习

表达式分为三类

1. 变量表达式

2. 选择或星号表达式

3. URL表达式

变量表达式

Spring中用来获取model attribute的数据,它们将以HTML标签的一个属性来表示:

<!--没有后台数据的时候,默认显示你好 thymleaf-->
<span th:text="${text}">你好 thymleaf</span>

星号表达式

选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行

被指定的objectth:object属性定义

<tr th:each="user : ${users}" th:object="${user}">
 <td th:text="${user.id}"></td>
 <td th:text="*{name}"></td>
 <td th:text="*{userName}"></td>
 ....

URL表达式

URL表达式指的是把一个有用的上下文或会话信息添加到URL,这个过程经常被叫做URL重写

<form th:action="@{/createOrder}"> 
<a href="main.html" th:href="@{/main}">
<a th:href="@{/delete(id=${user.id}, userName=*{userName})}">删除</a>

文本替换的方式
<a th:href="|/update/${user.id}|">修改</a>
字符串拼接方式
<a th:href="'/approve/' + ${user.id}">审核</a>

表达式常见用法

字面(Literals

文本文字(Text literals: 'one text', 'Another one!',…

数字文本(Number literals: 0, 34, 3.0, 12.3,…

布尔文本(Boolean literals: true, false

空(Null literal: null

文字标记(Literal tokens: one, sometext, main,…

文本操作(Text operations

字符串连接(String concatenation): +

文本替换(Literal substitutions: |The name is ${name}|

算术运算(Arithmetic operations

二元运算符(Binary operators: +, -, *, /, %

减号(单目运算符)Minus sign (unary operator): -

布尔操作(Boolean operations

二元运算符(Binary operators: and, or

布尔否定(一元运算符)Boolean negation (unary operator): !, not

比较和等价(Comparisons and equality)

比较(Comparators: >, <, >=, <= (gt, lt, ge, le)

等值运算符(Equality operators: ==, != (eq, ne)

条件运算符(Conditional operators

If-then: (if) ? (then)

If-then-else: (if) ? (then) : (else)

Default: (value) ?: (defaultvalue) 

常用th标签

1. 赋值、字符串拼接

<a th:href="|/update/${user.id}|">修改</a> 
<a th:href="'/approve/' + ${user.id}">审核</a>

2. 条件判断 If/Unless

 <a> 标签只有在 th:if 中条件成立时才显示,th:unless和th:if相反只有表达式中的条件不成立,才会显示其内容

也可以使用 (if) ? (then) : (else) 这种语法来判断显示的内容

<a th:if="${users.size() > 0}">查询结果存在</a><br> 
<a th:if="${users.size() <= 0}">查询结果不存在</a><br> 
<a th:unless="${session.user != null}" href="#">登录</a><br>

3. for 循环

status称作状态变量,属性有:

index:当前迭代对象的index(从0开始计算)

count: 当前迭代对象的index(1开始计算)

size:被迭代对象的大小

current:当前迭代变量

even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)

fifirst:布尔值,当前循环是否是第一个

last:布尔值,当前循环是否是最后一个

内嵌变量

dates java.util.Date 的功能方法类。

calendars : 类似#dates,面向java.util.Calendar

numbers : 格式化数字的功能方法类

strings : 字符串对象的功能类,contains,startWiths,prepending/appending等等。

objects: objects的功能类操作。

bools: 对布尔值求值的功能方法。

arrays对数组的功能类方法。

lists: lists功能类方法

maps:对maps功能类方法

<h6 th:text="${#dates.createNow()}">获取当前日期</h6> 
<h6 th:text="${#strings.substring(text, 6, 9)}">截取字符串</h6> 
<h6 th:text="${#strings.length(text)}">获得长度</h6> 
<h6 th:text="${#strings.randomAlphanumeric(6)}">随机字符串</h6> 
<h6 th:text="${#strings.equals(text, 'hello text....')}"></h6>
Thymeleaf 布局

/resources/templates/目录下创建footer.html,内容如下

<html xmlns:th="http://www.thymeleaf.org">
<body>
    <footer th:fragment="copy(title)">
     <span th:text="${title}"></span>
    </footer>
</body>
</html>

在页面任何地方引入:  

    <h5>thymeleaf布局</h5>
    <div th:insert="~{footer :: copy('vv')}"></div>
    <div th:replace="~{footer :: copy('77')}"></div>
    <div th:include="~{footer :: copy('22')}"></div>

th:insert :保留自己的主标签,保留th:fragment的主标签。

th:replace :不要自己的主标签,保留th:fragment的主标签。

th:include :保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)

5.5.登录功能

登录页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login" method="post">
        用户名<input type="text" name="username"><br>
        密  码<input type="password" name="password"><br>
        <input type="submit" value="登录">
        <!--如果msg为空,不显示提示-->
        <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
    </form>
</body>
</html>

controller

@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(String username, String password, ModelMap model, HttpSession session) {
        if("admin".equals(username) && "123".equals(password)) {
            session.setAttribute("loginuUser",username);
            return "redirect:dashboard";//重定向后就能使用thymeleaf模板了
        }else {
            model.addAttribute("msg","用户名或者密码错误");
            return "index";
        }
    }
}

拦截器

@Configuration
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录成功后,有用户的session
        HttpSession session = request.getSession();
        Object loginuUser = session.getAttribute("loginuUser");
        if(loginuUser==null) {//没有登录
            request.setAttribute("msg","没有权限,请先登录");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }
        return true;
    }
}

配置路由和添加拦截器

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

    //添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**").excludePathPatterns("/index.html","/","/login");
    }
}

5.6.Demo-员工管理

    @RequestMapping("/findAll")
    public String findAll(Model model) {
        EmployeeDao dao = new EmployeeDao();
        Collection<Employee> empss = dao.getAll();
        model.addAttribute("emps",empss);
        return "dashboard";
    }

dashboard.html

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>dashboard</h1>
<h3><a th:href="@{/toAdd}">添加</a> </h3>
<table border="1">
    <tr>
        <th>id</th>
        <th>lastName</th>
        <th>email</th>
        <th>gender</th>
        <th>department</th>
        <th>date</th>
        <th>操作</th>
    </tr>

    <tr th:each="emp:${emps}">
        <td th:text="${emp.getId()}"></td>
        <td th:text="${emp.getLastName()}"></th>
        <td th:text="${emp.getEmail()}"></td>
        <td th:text="${emp.getGender()==0?'女':'男'}"></td>
        <td th:text="${emp.getDepartment.getdName()}"></td>
        <td th:text="${#dates.format(emp.getDate(),'yyyy-MM-dd')}"></td>
        <td>
            <a th:href="'/delete?id=' + ${emp.getId()}">删除</a>
        </td>
    </tr>
</table>
</body>
</html>

toAdd 

    @RequestMapping("/toAdd")
    public String add(Model model) {
        //查出所有部门
        DepartmentDao dao = new DepartmentDao();
        Collection<Department> departments = dao.getDepartments();
        model.addAttribute("departments",departments);
        return "addOne";
    }

addOne

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/addEmp}" method="get">
    姓名:<input type="text" name="lastName"><br>
    邮箱:<input type="text" name="email"><br>
    <input type="radio" name="gender" value="1">男
    <input type="radio" name="gender" value="0">女<br>
    部门:<select name="department.id"><!--department是个类-->
            <option th:each="department:${departments}"
                    th:text="${department.getdName()}"
                    th:value="${department.getId()}">
            </option>
    </select><br>
    生日:<input type="text" name="date"><br>
    <!--若想输入yyyy-MM-dd格式,需要在application.yaml设置spring.mvc.date-format=yyyy-MM-dd  -->
    <input type="submit" value="提交">
</form>
</body>
</html>
    @RequestMapping("/addEmp")
    public String addEmp(Employee employee) {
        EmployeeDao dao = new EmployeeDao();
        dao.add(employee);
        return "redirect:findAll";
    }

    @RequestMapping("/delete")
    public String delete(Integer id) {
        EmployeeDao dao = new EmployeeDao();
        dao.delete(id);
        return "redirect:findAll";
    }

6.SpringDate

和数据库打交道

6.1.整合JDBC

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

yml配置文件

spring:
  datasource:
    username: root
    password: 
    #serverTimezone=UTC解决时区的报错
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver

配置连接池

其实,在刚才引入jdbc启动器的时候,SpringBoot已经自动帮我们引入了一个连接池: HikariCP,应该是目前速度最快的连接池了

测试

6.2.整合Mybatis**

整合包,不是springboot官方的

<!--mybatis -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>
<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.28</version>
    <scope>runtime</scope>
</dependency>

yml

spring:
  datasource:
    username: root
    password:
    url: jdbc:mysql://localhost:3306/数据库?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true

mapper的加载接口代理对象

dao

xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.vv.dao.UserDao">
    <select id="getAll" resultType="com.vv.entity.User">
        select * from tb_user
    </select>

    <delete id="deleteById" parameterType="Long">
        delete from tb_user where id = #{id}
    </delete>
    <insert id="add" parameterType="com.vv.entity.User">
        insert into tb_user (user_name,name,age,sex,birthday) values (#{userName},#{name},#{age},#{sex},#{birthday})
    </insert>
    <select id="selectById" parameterType="Long" resultType="com.vv.entity.User">
        select * from tb_user where id = #{id}
    </select>
    <update id="update" parameterType="com.vv.entity.User">
        update tb_user set user_name = #{userName}, name = #{name}, age = #{age}, sex = #{sex}, birthday = #{birthday} where id = #{id}
    </update>
</mapper>

 controller

@Controller
public class TestController {
    @Autowired
    UserDao dao;


    @RequestMapping("/getAll")
    public String test(ModelMap map){
        map.addAttribute("users",dao.getAll());
        return "show";
    }

    @RequestMapping("/delete")
    public String delete(Long id){
        dao.deleteById(id);
        return "redirect:getAll";
    }

    @RequestMapping("/toAdd")
    public String toAdd(){
        return "addOne";//跳转到addOne.xml
    }

    @RequestMapping("/add")
    public String add(User user){
        dao.add(user);
        return "redirect:getAll";
    }

    @RequestMapping("/toUpdate")
    public String toUpdate(Long id,ModelMap map){
        User user = dao.selectById(id);
        map.addAttribute("user",user);
        return "update";
    }

    @RequestMapping("/update")
    public String update(User user){
        dao.update(user);
        return "redirect:getAll";
    }
}

6.3.tk mybatis

使用Mybatis时,最大的问题是,要写大量的重复SQL语句在xml文件中,除了特殊的业务逻辑SQL语句之外,还有大量结构类似的增删改查SQL。而且,当数据库表结构改动时,对应的所有SQL以及实体类都需要更改。这大量增加了程序员的负担。避免重复书写CRUD映射的框架有两个:

通用mybatistk mybatis

mybatis plus,通能更加强大

添加依赖(可以不用引入mybatis)

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.0.2</version>
</dependency>

tk mybatis实体类使用 jpa 注解

1. 默认:表名=类名,字段名=属性名

2. 表名可以使用 @Table(name = "tableName") 进行指定

3. @Column(name = "fieldName") 指定

4. 使用 @Transient 注解表示跟字段不进行映射

@Table(name = "bills")
public class Bills {
    这两个不能省略,表示主键自增
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String title;
    private Date billtime;
    private Integer typeid;
    private Double price;
    private String explains;
    ...
}

接口

@Mapper//在启动类下用@MapperScan扫描这个类,要选择tk mybatis提供的@MapperScan!
@Repository
public interface BillsMapper extends tk.mybatis.mapper.common.Mapper<Bills>{
    List<Bills> getAll();
}

一旦继承了Mapper,继承的Mapper就拥有了Mapper所有的通用方法(可以不用自己另外写):

Select

方法: List<T> select(T record); 说明:根据实体中的属性值进行查询,查询条件使用等号

方法: T selectByPrimaryKey(Object key); 说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号

方法: List<T> selectAll(); 说明:查询全部结果,select(null)方法能达到同样的效果

方法: T selectOne(T record); 说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号

方法: int selectCount(T record); 说明:根据实体中的属性查询总数,查询条件使用等号

Insert

方法: int insert(T record); 说明:保存一个实体,null的属性也会保存,不会使用数据库默认值

方法: int insertSelective(T record); 说明:保存一个实体,null的属性不会保存,会使用数据库默认值

Update

方法: int updateByPrimaryKey(T record); 说明:根据主键更新实体全部字段,null值会被更新

方法: int updateByPrimaryKeySelective(T record); 说明:根据主键更新属性不为null的值

Delete

方法: int delete(T record); 说明:根据实体属性作为条件进行删除,查询条件使用等号

方法: int deleteByPrimaryKey(Object key); 说明:根据主键字段进行删除,方法参数必须包含完整的主键属性

Example 

方法: List<T> selectByExample(Object example); 说明:根据Example条件进行查询 重点:这个查询支持通过 Example 类指定查询列,通过 selectProperties 方法指定查询列

方法: int selectCountByExample(Object example); 说明:根据Example条件进行查询总数

方法: int updateByExample(@Param("record") T record, @Param("example") Object example); 说明:根据Example条件更新实体 record 包含的全部属性,null值会被更新

方法: int updateByExampleSelective(@Param("record") T record, @Param("example") Object example); 说明:根据Example条件更新实体 record 包含的不是null的属性值

方法: int deleteByExample(Object example); 说明:根据Example条件删除数据

复制的方法,我们也可以自定映射文件写SQL语句

测试

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    BillsMapper mapper;

    @Test
    void selectAll() {
        mapper.selectAll().forEach(bills -> {
            System.out.println(bills);
        });
    }

    @Test
    public void Example() {
        Example example = new Example(Bills.class);
        //查询所有以快递费开头的标题数据
        example.createCriteria().andLike("title","快递费%");
        mapper.selectByExample(example).forEach(bills -> {
            System.out.println(bills);
        });
    }
    
    ...
}

使用pagehelper

添加依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.13</version>
</dependency>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值