上一节《spring boot第一个web服务》中我们只是简单的展示了spring mvc的功能,并没有涉及到具体的CRUD的操作,也没有涉及到数据持久化的方面。本节中我们将基于原始的JDBC和简单的JPA两种数据持久化的方式讲解web应用中的CRUD操作,具体内容以用户的注册、登录、详情查询、列表查询为场景来展开(注:文章中的例子只为演示spring boot功能而设计,不能做为生产版本,针对生产版本还需做很多思考和优化工作)。

1.表结构

  1. /*==============================================================*/
  2. /* Table: t_user 用户表 */
  3. /*==============================================================*/
  4. (
  5. id bigint not null auto_increment comment 'id:主键',
  6. name varchar(8) not null comment '姓名',
  7. password varchar(8) comment '性别',
  8. primary key (id)
  9. );

2.构建实体类

为了提高代码的可读性,我们这里用到了Lombok,它能自动生成getter、setter、toString()等常见方法。使用它时,需引入依赖

  1. <!--lombok-->
  2. <dependency>
  3. <groupId>org.projectlombok</groupId>
  4. <artifactId>lombok</artifactId>
  5. <optional>true</optional>
  6. </dependency>

然后使用注解@Data来进行使用

用户实体类User

  1. package com.kinglead.demo.entity;

  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;

  5. import java.io.Serializable;

  6. @Data //添加getter、setter方法
  7. @NoArgsConstructor //无参构造函数
  8. @AllArgsConstructor //所以参数构造函数
  9. public class User implements Serializable {
  10. private static final long serialVersionUID = -21070736985722463L;
  11. /**
  12. * id:主键
  13. */
  14. private Long id;
  15. /**
  16. * 姓名
  17. */
  18. private String name;
  19. /**
  20. * 密码
  21. */
  22. private String password;
  23. }

3.请求Request类

为了方便简单的对表单进行校验,我们引入Validation API依赖,使用相关注解声明校验规则,如@NotNull、@Size等,注解直接加到类的成员变量上即可。

  1. <!--validation表单校验-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-validation</artifactId>
  5. </dependency>

UserVo

  1. package com.kinglead.demo.vo;

  2. import lombok.Data;

  3. import javax.validation.constraints.NotNull;
  4. import javax.validation.constraints.Size;
  5. import java.io.Serializable;

  6. @Data
  7. public class UserVo implements Serializable {
  8. private static final long serialVersionUID = -21070736985722463L;
  9. /**
  10. * 用户名
  11. */
  12. @NotNull(message = "用户名不能为空")
  13. @Size(max = 20, message = "用户名长度不能大于20")
  14. private String userName;
  15. /**
  16. * 密码
  17. */
  18. @NotNull(message = "密码不能为空")
  19. @Size(max = 20, message = "密码长度不能大于20")
  20. private String password;

  21. }

4.控制器Controller

