SpringBoot学习笔记2

一. SpringBoot自动配置原理

自己也写不出什么新的东西,参考:

http://t.csdnimg.cn/2NDhPhttp://t.csdnimg.cn/2NDhP步骤:

1.1:进入主程序类的注解 @SpringBootApplication

@SpringBootApplication 为一个复合注解,里面有两个重要注解:
(1)@SpringBootConfiguration :该注解上有一个 @Configuration注解,表示这个spring boot启动类是一个配置类,最终要被注入到spring容器中
(2)@EnableAutoConfiguration:表示开启自动配置,它也是一个复合注解

进入 @EnableAutoConfiguration 这个注解,有一个重要注解:

(3)@Import({AutoConfigurationImportSelector.class}):这个注解其中含有的参数:AutoConfigurationImportSelector类中有一个getCandidateConfigurations()方法,该方法通过SpringFactoriesLoader.loadFactoryNames()方法查找位于META-INF/spring.factories文件中的所有自动配置类,并加载这些类

META-INF/spring.factories 如图示位置:其中含有 137个配置类 

57c66bde77974e219d7dce7ec33bb778.png

spring boot在整个的启动过程中,其实就是在类路径的META-INF/spring.factories 文件中找到EnableAutoConfiguration对应的所有的自动配置类,然后将所有自动配置类加载到spring容器中。

注意,所有的自动配置类都有@Conditional或者子注解用于实现条件配置。以下是部分注解用于告知自动配置类应在什么条件下开始配置。

@ConditionalOnBean:当容器里存在指定bean的条件下。

@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。

@ConditionalOnClass:当类路径下有指定类的条件下。

@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。

@ConditionalOnProperty:指定的属性是否有指定的值,比如
@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true(设置默认情况)。

SpringBoot自动实现了字符集编码过滤配置服务,依靠的就是springBoot自动配置,使用的是UTF-8. 

二. 自定义场景启动器

首先先来解释下几个conditional的子注解

1.1 

@ConditionalOnProperty(prefix = "my.hello.encoding" ,value = "enabled" , matchIfMissing = true)   //条件注解:根据属性值来判断某些类或者实例能不能被创建:preifx为前缀。value为属性key,第三个懂得都懂(默认值)

Spring Boot 在启动时会检查 @ConditionalOnProperty 注解指定的属性。当属性存在并满足给定条件时,Spring 容器会加载相应的 Bean。否则,这些 Bean 将不会被创建。这种方式可以有效地控制应用程序的功能开关,适应不同的配置需求。

1.2

@ConditionalOnMissingBean(HelloService.class)

@ConditionalOnMissingBean(HelloService.class) 的作用是:当容器中没有 HelloService 类型的 Bean 时,才会创建该注解所标注的 Bean其中当 @ConditionalOnMissingBean 注解没有指定具体的缺失类型时,Spring 会自动根据标注该注解的类或方法的返回类型 来判断是否应该创建相应的 Bean。实现了单例?

2.1 开始书写自定义场景启动器

2.1.1创建一个包config用来创建配置访问对象:定义了访问对象访问的前缀

@Data
@ConfigurationProperties(prefix = "my.hello")
public class HelloProperties {
    private  String prefix = "default-prefix ";
    private  String suffix = "default-suffix ";
}

2.1.2 创建一个服务类,这个类用于获取到访问对象并且调用了访问对象内部的属性

public class HelloService {
    private String name;
    public HelloService(){

    }
    public HelloService(String name){
        this.name = name;
    }

    @Autowired
    private HelloProperties helloProperties;

    public String sayHello(String userName){
       return this.name + " : " + helloProperties.getPrefix() + " : " + userName + " : "+ helloProperties.getSuffix();
   }
}

2.1.3但是此时我们发现必须要将这个配置访问对象以及服务同时注册到springboot容器中。

首先服务类想要获取到配置访问对象的自动注入,我们要注册配置访问对象;这个服务类被打包后要被访问到以实现服务方法的调用也得注册到springboot容器中。

再次创建一个自动配置类:这个自动配置类用于在springinitializr配置时自动调用,将使用访问对象的服务实例注册到spring容器中

@Configuration             //表明此类为一个配置类
@EnableConfigurationProperties(HelloProperties.class) //将配置对象注册到spring容器中
@ConditionalOnProperty(prefix = "my.hello.encoding" ,value = "enabled" , matchIfMissing = true)   //条件注解:根据属性值来判断某些类或者实例能不能被创建:preifx为前缀。value为属性key,第三个懂得都懂(默认值)
public class HelloAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(HelloService.class)           //如果不标注则是自动匹配当前的类或者方法返回类型
    public HelloService helloService(){
        return new HelloService("【自定义场景启动器产生的】");
    }

}

