一. 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个配置类
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,在下一个项目中试验一下这个场景启动器
三. 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
基本语法规则:大小写区分 ;使用缩进冒号表示层级关系 ;缩进必须空格键 ;#表示注释
同一层级下的属性需要保持相同的缩进,且冒号后空格或回车
1.3 :
https://nodeca.github.io/js-yaml/ 进入后可以实现具体的编辑以及实时预览
yaml基本语法:
大小写区分 ;使用缩进冒号表示层级关系 ;缩进必须空格键 ;#表示注释
同一层级下的属性需要保持相同的缩进,且冒号后空格或回车
对象,数组(两种表示):
~表示null值:money: ~
日期表示:2024-10-10 ;在spring中,2024/10/10来表示引用:
通过 对象名:&自定义名 定义一个锚点
再通过 << : *自定义名 进行访问。
布尔值直接写就行,会识别的
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中书写配置对象属性:
在处理器中写一个方法调用,别忘了responsebody,浏览器访问得:
对了,如果是直接用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.properties
或 application.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)"> © 版权·诸葛亮所有 <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
参考:
情景二:
Ctrl+Shift+T 表示为当前类启动测试类
情景三:
java.util.Date 和 java.sql,date 的区别