用户UserController

  1. package com.kinglead.demo.controller;

  2. import com.kinglead.demo.entity.User;
  3. import com.kinglead.demo.service.UserService;
  4. import com.kinglead.demo.vo.UserVo;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.validation.BindingResult;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.PostMapping;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.servlet.ModelAndView;

  12. import javax.annotation.Resource;
  13. import javax.validation.Valid;
  14. import java.util.List;
  15. import java.util.Map;

  16. @Slf4j
  17. @Controller
  18. @RequestMapping("/user")
  19. public class UserController {

  20. /**注入UserService**/
  21. @Resource
  22. private UserService userService;

  23. /**
  24. *注册页面
  25. */
  26. @GetMapping("/register")
  27. public ModelAndView register(ModelAndView modelAndView){
  28. modelAndView.setViewName("register");
  29. return modelAndView;
  30. }

  31. /**
  32. *注册
  33. */
  34. @PostMapping("/register")
  35. public ModelAndView register(ModelAndView modelAndView, @Valid UserVo userVo, BindingResult bindingResult){
  36. //校验参数
  37. if(bindingResult.hasErrors()){
  38. modelAndView.addObject("error",bindingResult.getFieldError().getDefaultMessage());
  39. modelAndView.setViewName("register");
  40. return modelAndView;
  41. }
  42. //注册
  43. User user = new User();
  44. user.setName(userVo.getUserName());
  45. user.setPassword(userVo.getPassword());
  46. userService.insert(user);
  47. //注册成功返回到登录页面
  48. modelAndView.setViewName("login");
  49. return modelAndView;
  50. }

  51. /**
  52. *登录页面
  53. */
  54. @GetMapping("/login")
  55. public ModelAndView login(ModelAndView modelAndView){
  56. modelAndView.setViewName("login");
  57. return modelAndView;
  58. }

  59. /**
  60. *登录
  61. */
  62. @PostMapping("/login")
  63. public ModelAndView login(ModelAndView modelAndView,@Valid UserVo userVo, BindingResult bindingResult){
  64. //效验入参
  65. if(bindingResult.hasErrors()){
  66. modelAndView.addObject("error",bindingResult.getFieldError().getDefaultMessage());
  67. modelAndView.setViewName("login");
  68. return modelAndView;
  69. }
  70. //效验用户
  71. User user = new User();
  72. user.setName(userVo.getUserName());
  73. user.setPassword(userVo.getPassword());
  74. User rstUser = userService.queryByNameAndPassword(user);
  75. if(null == rstUser){
  76. modelAndView.addObject("error","用户名或密码错误!");
  77. modelAndView.setViewName("login");
  78. }
  79. //展示首页
  80. modelAndView.addObject("userName",rstUser.getName());
  81. modelAndView.setViewName("index");
  82. return modelAndView;
  83. }

  84. /**
  85. * 查询用户列表
  86. */
  87. @GetMapping("/userList")
  88. public ModelAndView queryAll(ModelAndView modelAndView){
  89. //查询用户列表
  90. List<Map<String, Object>> userList = userService.queryAll();
  91. //返回
  92. modelAndView.addObject("userList", userList);
  93. modelAndView.setViewName("userList");
  94. return modelAndView;
  95. }

  96. }

5.服务接口Service及实现类

UserService

  1. package com.kinglead.demo.service;

  2. import com.kinglead.demo.entity.User;

  3. import java.util.List;
  4. import java.util.Map;

  5. public interface UserService {

  6. /**
  7. * 新增用户
  8. */
  9. User insert(User user);

  10. /**
  11. * 通过用户名和密码查询用户
  12. */
  13. User queryByNameAndPassword(User user);

  14. /**
  15. * 查询用户列表
  16. */
  17. List<Map<String, Object>> queryAll();

  18. }

UserServiceImpl

  1. package com.kinglead.demo.service.impl;

  2. import com.kinglead.demo.entity.User;
  3. import com.kinglead.demo.service.UserService;
  4. import org.springframework.jdbc.core.JdbcTemplate;
  5. import org.springframework.stereotype.Service;

  6. import javax.annotation.Resource;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. import java.util.List;
  10. import java.util.Map;

  11. @Service
  12. public class UserServiceImpl implements UserService {

  13. @Resource
  14. private JdbcTemplate jdbcTemplate;

  15. /**
  16. * 新增用户
  17. */
  18. @Override
  19. public User insert(User user) {
  20. jdbcTemplate.update("insert into t_user(name,password) values(?,?)", user.getName(), user.getPassword());
  21. return user;
  22. }

  23. /**
  24. * 通过用户名和密码查询用户
  25. */
  26. @Override
  27. public User queryByNameAndPassword(User user) {
  28. return jdbcTemplate.queryForObject("select id, name, password from t_user where name = ? and password = ?", this::mapRowToUser, user.getName(), user.getPassword());
  29. }

  30. /**
  31. * 查询用户列表
  32. */
  33. @Override
  34. public List<Map<String, Object>> queryAll() {
  35. return jdbcTemplate.queryForList("select id, name, password from t_user");
  36. }

  37. private User mapRowToUser(ResultSet rs, int rowNum) throws SQLException {
  38. return new User(rs.getLong("id"), rs.getString("name"), rs.getString("password"));
  39. }
  40. }