好好,这个简易的服务写完了,但是此时springboot容器并不会自动配置这个自定义场景启动器,因为原来的springboot自动配置再经过一系列的调用后会到spring.factories文件中读取,因此我们模仿以下创建一个resources文件夹,按照META-INF/spring.factories路径创建文件并且书写

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.lkz.demo.config.HelloAutoConfiguration  //就是你的自动配置类

ok完成后打包,打包注意事项:

删除主程序启动类,然后去pom文件中删除对应配置

<mainClass>com.lkz.demo.CCustomStarterApplication</mainClass>

ok,在下一个项目中试验一下这个场景启动器

ad22d25e1708487089e7d68eef47a7b5.png

三. springBoot配置文件

1.1 回顾spring和springboot的几种访问配置文件属性的方法:

spring中的方式:

                                                     加载属性文件的两种方式:

第一种,使用注解(在配置类中):@PropertySource(“/classpath:jdbc.properties”)

第二种,xml配置:<contextpropertyPlaceHolder location="classpath:jdbc.properties">

其中第一种的注解应用场景为:如果这个配置文件不是springboot默认读取的application.properies文件,则需要书写

                                                      读取配置文件属性的两种方式:

在属性上方书写注解: @Value(“${配置文件属性名称}”)

通过Environment属性接收:

@Resource

private Environment environment

environment.getProperties("配置文件属性名称")

springboot则是使用创建访问对象以及配置访问服务和注册,就是自定义场景启动器的前部分

1.2 策略:使用yaml文件实现配置:

yaml意为:Yet Another Markup language 

基本语法规则:大小写区分 ;使用缩进冒号表示层级关系 ;缩进必须空格键 ;#表示注释

                         同一层级下的属性需要保持相同的缩进,且冒号后空格或回车

0a68d61abd4d4f4fb0b7b21833a826c7.png0bd6adc19f194c4ebeb34e7ce4fed628.png

1.3 :

https://nodeca.github.io/js-yaml/    进入后可以实现具体的编辑以及实时预览

yaml基本语法:

大小写区分 ;使用缩进冒号表示层级关系 ;缩进必须空格键 ;#表示注释

同一层级下的属性需要保持相同的缩进,且冒号后空格或回车

对象,数组(两种表示):

01873b6fad3c429d91a77c8e13f9e9d0.png

~表示null值:money: ~      

日期表示:2024-10-10  ;在spring中,2024/10/10来表示引用:25a58c14cf2d4e21b39c03a7ff5ca324.png

通过                对象名:&自定义名                               定义一个锚点

再通过            << : *自定义名                                        进行访问。

布尔值直接写就行,会识别的

1.4 应用yaml文件:

创建person类:

@Data
@ConfigurationProperties(prefix = "my.lkz.person")
public class Person {

    private String userName ;
    private Boolean boss ;
    private Date birth ;
    private Integer age ;
    private Pet pet ;
    private String[] interests ;
    private List<String> animal ;
    private Map<String,Object> scores ;
    private Set<Double> salary ;
    private Map<String,List<Pet>> allPets ;

在yaml中书写配置对象属性:

48347ecc68954ae4a983b3e71d3408f9.png

在处理器中写一个方法调用,别忘了responsebody,浏览器访问得:

5a0ca5280a5647b2a1c187a154dcb22a.png

对了,如果是直接用application文件改的yml文件,别忘了删除最顶上的

# åºç¨æå¡ WEB 访é®ç«¯å£

1.5 修改profile环境。

创建多个yml文件:注意,命名要以:application-{名称}.yml 类似这种的方式。

实现:创建三个yml文件,分别设置三个不同的端口号

   application-test :8081 

   application-dev :8082

   application-prod :8083   

在主application.yml文件中:

spring:
  profiles:
    active: dev  
启动测试后:得到的端口号为8082,测试完成

还有一种切换方式:在命令行启动时书写

四.接触springboot web

1.1 : 静态资源处理:

springboot并不需要像springmvc一样开发人员手动指定静态资源位置,springboot是怎么实现的?

Spring Boot 遵循了“约定大于配置”的原则,提供了默认的资源路径配置。具体来说,Spring Boot 默认会在以下路径下查找静态资源:

  • src/main/resources/static

  • src/main/resources/public

  • src/main/resources/resources

  • src/main/resources/META-INF/resources

如果你将静态资源放在这些目录中的任意一个,Spring Boot 会自动将它们暴露为静态资源。例如,如果你在 src/main/resources/static 目录下放置一个 index.html 文件,Spring Boot 会将其映射到应用的根 URL (/)。

内置的 ResourceHandlerRegistry

在 Spring Boot 启动时,它会自动配置一个 ResourceHandler,这个配置是由 WebMvcConfigurer 接口实现的。默认的实现会设置静态资源处理的规则,将这些资源暴露给应用的请求。Spring Boot 的 ResourceHandlerRegistry 配置了一些默认的静态资源路径,使得开发人员可以直接使用默认配置而无需额外的配置。

application.properties 或 application.yml 配置

尽管 Spring Boot 提供了默认的配置,但你仍然可以通过 application.propertiesapplication.yml 文件自定义静态资源的处理。以下是一些常用的配置选项:

  • spring.web.resources.static-locations:可以用来指定额外的静态资源位置

修改默认的静态资源访问路径:注意,修改后原有的无效

spring   

   mvc: 

     static-path-pattern:              //匹配请求

  resources: 

    static-location:                     //静态资源路径

1.2web欢迎页:

不写具体的访问地址,而是通过书写根目录实现访问。

在springboot中,直接输入网站进入的为欢迎页,这个欢迎页是默认在ststiac文件夹下的,

springboot会自动设置一个欢迎页处理器,类似于web静态资源处理,这个欢迎页处理器会自动到static下去找index.html 文件进行展示。

使用thymeleaf进行处理,引入依赖

1.3restful风格接口设计:表单请求需要,用ajax的话就没用了

详情请看:

还不懂 RESTful 接口是什么?快进来看看_resful接口是什么意思-优快云博客

HTTP协议的8种请求方式及常用请求方式的解析_请求方式详解-优快云博客

springMVC实现restful的原理HidenMethodFilter拦截器,在web配置文件中书写

原理

SpringBoot实现restful拦截的方式:书写请求类型注解

@GetMapping ; @PostMapping ;@DeleteMapping ; @PutMapping

与此同时,不同的请求方法可以使用相同的请求名称

注意,springboot没有自动帮你配置,你需要在sml文件中书写

原理就是源码中的一个注解的参数没有设置:

MissingIfMatch:true ;在注解中没有使用这个参数,因此不会自动配置,需要手动配置

好,写一个文件测试一下:

首先在springBoot配置文件中配置restful拦截:

spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true

然后书写一个控制器类:

@RestController     //此注解修饰的控制器方法自动加上了@ResponseBody,所有string写入响应体
                     //同时配置实现了restWeb服务
@RequestMapping("/restTest")
public class RestfulController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable("id") Integer id){
        return "GET - "+id ;
    }

    @PostMapping("/{id}")
    public String saveUser(@PathVariable("id") Integer id){
        return "POST - "+id ;
    }

    @PutMapping("/{id}")
    public String createUser(@PathVariable("id") Integer id){
        return "Put - "+id ;
    }

    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable("id") Integer id){
        return "DELETE - "+id ;
    }

}

重点来了,index中书写的

<h1>hello word!!!</h1>
<p>this is a html page</p>

<p>GET Method</p>
<form action="/restTest/123" method="get">
    <input type="submit">
</form>

<p>POST Method</p>
<form action="/restTest/123" method="post">
    <input type="submit">
</form>

<p>PUT Method</p>
<form action="/restTest/123" method="post">
    <input type="hidden" name="_method" value="put">   //注意,多出来的字段书写,name必须                                       为"_method",而value必须为指定的方法名,如put,delete等,其中包装的话要用post实现
    <input type="submit">
</form>

<p>DELETE Method</p>
<form action="/restTest/123" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit">
</form>

五. thymeleaf

1.1thymleaf模板原理

1.2 入门案例:

创建项目,template中引入thymeleaf依赖

打开springboot核心配置文件,spring会自动配置完

# 这个说明了无法支持热部署,即更新完的页面不会再被加载和渲染,因此开发时要设置为false
spring.thymeleaf.cache=true

thymeleaf中实现了mvc的视图解析器:

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

这意味着我们需要到resource文件夹下创建一个templates文件夹并再次创建html文件

在控制器类中书写:

@RequestMapping("/list")
public String list(Model model) {
    model.addAttribute("msg","Hello, World");
    return "users";
}
 

再html文件中书写

<html lang="en" xmlns:th="https://www.thymeleaf.org">
<p>这是一个thymeleaf页面</p>

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

结果如下:

入门总结:

1.2.1 thymeleaf语句应该写在指令内部 ;

        在spring核心配置文件中实现了thymeleaf的自动配置

        动静结合的页面,即未经过thymeleaf的模板引擎的页面打开只会显示静态内容

       spring.thymeleaf.cache=true的分析,热部署应为false

1.3 thymeleaf基本语法

1.3.1 字符串操作:

拼接:“   ’内容1‘ + ’内容2‘     ”

插值:“|内容|”

1.3.2:设置属性值

<h3>2.2设置属性值</h3><br>
<input type="text" th:value="${msg}"><br>

1.3.3:迭代

测试一下:

<h3>2.3迭代测试</h3><br>
         <table align="center">
             <tr>
                 <th>序号</th>
                 <th>姓名</th>
                 <th>ID</th>
                 <th>年龄</th>
                 <th>住址</th>
                 <th>联系方式</th>
             </tr>

             <tr th:each="user , s : ${users}">

                 <td th:text="${s.count}">序号</td>
                 <td th:text="${user.getName()}">姓名</td>
                 <td th:text="${user.id}">ID</td>
                 <td th:text="${user.getAge()}">年龄</td>
                 <td th:text="${user.getAddress()}">住址</td>
                 <td th:text="${user.getEmail()}">联系方式</td>

             </tr>
         </table>
MySelf me =new MySelf("lkz",1111,21,"China","gmail");
MySelf you =new MySelf("lk",2222,11,"China","Ngmail");
MySelf him =new MySelf("lz",3333,31,"UK","Hgmail");
MySelf her =new MySelf("kz",4444,41,"USA","Mgmail");

List<MySelf> list = new ArrayList<MySelf>();

list.add(me);
list.add(you);
list.add(him);
list.add(her);

model.addAttribute("users",list);

结果为:可,注意:此时的user后面的s代表status变量,类型有可看上图

 1.3.4条件判断

1.3.5内嵌变量

1.3.6 thymeleaf布局

定义一个片段,在别的html中引用这个片段如上图所示

语法: <div th:insert=" 文件名 ::fragment名(’title名‘) ">可以的<div>

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<footer th:fragment="copy(title)">
    &copy; 版权·诸葛亮所有 <br>
    <span th:text="${title}">title</span>
</footer>
</body>

</html>

1、静态文件的访问默认是在static目录下的文件,如果是通过编写控制类来访问,则必须在返回值后添加文件类型后缀

2、动态文件的访问默认是在templates目录下访问,且应在pom.xml中导入thymeleaf依赖。如果此时编写控制类访问,则会覆盖静态文件的路径,直接访问templates下的文件。

3、templates下的文件不能通过文件名直接进行访问,必须发起请求(编写控制类),或者向系统容器中添加相应的组件。并且添加组件的方式可以改变访问路径

TIP:springBoot 完成thymeleaf的配置后的资源访问策略:

访问根路径不带名,springBoot会自动访问static等默认静态资源存储位置

访问加上文件类型,此时springBoot会自动访问static等默认静态资源存储位置

访问加上控制器/方法名会进入到控制器方法中:

                                    返回string不加文件类型会到templates中寻找

                                    返回string加上文件类型会到静态资源位置寻找(有概率不行)

                           以上的默认为请求转发,重定向同理,但是加上文件类型能直接在静态找

注意,处理器转入到另一个处理器必须重定向

六. 拦截器

原理: 一个请求会先从拦截器开始,一层一层的经过拦截器,最后再进入处理器方法,再从处理器方法一层一层经过拦截器,最后进入视图解析器,在经过拦截器完成。

书写一个拦截器测试

一个登录页:login.html

<form action="/login" method="post">
    <input type="text" name="username" value="lkz">
    <input type="text" name="password" value="1234">
    <input type="submit">
</form>

一个控制器:

@RequestMapping("/login")
public String login(@RequestParam("username") String name , @RequestParam("password") String password, HttpSession session){
    if(name.equals("lkz") && password.equals("1234")){
        session.setAttribute("loginUser","admin");
        return "redirect:/list";
    }else {
        return "redirect:index.html";
    }

}

一个拦截器:注意必须实现HandlerInterceptor

