教程与文档 SpringBoot2核心技术与响应式编程 · 语雀 (yuque.com)
Spring与SpringBoot2 01、Spring与SpringBoot · 语雀 (yuque.com)
HelloWorld
导入依赖 pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.3.3.RELEASE</version > </parent > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > </dependencies >
编写controller HelloController.java
1 2 3 4 5 6 7 8 9 10 @RestController public class HelloController { @RequestMapping("/hello") public String handle1 () { return "Hello,SpringBoot2" ; } }
编写主程序类并测试 MainApplication.java
1 2 3 4 5 6 7 8 9 10 11 @SpringBootApplication public class MainApplication { public static void main (String[] args) { SpringApplication.run(MainApplication.class, args); } }
resources文件夹下application.properties,可根据文档自定义配置
Common Application properties (spring.io)
创建可执行jar包,添加build依赖,然后点击maven中的lifecycle中的clean与package并执行 pom.xml
1 2 3 4 5 6 7 8 9 <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <version > 2.2.4.RELEASE</version > </plugin > </plugins > </build >
执行jar包,在target目录下执行以下命令
java -jar 包名.jar
依赖管理与自动配置特性 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
底层注解 @Configuration、@Bean 配置对象 原 原Spring使用xml配置文件配置bean对象如下
bean.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id ="user01" class ="com.myspringboot2.bean.User" > <property name ="name" value ="zhangsan" /> <property name ="age" value ="18" /> </bean > <bean id ="cat" class ="com.myspringboot2.bean.Pet" > <property name ="name" value ="mimi" /> </bean > </beans >
现 编写配置MyConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration(proxyBeanMethods = true) public class MyConfig { @Bean public User user01 () { return new User("zhangsan" , 18 ); } @Bean("pet01") public Pet cat () { return new Pet("mimi" ); } }
测试类MainApplication.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @SpringBootApplication public class MainApplication { public static void main (String[] args) { ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); User user01 = run.getBean("user01" , User.class); Pet pet01 = run.getBean("pet01" , Pet.class); MyConfig myConfig = run.getBean(MyConfig.class); } }
Full模式与Lite模式
配置类组件之间无依赖关系用Lite模式加速客器启动过程,减少判断
配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
@ComponentScan 包扫描 1 2 3 4 @ComponentScan("com.myspringboot2") @EnableAutoConfiguration @SpringBootConfiguration
@Import 注入对象 1 @Import({User.class, DBHelper.class})
@Conditional 条件装配 使用 MyConfig.java
1 2 3 4 5 6 7 8 @Configuration(proxyBeanMethods = false) public class MyConfig { @ConditionalOnBean(name = "pet02") @Bean public User user01 () { return new User("zhangsan" , 18 ); } }
测试 MainApplication.java
1 2 3 4 5 6 7 8 9 @SpringBootApplication public class MainApplication { public static void main (String[] args) { ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); System.out.println(run.containsBean("user01" )); } }
@ImportResource 导入xml配置文件 1 2 3 4 @ImportResource("classpath:beans.xml") @Configuration(proxyBeanMethods = false) public class MyConfig {}
1 2 3 4 5 6 7 8 9 @SpringBootApplication public class MainApplication { public static void main (String[] args) { ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); System.out.println(run.containsBean("user01" )); } }
@ConfigurationProperties 配置绑定 编写属性, application.properties
,注意使用全小写
1 2 mycar.brand =ABC mycar.price =100000
第一种方法:需要在容器中的组件上使用, Car.java
1 2 3 4 5 6 7 @Component @ConfigurationProperties(prefix = "mycar") public class Car { String brand; Integer price; }
第二种方法:不使用@Component声明Car为组件,而是在配置类种开启指定对象的属性配置功能
1 2 3 4 5 @EnableConfigurationProperties(Car.class) @Configuration(proxyBeanMethods = false) public class MyConfig { }
测试, HelloController.java
1 2 3 4 5 6 7 8 9 @RestController public class HelloController { @Autowired Car car; @RequestMapping("/car") public Car car () { return car; } }
自动配置原理(源码分析 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
@SpringBootApplication
声明当前是一个配置类
@ComponentScan
指定扫描路径
@EnableAutoConfiguration @AutoConfigurationPackage
利用Registrar将当前包下的所有组件全部导入进容器
@Import
导入默认组件
便捷使用 Lombok
简化JavaBean编写等
引入依赖
1 2 3 4 <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </dependency >
编写JavaBean
1 2 3 4 5 6 7 @NoArgsConstructor @AllArgsConstructor @Data public class Car { String brand; Integer price; }
编写controller的日志打印
1 2 3 4 5 6 7 8 9 10 @Slf4j //引入日志接口 @RestController public class HelloController { // 映射请求的地址 @RequestMapping("/hello") public String handle1() { log.info("hello"); //日志打印信息 return "Hello,SpringBoot2"; } }
自动重启、热更新
引入依赖
1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-devtools</artifactId > <optional > true</optional > </dependency >
使用 Ctrl+F9 更新
Spring Initializr
快速创建springboot应用,创建应用时选择即可
配置文件 properties yaml 基本语法
key: value #注意空格
大小写敏感
使用缩进表示层级关系
缩进不允许使用tab,只允许空格
缩进空格数无影响,同层级的元素需要左对齐
#编写注释
“”双引号内\n等不转义,仍然是回车的本意显示为回车,’’单引号内转义,\n显示为字符串
数据类型
字面量
对象
1 2 3 4 5 6 k: {k1: v1 ,k2: v2 ,k3: v3 }k: k1: v1 k2: v2 k3: v3
数组
1 2 3 4 5 6 k: [v1 ,v2 ,v3 ]k: - v1 - v2 - v3
示例 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
configuration-processor
配置处理器
添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-configuration-processor</artifactId > <optional > true</optional > </dependency > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <version > 2.2.4.RELEASE</version > <configuration > <excludes > <exclude > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-configuration-processor</artifactId > </exclude > </excludes > </configuration > </plugin > </plugins > </build >
web开发 简单功能 静态资源访问
欢迎页 命名为index.html放在静态资源目录下即可。
自定义Favicon 命名为favicon.ico 放在静态资源目录下即可。
源码分析 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
请求处理 @xxxMapping 请求映射
Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)
以前:**/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
编写controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @RestController public class HelloController { @GetMapping("/user") public String getUser () { return "getUser GET" ; } @PostMapping("/user") public String saveUser () { return "saveUser POST" ; } @PutMapping("/user") public String modifiedUser () { return "modifiedUser PUT" ; } @DeleteMapping("/user") public String deleteUser () { return "deleteUser DELETE" ; } }
编写页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <form action ="/user" method ="get" > <input type ="submit" value ="get提交" > </form > <form action ="/user" method ="post" > <input type ="submit" value ="post提交" > </form > <form action ="/user" method ="post" > <input type ="hidden" name ="_method" value ="PUT" > <input type ="submit" value ="PUT提交" > </form > <form action ="/user" method ="post" > <input type ="hidden" name ="_method" value ="DELETE" > <input type ="submit" value ="DELETE提交" > </form >
在配置文件中开启hiddenmethod-filter(默认为false),如果前端不是使用表单发送请求则不需要开启filter
1 2 3 4 5 spring: mvc: hiddenmethod: filter: enabled: true
自定义HiddenMethodFilter 编写配置类,自定义filter
1 2 3 4 5 6 7 8 @Configuration(proxyBeanMethods = false) public class MyWebConfig { public HiddenHttpMethodFilter hiddenHttpMethodFilter () { HiddenHttpMethodFilter filter = new HiddenHttpMethodFilter(); filter.setMethodParam("_m" ); return filter; } }
请求映射原理 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
参数注解 @PathVariable、@RequestHeader、@RequestParam、@CookieValue、@RequestBody 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 @RestController public class ParamTestController { @GetMapping("/test1/{id}/{username}") public Map<String, Object> test1 (@PathVariable("id") Integer id, @PathVariable("username") String name, @PathVariable Map<String, String> variables, @RequestHeader("User-Agent") String userAgent, @RequestHeader Map<String, String> headers, @RequestParam("age") Integer age, @RequestParam("inters") List<String> inters, @RequestParam Map<String,String> params1, @RequestParam MultiValueMap<String, String> params2, @CookieValue("_xsrf") String _xsrf, @CookieValue("_xsrf") Cookie cookie) { Map<String, Object> map = new HashMap<>(); map.put("id" , id); map.put("name" , name); map.put("pv" , variables); map.put("userAgent" , userAgent); map.put("rh" , headers); map.put("age" ,age); map.put("inters" ,inters); map.put("params1" ,params1); map.put("params2" ,params2); map.put("_xsrf" ,_xsrf); System.out.println(cookie.getName()+"===>" +cookie.getValue()); return map; } @PostMapping("/test2") public Map<String, Object> test2 (@RequestBody String content) { Map<String, Object> map = new HashMap<>(); map.put("content" , content); return map; } }
@RequestAttribute 获取域对象参数值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Controller public class RequestController { @GetMapping("/goto") public String gotoPage (HttpServletRequest req) { req.setAttribute("msg" , "信息" ); req.setAttribute("code" , "信息123123" ); return "forward:/success" ; } @ResponseBody @GetMapping("/success") public Map<String, Object> success (@RequestAttribute("msg") String msg, @RequestAttribute("code") String code) { Map<String, Object> map = new HashMap<>(); map.put("msg" , msg); map.put("code" , code); return map; } }
@MatrixVariable 获取矩阵变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @GetMapping("/cars/{path}") public Map carsSell (@MatrixVariable("low") Integer low, @MatrixVariable("brand") List<String> brand, @PathVariable("path") String path) { Map<String,Object> map = new HashMap<>(); map.put("low" ,low); map.put("brand" ,brand); map.put("path" ,path); return map; } @GetMapping("/boss/{bossId}/{empId}") public Map boss (@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge, @MatrixVariable(value = "age",pathVar = "empId") Integer empAge) { Map<String,Object> map = new HashMap<>(); map.put("bossAge" ,bossAge); map.put("empAge" ,empAge); return map; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Configuration(proxyBeanMethods = false) public class MyWebConfig { public HiddenHttpMethodFilter hiddenHttpMethodFilter () { HiddenHttpMethodFilter filter = new HiddenHttpMethodFilter(); filter.setMethodParam("_m" ); return filter; } @Bean public WebMvcConfigurer webMvcConfigurer () { return new WebMvcConfigurer() { @Override public void configurePathMatch (PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false ); configurer.setUrlPathHelper(urlPathHelper); } }; } }
ServletAPI
WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId
参数注解源码分析 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
直接看困了,以后再看吧。
自定义参数绑定
编写两个bean
1 2 3 4 5 6 7 8 @Data public class User { String username; String password; Integer age; Date birthday; Pet pet; }
1 2 3 4 5 @Data public class Pet { String name; Integer age; }
编写表单
1 2 3 4 5 6 7 8 <form action ="/saveuser" method ="post" > 姓名:<input type ="text" name ="username" > 年龄:<input type ="number" name ="age" > 生日:<input type ="date" name ="birthday" > 宠物名字:<input type ="text" name ="pet.name" > 宠物年龄:<input type ="number" name ="pet.age" > <input type ="submit" value ="POST提交" > </form >
编写controller测试
1 2 3 4 @PostMapping("/saveuser") public User saveuser (User user) { return user; }
自定义转换器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Configuration(proxyBeanMethods = false) public class MyWebConfig { @Bean public WebMvcConfigurer webMvcConfigurer () { return new WebMvcConfigurer() { @Override public void addFormatters (FormatterRegistry registry) { registry.addConverter(new Converter<String, Date>() { @Override public Date convert (String s) { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd" ); Date date = null ; try { date = sf.parse(s); } catch (ParseException e) { e.printStackTrace(); } return date; } }); } }; } }
数据响应与内容协商 响应JSON数据
引入jackson.jar,已包含在starter-web场景启动器中
使用注解@ResponseBody
响应原理 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
内容协商
根据客户端接收能力不同,返回不同媒体类型的数据。
以xml为示例,引入依赖
1 2 3 4 <dependency > <groupId > com.fasterxml.jackson.dataformat</groupId > <artifactId > jackson-dataformat-xml</artifactId > </dependency >
请求头里accept字段,设置了接收数据以xml格式为优先
开启基于请求参数的内容协商原理,同时url中添加请求参数format=xxx即可
1 2 3 4 spring: mvc: contentnegotiation: favor-parameter: true
内容协商原理 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
自定义MessageConvertor 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
视图解析与模板引擎 thymeleaf
java模板引擎
基本语法
引入依赖
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</artifactId > </dependency >
编写模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html > <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 th:text ="${msg}" > 默认的值</h1 > <h2 > <a href ="www.google.com" th:href ="${link}" > 跳转百度</a > <a href ="www.google.com" th:href ="@{link}" > 跳转百度</a > </h2 > </body > </html >
编写controller
1 2 3 4 5 6 7 8 9 10 11 @Controller public class ViewTestController { @GetMapping("/testsuccess") public String test (Model model) { model.addAttribute("msg" , "msgTest" ); model.addAttribute("link" , "https://www.baidu.com" ); return "success" ; } }
拦截器 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
编写Interceptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @Slf4j public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("Run LoginInterceptor.preHandle" ); HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser" ); if (loginUser != null ) { return true ; } else { session.setAttribute("msg" , "当前尚未登录" ); response.sendRedirect("/" ); return false ; } } @Override public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("Run LoginInterceptor.postHandle" ,modelAndView); } @Override public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("Run LoginInterceptor.afterCompletion" ,ex); } }
编写WebConfig类,添加interceptor
1 2 3 4 5 6 7 8 9 10 @Configuration public class AdminWebConfig implements WebMvcConfigurer { @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**" ).excludePathPatterns("/" ,"/login" ,"/css/**" ,"/js/**" ,"/font/**" ,"/images/**" ); } }
文件上传 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
编写controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @Slf4j @Controller public class FormTestController { @GetMapping("/form_layouts") public String formLayouts () { return "form/form_layouts" ; } @PostMapping("/upload") public String upload (@RequestParam("email") String email, @RequestParam("name") String name, @RequestPart("headImg") MultipartFile headImg, @RequestPart("photos") MultipartFile[] photos) throws IOException { log.info("上传的信息:email={},name={},headImg={},photos={}" , email, name, headImg.getSize(), photos.length); if (!headImg.isEmpty()) { headImg.transferTo(new File("C:\\Users\\卢荟\\Desktop\\test1\\" +headImg.getOriginalFilename())); } if (photos.length > 0 ) { for (MultipartFile photo : photos) { if (!photo.isEmpty()) { photo.transferTo(new File("C:\\Users\\卢荟\\Desktop\\test2\\" +photo.getOriginalFilename())); } } } return "index" ; } }
编写配置文件
1 2 3 spring.servlet.multipart.max-file-size =10MB spring.servlet.multipart.max-request-size =100MB
异常处理
默认情况下,Spring Boot提供/error
处理所有错误的映射
对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。
对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
自定义错误页 在将400.html、500.html等页面放在resources > templates >error下即可
自定义异常处理 @ControllerAdvice+@ExceptionHandler 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({ArithmeticException.class, NullPointerException.class}) public String handleArithException (Exception e) { log.error("异常是:{}" , e); return "error/404" ; } }
@ResponseStatus+自定义Exception 1 2 3 4 5 6 7 8 9 @ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户数量太多") public class UserTooManyException extends RuntimeException { public UserTooManyException () { } public UserTooManyException (String msg) { super (msg); } }
自定义HandlerExceptionResolver 1 2 3 4 5 6 7 8 9 10 11 12 @Component public class CustomerHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { try { httpServletResponse.sendError(511 , "自定义错误" ); } catch (IOException ex) { ex.printStackTrace(); } return new ModelAndView(); } }
原生组件注入 ServletAPI @ServletComponentScan 主应用类中使用@ServletComponentScan配置扫描路径
1 2 3 4 5 6 7 @ServletComponentScan(basePackages = "com.spb_adminex.servlet") //配置servlet、filter、listener扫描地址 @SpringBootApplication public class SpbAdminexApplication { public static void main(String[] args) { SpringApplication.run(SpbAdminexApplication.class, args); } }
@WebServlet 1 2 3 4 5 6 7 @WebServlet(urlPatterns = "/my") public class MyServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("MyServlet running" ); } }
@WebFilter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Slf4j @WebFilter(urlPatterns = {"/css/*","/images/*"}) public class MyFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { log.info("MyFilter初始化" ); } @Override public void destroy () { log.info("MyFilter销毁" ); } @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("MyFilter running" ); filterChain.doFilter(servletRequest, servletResponse); } }
@WebListener 1 2 3 4 5 6 7 8 9 10 11 12 @Slf4j @WebListener public class MyListener implements ServletContextListener { @Override public void contextInitialized (ServletContextEvent sce) { log.info("MyListener监听到项目初始化完成" ); } @Override public void contextDestroyed (ServletContextEvent sce) { log.info("MyListener监听到项目销毁" ); } }
RegisterBean 编写一个配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration public class MyRegisterConfig { @Bean public ServletRegistrationBean myServlet () { return new ServletRegistrationBean(new MyServlet(), "/my" ); } @Bean public FilterRegistrationBean myFilter () { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter()); filterRegistrationBean.setUrlPatterns(Arrays.asList("/my" ,"/css/*" )); return filterRegistrationBean; } @Bean public ServletListenerRegistrationBean myListener () { return new ServletListenerRegistrationBean(new MyListener()); } }
数据访问 SQL 使用默认数据源、jdbcTemplate
导入starter场景和数据库驱动
1 2 3 4 5 6 7 8 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency >
编写配置文件application.yaml
1 2 3 4 5 6 spring: datasource: url: jdbc:mysql://localhost:3306/online_bookstore username: root password: 123456789 driver-class-name: com.mysql.cj.jdbc.Driver
使用jdbcTemplate测试
1 2 3 4 5 6 7 8 9 10 11 @Slf4j @SpringBootTest class SpbAdminexApplicationTests { @Autowired JdbcTemplate jdbcTemplate; @Test void contextLoads () { Long count = jdbcTemplate.queryForObject("select count(*) from admin" , Long.class); log.info("当前表的记录数为" + count); } }
使用Druid数据源
引入数据源
1 2 3 4 5 <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.6</version > </dependency >
编写数据源配置类
1 2 3 4 5 6 7 8 9 10 @Configuration public class MyDataSourceConfig { @ConfigurationProperties("spring.datasource") @Bean public DataSource dataSource () { DruidDataSource druidDataSource = new DruidDataSource(); return druidDataSource; } }
测试
1 2 3 4 5 6 7 8 9 10 @Slf4j @SpringBootTest class SpbAdminexApplicationTests { @Autowired DataSource dataSource; @Test void contextLoads () { log.info("当前数据源类型为{}" , dataSource.getClass()); } }
其他👉雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
使用xml配置文件整合MyBatis
导入依赖
1 2 3 4 5 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.2.0</version > </dependency >
编写application.yaml配置文件
1 2 3 mybatis: config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml
编写mybatis-config.xml全局配置文件/或者编写application配置文件(此时不能同时配置全局配置文件位置)
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration > <settings > <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > </configuration >
1 2 3 4 mybatis: mapper-locations: classpath:mybatis/mapper/*.xml configuration: map-underscore-to-camel-case: true
编写beanMapper接口
1 2 3 4 5 @Mapper public interface AdminMapper { public Admin getAdmin (Integer id) ; public Boolean insertAdmin (Admin admin) ; }
编写beanMapper.xml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 <?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.spb_adminex.mapper.AdminMapper" > <select id ="getAdmin" resultType ="com.spb_adminex.bean.Admin" > select * from admin where id=#{id} </select > <insert id ="insertAdmin" useGeneratedKeys ="true" keyProperty ="id" > insert into admin(`account`,`password`) values(#{account},#{password}) </insert > </mapper >
编写service层
1 2 3 4 5 6 7 8 9 10 11 12 @Service public class AdminService { @Autowired AdminMapper adminMapper; public Admin getAdminById (Integer id) { return adminMapper.getAdmin(id); } public Boolean insertAdmin (Admin admin) { return adminMapper.insertAdmin(admin); } }
编写controller层
1 2 3 4 5 6 7 8 9 10 11 @Controller public class AdminController { @Autowired AdminService adminService; @ResponseBody @GetMapping("/getAdmin") public Admin getAdminById (@RequestParam("id") Integer id) { return adminService.getAdminById(id); } }
使用注解整合MyBatis
其余文件,且不需要beanMapper.xml
编写beanMapper接口
1 2 3 4 5 @Mapper public interface AdminMapper { @Select("select * from admin where id=#{id}") public Admin getAdmin (Integer id) ; }
整合MyBatis-Plus 快速开始 | MyBatis-Plus (baomidou.com)
获取数据
导入依赖
1 2 3 4 5 <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.4.3</version > </dependency >
为启动类添加@MapperScan,注明扫描Mapper文件的地址
1 2 3 4 5 6 7 8 9 @SpringBootApplication @MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper") public class Application { public static void main (String[] args) { SpringApplication.run(QuickStartApplication.class, args); } }
编写全局配置文件
1 2 3 4 5 6 spring: datasource: url: jdbc:mysql://localhost:3306/spb_adminex username: root password: 123456789 driver-class-name: com.mysql.cj.jdbc.Driver
编写Bean类
1 2 3 4 5 6 7 8 9 10 11 12 13 @NoArgsConstructor @AllArgsConstructor @Data @TableName("user") public class User { private Long id; private String name; private String age; private String email; @TableField(exist = false) private String test; }
编写BeanMapper接口
1 2 public interface UserMapper extends BaseMapper<User> { }
编写BeanService接口
1 2 3 public interface UserService extends IService <User > {}
编写BeanServiceImpl实现类
1 2 3 4 @Service public class UserServiceImpl extends ServiceImpl <UserMapper ,User > implements UserService {}
编写controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Controller public class TableController { @Autowired UserService userService = new UserServiceImpl(); @GetMapping("/dynamic_table") public String dynamicTable (Model model) { List<User> userList = userService.list(); model.addAttribute("userList" , userList); return "table/dynamic_table" ; } @GetMapping("/responsive_table") public String responsiveTable () { return "table/responsive_table" ; } @GetMapping("/editable_table") public String editableTable () { return "table/editable_table" ; } }
分页操作
编写MybatisPlugConfig
1 2 3 4 5 6 7 8 9 10 @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor () { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
编写controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Controller public class TableController { @Autowired UserService userService = new UserServiceImpl(); @GetMapping("/dynamic_table") public String dynamicTable (@RequestParam(value = "pn",defaultValue = "1") Integer pn, Model model) { Page<User> page = userService.page(new Page<User>(pn, 2 )); model.addAttribute("page" , page); return "table/dynamic_table" ; } @GetMapping("/user/delete/{id}") public String deleteUser (@PathVariable("id") Long id, @RequestParam(value = "pn",defaultValue = "1") Integer pn, RedirectAttributes ra) { userService.removeById(id); ra.addAttribute("pn" , pn); return "redirect:/dynamic_table" ; } }
编写html页面,thymeleaf语法详见雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <table > <thead > <tr > <th > id</th > <th > 用户名</th > <th > 年龄</th > <th > 邮箱</th > <th > 操作</th > </tr > </thead > <tbody > <tr class ="gradeX" th:each ="user,status:${page.getRecords()}" > <td th:text ="${status.count}" > xxx</td > <td th:text ="${user.name}" > xxx</td > <td th:text ="${user.age}" > xxx</td > <td th:text ="${user.email}" > xxx</td > <td > <a th:href ="@{/user/delete/{id}(id=${user.id},pn=${page.current})}" class ="btn btn-primary" > 删除</a > </td > </tr > </tbody > </table > <div class ="row-fluid" > <div > <div class ="dataTables_info" > 当前第[[${page.current}]]页 总计[[${page.pages}]]页 总[[${page.getTotal}]]条记录 </div > </div > <div > <div class ="dataTables_paginate paging_bootstrap pagination" > <ul > <li class ="prev disabled" > <a href ="#" > ← Previous</a > </li > <li th:class ="${num == page.current?'active':''}" th:each ="num:${#numbers.sequence(1,page.pages)}" > <a th:href ="@{/dynamic_table(pn=${num})}" > [[${num}]]</a > </li > <li class ="next disabled" > <a href ="#" > Next → </a > </li > </ul > </div > </div > </div >
NoSQL(Redis) 不尝试了没钱
单元测试 @SpringBootTest 1 2 3 4 5 6 @SpringBootTest class MyTest { @Test public void test () { } }
常用注解
**@Test :**表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
**@ParameterizedTest :**表示方法是参数化测试,下方会有详细介绍
**@RepeatedTest :**表示方法可重复执行,下方会有详细介绍
**@DisplayName :**为测试类或者测试方法设置展示名称
**@BeforeEach :**表示在每个单元测试之前执行
**@AfterEach :**表示在每个单元测试之后执行
**@BeforeAll :**表示在所有单元测试之前执行
**@AfterAll :**表示在所有单元测试之后执行
**@Tag :**表示单元测试类别,类似于JUnit4中的@Categories
**@Disabled :**表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
**@Timeout :**表示测试方法运行如果超过了指定时间将会返回错误
**@ExtendWith :**为测试类或测试方法提供扩展类引用
断言机制 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
…… 指标监控 雷丰阳2021版SpringBoot2零基础入门springboot全套完整版(spring boot2)_哔哩哔哩_bilibili
高级特性 后会有期 源码和其他部分到时候(也不知道啥时候)会再去看的,but not today