6.用户注册功能详解

从第4点UserController,我们可以看到用于注册的请求有:展示注册页面@GetMapping("/register")和完成注册@PostMapping("/register"),下面我们看看具体的html页面、service实现和JDBC的操作。

register.html

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  5. <title>注册</title>
  6. </head>
  7. <body>
  8. <form th:action="@{/user/register}" method="post">
  9. <div>
  10. <h2>帐号注册</h2>
  11. </div>
  12. <div>
  13. <!--/*@thymesVar id="error" type=""*/-->
  14. <span id="basic-addon0">&nbsp;</span>
  15. <span style="font-size: 12px;color: red" th:text="${error}" aria-describedby="basic-addon0"></span>
  16. <br />
  17. </div>
  18. <div>
  19. <span id="basic-addon1">用户名</span>
  20. <input id="user_name" name="name" type="text" placeholder="用户名" aria-describedby="basic-addon1" />

  21. </div>
  22. <br />
  23. <div>
  24. <span id="basic-addon2">密 码</span>
  25. <input id="password" name="password" type="password" placeholder="密 码" aria-describedby="basic-addon2" />
  26. </div>
  27. <br />
  28. <div>
  29. <button type="submit" style="width:190px;">注 册</button>
  30. </div>
  31. </form>
  32. </body>
  33. </html>

注册页面完成后,我们通过浏览器访问:http://localhost:8080/user/register,URL地址映射到@GetMapping("/register")方法

  1. /**
  2. *注册页面
  3. */
  4. @GetMapping("/register")
  5. public ModelAndView register(ModelAndView modelAndView){
  6. modelAndView.setViewName("register");
  7. return modelAndView;
  8. }

返回register.html页面,浏览器展示用户注册页面

在注册页面填写用户名和密码后,点击“注册”按钮。

由于register.html中,from的method=“POST”,所以“注册”按钮会映射到@PostMapping("/register")方法

  1. /**
  2. *注册
  3. */
  4. @PostMapping("/register")
  5. public ModelAndView register(ModelAndView modelAndView, @Valid UserVo userVo, BindingResult bindingResult){
  6. //校验参数
  7. if(bindingResult.hasErrors()){
  8. modelAndView.addObject("error",bindingResult.getFieldError().getDefaultMessage());
  9. modelAndView.setViewName("register");
  10. return modelAndView;
  11. }
  12. //注册
  13. User user = new User();
  14. user.setName(userVo.getUserName());
  15. user.setPassword(userVo.getPassword());
  16. userService.insert(user);
  17. //注册成功返回到登录页面
  18. modelAndView.setViewName("login");
  19. return modelAndView;
  20. }

通过@Valid注解打开了表单校验,所以如果有参数不符合开始声明的校验规则,会参数错误Errors。如果有参数错误,会返回注册页面,并显示错误。如果没有错误,将会调用UserService的insert方法

  1. /**
  2. * 新增用户
  3. */
  4. @Override
  5. public User insert(User user) {
  6. jdbcTemplate.update("insert into t_user(name,password) values(?,?)", user.getName(), user.getPassword());
  7. return user;
  8. }

这里就用到了spring封装的JdbcTemplate。要正常使用JDBC和访问数据库还需要做两件事:

1、引入JDBC依赖和mysql连接驱动依赖(这里使用最常用的mysql数据库)

  1. <!--JDBC-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-jdbc</artifactId>
  5. </dependency>
  6. <!--mysql驱动-->
  7. <dependency>
  8. <groupId>mysql</groupId>
  9. <artifactId>mysql-connector-java</artifactId>
  10. </dependency>

2、配置数据库连接