public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 此方法用于实现拦截器 的 前置方法 ;后面的依次为后置 , 完成后最终(即视图)
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if(loginUser == null){
            response.sendRedirect("/login.html");
            return  false ;
        }else{
            return  true;
        }

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

配置拦截器:这个会将我们的拦截器添加到springBoot的拦截器中

@Configuration
public class LoginConfig implements WebMvcConfigurer {

    /**
     * 此方法用于配置自定义的拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).
                addPathPatterns("/**").              //映射路径 /**代表所有的请求都进行拦截
                excludePathPatterns("/login.html");              //放行路径 :指对login.html进行访问的请求会被放行
    }
}

测试以下:直接进入list页面不行,会跳转到login.html页面

七. 全局异常处理

mvc中全局异常处理:不展开说了,tip:@ControllerAdvice自定义全局异常处理类,都能捕获

Spring Boot项目优雅的全局异常处理方式(全网最新)_springboot全局异常处理-优快云博客

说实话,全局异常捕获在boot和mvc中区别不大,写法甚至可以一个样

白页的替换:在templates中创建error文件夹,在其中书写404.html或者对应名称的页面,在全局报错遇到白页时会到这里面去找对应名称的页面展示

八. 配置druid

选取判断:

springboot核心配置文件:
spring.datasource.url=jdbc:mysql://localhost:3306/mytest
spring.datasource.username=root
spring.datasource.password=0323
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
pom文件:
<!--   默认使用的是hikari的连接池,现在配置druid的连接池     -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.20</version>
        </dependency>

druid也实现了自动配置,但是还有一些手动的配置

配置druid

spring:
datasource:
#1.JDBC
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8
username: root
password: 123
druid:
#2.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache  官方建议MySQL下建议关闭   个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1
#deny: 192.168.1.100

想要监控:

 启动springBoot后再浏览器输入:http://localhost:tomcat端口号/项目名称/druid/login.html
输入账户密码,即可查看

参考:

SpringBoot中Druid数据源配置_spring druid地址-优快云博客

九. 配置Mybatis

mybatis:
  configuration:
    map-underscore-to-camel-case: true //下划线转驼峰
    aggressive-lazy-loading: false  // 激进懒加载
    lazy-loading-enabled: true   //懒加载
  mapper-locations: classpath:/mappers/**/*.xml   //会到REsources文件夹下找映射文件dao,不需要再将映射文件和dao接口放于一起了,还有方法:在接口上声明映射文件位置 @MapperScan(。。)
  type-aliases-package: com.lkz.demo.entity       //实体类别名映射

1.Dao:

我们需要在resources中添加一个mapper文件夹用于存放映射文件:文件同名,方法同名,命名空间

但是Mybatis并没有实现在SpringBoot中自动注册dao代理对象注册,意味着我们需要手动注册dao代理对象

方法一: 在接口上书写 @Mapper      注解以实现代理对象的注册

方法二:在启动类中书写 @MapperScan(”dao接口包名“),会将包下的所有接口生成代理对象

Mybatis_Plus  官网: baomidou.com  mybatis增强版,学习或者看

去maven仓库去找plus的场景启动器

在mybatis-plus中,我们不需要再去mapper文件夹中书写dao接口的映射文件了,因为plus已经帮助我们实现了最基础的实现类。

比如:继承BaseMapper<类名>的接口,在被mapper标注后自动生成dao代理对象,此时我们不需要去写dao接口映射文件,实现了最基础的增删改查操作

@Mapper
public interface UserDao extends BaseMapper<Dept> {


}

注意:映射文件和继承类都是可选项,根据实际情况使用

2.实体类:

在实体类中要声明几个注解:tableld只需用对主键用,tablefield其他的用(可省):匹配字段名

链式注入:@Accessors(chain = true)

好,现在我们想要实现在dao接口中书写一些额外功能的查询,该如何做呢?

3.mybatis-plus语法

注意:接口继承了baseMapper类的对象再被注册到spring中后,有着最基础的增删改查的方法,如果我们想要书写额外功能的语句,可以再接口中书写然后添加实现类进行具体的书写。

此外,mybatis-plus为我们提供了很多封装功能:

QueryWrapper类,Wrapper工具类,既可以创建新的语句方法,也可以在最基础的增删查改的方法上进行条件封装

(1)这个封装了一个语句:查询姓名有a,年龄大于18的

gt,大于 ; lt,小于 ;eq,等于;in存在    等等;

注意:继承BaseMapper和书写mapper映射文件这两种都是可以用的,根据实际情况书写

(2)批量修改:

批量修改方法二:

 userDao.update(Wrappers.<Uesr>update().like("name",'a').gt("age",18).set……)

更简单,语句量更少

(3)分页:

mybatis分页

mybatis-plus分页:

pageHelper插件:

原理: 

注意:如果依赖核心包的话需要我们手动配置分页插件(核心为拦截器),就是注册一下

然后使用:

@Test
void testPage(){
    PageHelper.startPage(1,5);,查询第一页,size为5;

    List<Dept> list = userDao.selectList(null);  //无包装,默认找全部

    //包装
    PageInfo pageInfo = new PageInfo(list);

    System.out.println(pageInfo);   //第几页数据

    System.out.println("总行数:"+pageInfo.getTotal());
    System.out.println("当前页:"+pageInfo.getPageNum());
    System.out.println("每页行数:"+pageInfo.getPageSize());
    System.out.println("总页数:"+pageInfo.getPages());
    System.out.println("起始行数:"+pageInfo.getStartRow());

    System.out.println("判断是否为第一页:"+pageInfo.isIsFirstPage());
    System.out.println("判断是否为最后页:"+pageInfo.isIsLastPage());
    System.out.println("判断是否还有下一页:"+pageInfo.isHasNextPage());
    System.out.println("判断是否还有上一页:"+pageInfo.isHasPreviousPage());
    System.out.println("页码列表:"+ Arrays.toString(pageInfo.getNavigatepageNums()));

}

使用for循环查看不同页(Vue拿来用)

因此推荐使用场景启动器实现,不用写拦截器了

(4)主键策略:

Mybatis-plus 主键生成策略详解_mybatisplus主键生成策略-优快云博客

AUTO:一般用

INPUT:订单号啥的用

NONE:

ASSIGN_ID:

ASSOIGN_UUID:

修改自增值:(alert table your_table auto increment = 1 ;

(5)使用Mybatis_plus进行映射文件的创建时的流程:

实体类有了,自定义dao文件夹下的dao接口(mapper文件夹也行,别是resources下的就行)继承BaseMapper类 (BaseMapper<User>),

然后服务包下创建对应的服务方法接口:IUserService并继承Mybatis-plus自带的IService<User>这个接口: public interface IUserService extends IService<User>{}

最后在实现类文件夹中给出实现类,注意要先继承ServiceImpl这个mybatis自带的基础实现类:

public UserServiceImpl extends ServiceImpl<UserMapper,User> implement IUserService{} 

实现后,必须这样:private UserMapper userMapper;进行Mapper对象的引入,然后在实现类中使用

tip:xml文件以及Mybatis-plus新增的功能可以同时使用:即,我们既可以在mapper中定义很多方法在xml文件中进行创建,也可以继承baseMapper然后使用baseMapper中的服务。

十. 实战项目:账单增删改查

tools: springBoot, thymeleaf, druid , devtool, lombok,mybatis(不用代码生成器)

tip: 

(1)sql语句查询的函数:

推荐第二种方法: and b.title_ LIKE CONCAT(‘%’,#{title},‘%’)

记得最开始Mybatis有两种占位符:#{} 和 ${}, 如果进行模糊查询的话,只能使用${}作为连接符和占位符,会有sql注入问题,因此推荐使用CONCAT() 函数进行模糊查询(注意,mysql用CONCAT函数)

(2)My97日历控件

(3)springBoot控制器访问,没有指定对象参数,spring会自动创建一个,并将表单中提交的字段和这个对象的属性名进行匹配并赋值

十一. 报错以及解决

情景一:springboot报错:Access Denied for user 'root'@'localhost':

原因:

  • 在 YAML 中,如果一个数字以 0 开头,且后面跟着其他数字(如 0123),YAML 解释器会将其视为八进制(base 8)数。
  • 例如,0123 会被解释为八进制的 123,其十进制值为 83

解决方案:将数字密码转换成字符串

datasource:
    username: root
    url: jdbc:mysql://localhost:3306/mytest
    password: "0323"
    driver-class-name: com.mysql.cj.jdbc.Driver

参考:

SpringBoot项目连接数据库报错:Access denied for user 'root'@'localhost' (using password: YES)_以下项目未通过检测:access denied for user-优快云博客

情景二:

Ctrl+Shift+T 表示为当前类启动测试类

情景三: 

java.util.Date 和 java.sql,date 的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值