application.yml

  1. spring:
  2. datasource:
  3. username: root
  4. password: 123456
  5. url: jdbc:mysql://127.0.0.1:3306/spring_boot_topic
  6. driver-class-name: com.mysql.cj.jdbc.Driver

通过jdbcTemplate的update方法即可插入数据。

7.用户登录功能详解

从第4点UserController,我们可以看到用于注册的请求有:展示登录页面@GetMapping("/login")和完成登录@PostMapping("/login"),下面我们看看具体的html页面、service实现和JDBC的操作。

login.html

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  5. <title>登录</title>
  6. <!--<link rel="stylesheet" type="text/css" href="/css/common.css" />-->
  7. </head>
  8. <body>
  9. <div>
  10. <h2>用户登录</h2>
  11. </div>
  12. <form th:action="@{/user/login}" method="post">
  13. <div>
  14. <!--/*@thymesVar id="error" type=""*/-->
  15. <span id="basic-addon0">&nbsp;</span>
  16. <span style="font-size: 12px;color: red" th:text="${error}" aria-describedby="basic-addon0"></span>
  17. <br />
  18. </div>
  19. <div>
  20. <span id="basic-addon1">用户名</span>
  21. <input id="user_name" name="userName" type="text" placeholder="用户名" aria-describedby="basic-addon1" th:field="*{userName}"/>
  22. </div>
  23. <br />
  24. <div>
  25. <span id="basic-addon2">密 码</span>
  26. <input id="password" name="password" type="password" placeholder="密 码" aria-describedby="basic-addon2" th:field="*{password}"/>
  27. </div>
  28. <br />
  29. <div>
  30. <button type="submit" style="width:95px;">登 录</button>
  31. <a href="/user/register">注册</a>
  32. </div>
  33. </form>
  34. </body>
  35. </html>

我们通过浏览器访问:http://localhost:8080/user/login,进入到登录页面,URL地址映射到@GetMapping("/login")方法

  1. /**
  2. *登录页面
  3. */
  4. @GetMapping("/login")
  5. public ModelAndView login(ModelAndView modelAndView){
  6. modelAndView.setViewName("login");
  7. return modelAndView;
  8. }

返回login.html页面,浏览器展示用户登录页面

在登录页面填写用户名和密码后,点击“登录”按钮。

由于login.html中,from的method=“POST”,所以“注册”按钮会映射到@PostMapping("/login")方法

  1. /**
  2. *登录
  3. */
  4. @PostMapping("/login")
  5. public ModelAndView login(ModelAndView modelAndView,@Valid UserVo userVo, BindingResult bindingResult){
  6. //效验入参
  7. if(bindingResult.hasErrors()){
  8. modelAndView.addObject("error",bindingResult.getFieldError().getDefaultMessage());
  9. modelAndView.setViewName("login");
  10. return modelAndView;
  11. }
  12. //效验用户
  13. User user = new User();
  14. user.setName(userVo.getUserName());
  15. user.setPassword(userVo.getPassword());
  16. User rstUser = userService.queryByNameAndPassword(user);
  17. if(null == rstUser){
  18. modelAndView.addObject("error","用户名或密码错误!");
  19. modelAndView.setViewName("login");
  20. }
  21. //展示首页
  22. modelAndView.addObject("userName",rstUser.getName());
  23. modelAndView.setViewName("redirect:/user/index");
  24. return modelAndView;
  25. }

通过@Valid注解打开了表单校验,所以如果有参数不符合开始声明的校验规则,会参数错误Errors。如果有参数错误,会返回登录页面,并显示错误。如果没有错误,将会调用UserService的queryByNameAndPassword方法

  1. /**
  2. * 通过用户名和密码查询用户
  3. */
  4. @Override
  5. public User queryByNameAndPassword(User user) {
  6. return jdbcTemplate.queryForObject("select id, name, password from t_user where name = ? and password = ?", this::mapRowToUser, user.getName(), user.getPassword());
  7. }

  8. private User mapRowToUser(ResultSet rs, int rowNum) throws SQLException {
  9. return new User(rs.getLong("id"), rs.getString("name"), rs.getString("password"));
  10. }

通过jdbcTemplate的queryForObject方法即可查询到数据,然后重定向redirect到首页index.html。

  1. /**
  2. *首页
  3. */
  4. @GetMapping("/index")
  5. public ModelAndView index(ModelAndView modelAndView, HttpServletRequest request){
  6. modelAndView.addObject("userName",request.getParameter("userName"));
  7. modelAndView.setViewName("index");
  8. return modelAndView;
  9. }

inde.html

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  5. <title>登录</title>
  6. <!--<link rel="stylesheet" type="text/css" href="/css/common.css" />-->
  7. </head>
  8. <body>
  9. <div>
  10. <br />
  11. <span>欢迎你</span>
  12. <span style="font-size: 12px;color: black" th:text="${userName}" aria-describedby="basic-addon0"></span>
  13. </div>
  14. </body>
  15. </html>

登录成功界面

8.用户列表查询功能详解

从第4点UserController,我们可以看到用于用户列表查询的请求有:@GetMapping("/userList"),下面我们看看具体的html页面、service实现和JDBC的操作。

userList.html

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  5. <title>用户信息</title>
  6. <!--<link rel="stylesheet" type="text/css" href="/css/common.css" />-->
  7. <style type="text/css">
  8. table {
  9. border: 1px solid black;
  10. text-align: center;
  11. border-collapse: collapse;
  12. }
  13. table thead th {
  14. border: 1px solid black;
  15. }
  16. table tbody td {
  17. border: 1px solid black;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <div>
  23. <h2>用户列表</h2>
  24. </div>
  25. <table cellpadding="0" cellspacing="0">
  26. <thead>
  27. <th>序号</th>
  28. <th>编码</th>
  29. <th>用户名</th>
  30. </thead>
  31. <tbody>
  32. <tr th:each="entries,stat:${userList}" th:style="' color: rgb(17, 119, 0);">>
  33. <td th:text="${stat.count}"></td>
  34. <td th:text="${entries['id']}"></td>
  35. <td th:text="${entries['name']}"></td>
  36. <td th:text="${entries['sage']}"></td>
  37. </tr>
  38. </tbody>
  39. </table>
  40. </body>
  41. </html>

我们通过浏览器访问:http://localhost:8080/user/userList,进入到登录页面,URL地址映射到@GetMapping("/userList")方法

  1. /**
  2. * 查询用户列表
  3. */
  4. @GetMapping("/userList")
  5. public ModelAndView queryAll(ModelAndView modelAndView){
  6. //查询用户列表
  7. List<Map<String, Object>> userList = userService.queryAll();
  8. //返回
  9. modelAndView.addObject("userList", userList);
  10. modelAndView.setViewName("userList");
  11. return modelAndView;
  12. }

调用UserService的queryAll方法

  1. /**
  2. * 查询用户列表
  3. */
  4. @Override
  5. public List<Map<String, Object>> queryAll() {
  6. return jdbcTemplate.queryForList("select id, name, password from t_user");
  7. }

通过jdbcTemplate的queryForList方法即可查询到数据,然后返回到userList.html页面上。

总结

Spring对JDBC的支持主要是使用JdbcTemplate,虽然JdbcTemplate将创建连接、创建语句、关闭连接、关闭结果集和sql异常处理做了很好的封装,但是还有待完善。下一节我们再聊聊更简单的JPA。

三、spring boot开发web应用-使用传统的JDBC的更多相关文章

  1. 使用Spring Boot开发Web项目(二)之添加HTTPS支持

    上篇博客使用Spring Boot开发Web项目我们简单介绍了使用如何使用Spring Boot创建一个使用了Thymeleaf模板引擎的Web项目,当然这还远远不够.今天我们再来看看如何给我们的We ...

  2. Spring Boot开发Web应用之Thymeleaf篇

    前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Spring Boot提供了spring-boot-starter-web为Web开发予以 ...

  3. 使用Spring Boot开发Web项目

    前面两篇博客中我们简单介绍了Spring Boot项目的创建.并且也带小伙伴们来DIY了一个Spring Boot自动配置功能,那么这些东西说到底最终还是要回归到Web上才能体现出它的更大的价值,so ...

  4. Spring Boot开发Web应用

    静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /s ...

  5. Spring Boot开发Web应用之JSP篇

    前言 上一篇介绍了Spring Boot中使用Thymeleaf模板引擎,今天来介绍一下如何使用SpringBoot官方不推荐的jsp,虽然难度有点大,但是玩起来还是蛮有意思的. 正文 先来看看整体的 ...

  6. 天天玩微信,Spring Boot 开发私有即时通信系统了解一下

    1/ 概述 利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天. 2/ 所需依赖 Spring Boot 版本 ...

  7. Spring Boot 开发集成 WebSocket,实现私有即时通信系统

    1/ 概述 利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天. 2/ 所需依赖 Spring Boot 版本 ...

  8. 【spring boot】5.spring boot 创建web项目并使用jsp作前台页面

    贼烦的是,使用spring boot 创建web项目,然后我再idea下创建的,but 仅仅启动spring boot的启动类,就算整个项目都是好着的,就算是能够进入controller中,也不能成功 ...

  9. Spring Boot 开发微信公众号后台

    Hello 各位小伙伴,松哥今天要和大家聊一个有意思的话题,就是使用 Spring Boot 开发微信公众号后台. 很多小伙伴可能注意到松哥的个人网站(http://www.javaboy.org)前 ...

随机推荐

  1. 听说同学你搞不懂Java的LinkedHashMap,可笑

    先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题 ...

  2. Java中实现十进制数转换为二进制的三种方法

    第一种:除基倒取余法 这是最符合我们平时的数学逻辑思维的,即输入一个十进制数n,每次用n除以2,把余数记下来,再用商去除以2...依次循环,直到商为0结束,把余数倒着依次排列,就构成了转换后的二进制数 ...

  3. Jmeter 常用函数(3)- 详解 __RandomString

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 根据指定的字符产生一个随机字符串 语法 ...

  4. unsigned char printf 如何输出

    参考链接:https://blog.csdn.net/m0_37362454/article/details/88639668 #include <stdio.h> int main() ...

  5. python 多个装饰器的调用顺序分析

    一般情况下,在函数中可以使用一个装饰器,但是有时也会有两个或两个以上的装饰器.多个装饰器装饰的顺序是从里到外(就近原则),而调用的顺序是从外到里(就远原则) 样例: def func1(func): ...

  6. Spring Cloud Admin健康检查 邮件、钉钉群通知

    源码地址:https://github.com/muxiaonong/Spring-Cloud/tree/master/cloudadmin Admin 简介 官方文档:What is Spring ...

  7. Shell编程—创建函数

    1基本的脚本函数 函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用.要在脚本中使用该代码块时,只要使用所起的函数名就行了. 1.1创建函数 有两种格式可以用来在bash shell脚本中创建 ...

  8. 牛客网PAT练兵场-德才论

    题解:用sort排序即可 题目地址:https://www.nowcoder.com/questionTerminal/97b6a49a85944650b2e3d0660b91c324 /** * C ...

  9. Kafka工作流程

    Kafka生产过程分析 1 写入方式 producer采用推(push)模式将消息发布到broker,每条消息都被追加(append)到分区(patition)中,属于顺序写磁盘(顺序写磁盘效率比随机 ...

  10. python官网打不开

    这可能是因为该站点使用过期的或不安全的 TLS 安全设置. 解决:依次打开IE的Internet选项.高级,往下拉,找到安全模块,勾上四个使用:使用SSL 3.0.使用TLS 1.0.使用TLS 1. ...