当前位置: 首页 > news >正文

仿论坛项目--初识Spring Boot

1. 技术准备

技术架构

• Spring Boot
• Spring、Spring MVC、MyBatis
• Redis、Kafka、Elasticsearch
• Spring Security、Spring Actuator

开发环境

• 构建工具:Apache Maven
• 集成开发工具:IntelliJ IDEA
• 数据库:MySQL、Redis
• 应用服务器:Apache Tomcat
• 版本控制工具:Git
在这里插入图片描述

2. 搭建开发环境

Apache Maven
• 可以帮助我们构建项目、管理项目中的jar包
• Maven仓库:存放构件的位置

  • 本地仓库:默认是 ~/.m2/repository
  • 远程仓库:中央仓库、镜像仓库、私服仓库
    • 示例:安装、配置、常用命令
    http://maven.apache.org
    安装配置版本:apache-maven-3.6.1-bin.zip

改成阿里云的镜像仓库
在conf文件夹下修改settings.html

<mirror><id>alimaven</id><mirrorOf>central</mirrorOf><name>aliyun maven</name><url>https://maven.aliyun.com/repository/central</url>
</mirror>

配置好后在系统环境变量path上新建一条
E:\work\apache-maven-3.6.1-bin\apache-maven-3.6.1\bin

输入命令行:mvn -version 出现以下信息就是安装成功了。(首先要配置好JDK)
在这里插入图片描述

IntelliJ IDEA
• 目前最流行的Java集成开发工具
• 示例:安装、配置、创建项目
http://www.jetbrains.com/idea

Spring Initializr
• 创建 Spring Boot 项目的引导工具
• 示例:创建“论坛社区”项目
https://start.spring.io

Spring Boot 入门示例
• Spring Boot 核心作用

  • 起步依赖、自动配置、端点监控
    • 示例
  • 一个简单的处理客户端请求案例

@ResponseBody 是一个在 Spring 框架中常用的注解,主要用于 Web 层的控制器(Controller)方法上。它的主要功能是将方法的返回值直接写入 HTTP 响应的主体(Body)部分,而不是使用视图解析器(ViewResolver)生成视图。这意味着,当一个控制器方法被标注了 @ResponseBody,Spring 会将该方法的返回值转换成适合 HTTP 响应的内容类型,通常是 JSON 或 XML。

以下是 @ResponseBody 注解的一些关键点:

自动序列化:当方法的返回值是一个 Java 对象时,@ResponseBody 会使用一个合适的 HttpMessageConverter(如 MappingJackson2HttpMessageConverter 或 Jaxb2RootElementHttpMessageConverter)来将对象序列化为 JSON 或 XML 格式,具体取决于客户端请求头中的 Accept 字段或默认配置。避免视图渲染:在没有 @ResponseBody 的情况下,控制器方法的返回值通常会被视为视图名,然后通过视图解析器找到对应的视图模板进行渲染。但是,使用 @ResponseBody 后,这个流程被绕过,直接返回数据。支持多种数据类型:@ResponseBody 支持返回各种类型的数据,包括原始字符串、字节数组、基本数据类型、Java 对象等。对于非对象类型的简单数据,可以直接写入响应体;对于复杂对象,会进行序列化处理。AJAX 和 RESTful API:@ResponseBody 经常用于构建 AJAX 应用程序或 RESTful 服务,因为这些场景通常不需要完整的 HTML 页面作为响应,而是需要数据。

示例代码:

java

@RestController // 或者 @Controller + @ResponseBody 在类级别

public class MyController {

@GetMapping("/data")@ResponseBody // 也可以省略,因为类级别有 @RestControllerpublic MyData getData() {MyData data = new MyData();data.setValue("Hello, World!");return data;}

}

在这个示例中,getData() 方法的返回值 MyData 会被序列化成 JSON 格式(假设客户端请求接受 JSON),并直接写入 HTTP 响应的 Body 部分。

需要注意的是,@ResponseBody 通常与 @RestController 或 @Controller 结合使用,后者会应用于整个控制器类,意味着类中的所有方法都会默认使用 @ResponseBody 行为。如果某个方法不希望有这样的行为,可以在方法级别使用 @ModelAttribute 或直接返回一个 ModelAndView 对象。

3.Spring入门

Spring全家桶
• Spring Framework
• Spring Boot
• Spring Cloud
• Spring Cloud Data Flow
https://spring.io
在这里插入图片描述
Spring Framework
• Spring Core

  • IoC、AOP
    • Spring Data Access
  • Transactions、Spring MyBatis
    • Web Servlet
  • Spring MVC
    • Integration
  • Email、Scheduling、AMQP、Security

Spring IoC
• Inversion of Control

  • 控制反转,是一种面向对象编程的设计思想。
    • Dependency Injection
  • 依赖注入,是IoC思想的实现方式。
    • IoC Container
  • IoC容器,是实现依赖注入的关键,本质上是一个工厂。
    在这里插入图片描述
    Spring框架的IOC(Inversion of Control,控制反转)容器是其核心特性之一,它负责管理应用程序的组件和它们之间的依赖关系。IOC容器简化了组件的配置和管理,使得开发人员能够更专注于业务逻辑而非底层基础设施。

1. 控制反转 (Inversion of Control)

在传统的编程模式中,对象会主动地去创建依赖的实例或者从某个地方获取所需的实例,这种模式下,对象控制着依赖的创建和获取过程。而在控制反转中,这种控制权被“反转”了,对象不再控制依赖的创建和获取,而是由一个外部的容器(在Spring中就是IOC容器)来负责。对象只需要声明它所需要的依赖,剩下的工作都交给IOC容器来完成。

2. Spring的IOC容器

Spring框架提供了两种主要的IOC容器:

  • BeanFactory:这是最基本的IOC容器,它实现了BeanFactory接口。BeanFactory负责读取配置元数据,创建和管理bean以及处理bean之间的依赖注入。然而,BeanFactory并不提供按需加载和单例缓存等功能,这使得它在实际应用中不如ApplicationContext强大和方便。

  • ApplicationContext:这是一个高级的BeanFactory,它继承了BeanFactory的功能,并添加了更多的特性,比如国际化支持、事件发布机制、资源访问机制等。ApplicationContext是Spring推荐使用的容器,因为它提供了更多的企业级功能。

3. Bean的生命周期

在Spring中,bean的生命周期由容器控制。从bean的创建到销毁,Spring提供了多个回调方法,让开发者可以自定义bean的初始化和销毁逻辑。例如,你可以指定一个方法作为初始化方法,在bean创建完成后立即调用;同样,也可以指定一个销毁方法,在容器关闭时调用。

4. 依赖注入 (Dependency Injection)

依赖注入是IOC的一个重要实现方式,它允许在运行时将依赖关系注入到对象中,而不是在编译时就确定。Spring支持三种依赖注入方式:

  • 构造器注入:依赖通过构造函数传入。
  • 属性注入:依赖通过setter方法设置。
  • 字段注入:依赖直接注入到字段中,通常使用@Autowired注解。

5. 配置元数据

Spring的配置元数据可以通过XML文件、注解或Java配置类来提供。这些元数据描述了bean的定义、依赖关系以及配置信息,IOC容器会读取这些元数据来创建和装配bean。

Spring的IOC容器通过控制反转和依赖注入,使得应用程序的结构更加松耦合,提高了代码的可测试性和可维护性。

@EnableAutoConfiguration:自动配置,不用人工配置也能够启动服务
@ComponentScan:自动扫描,自动装配bean(扫描配置所在的包以及子包的bean)。还要有@controller和@service注解,@repository,@component才会被扫描

4.Spring MVC入门

HTTP

• HyperText Transfer Protocol
• 用于传输HTML等内容的应用层协议
• 规定了浏览器和服务器之间如何通信,以及通信时的数据格式。
https://www.ietf.org
https://developer.mozilla.org/zh-CN
在这里插入图片描述HTTP请求是客户端(通常是浏览器)向服务器发送的一种请求,以获取或操作资源。HTTP请求有两种主要类型:GET和POST。

GET请求:用于从服务器检索信息。信息在URL中可见,且有长度限制。GET请求可以被缓存,保留在浏览历史中,并在浏览器的"后退"按钮中保留。

POST请求:用于向服务器发送数据,通常用于表单提交。数据在请求体中发送,不显示在URL中,且没有长度限制。POST请求不会被缓存,也不会保留在浏览器的历史记录中。

三层架构(面试)

  • 表现层、业务层、数据访问层
    • MVC

  • Model:模型层

  • View:视图层

  • Controller:控制层
    • 核心组件

  • 前端控制器:DispatcherServlet
    在这里插入图片描述MVC,全称为Model-View-Controller,是一种广泛使用的软件架构模式,主要用于开发易于维护和修改的用户界面。MVC将应用程序分为三个核心组成部分:

    Model(模型):模型负责管理应用程序的数据逻辑,以及对数据的存储、读取和更新等操作。它是应用程序的核心,独立于任何用户界面。模型直接与数据打交道,当数据发生变化时,它会通知视图和控制器。

    View(视图):视图负责展示模型中的数据给用户,它是用户看到并交互的界面。视图从模型获取数据,然后以某种形式展示出来。当模型数据改变时,视图也会自动更新。

    Controller(控制器):控制器是模型和视图之间的协调者,它接收用户的输入并调用模型和视图去完成用户的需求。控制器处理用户请求,控制应用程序的流程,并决定使用哪个视图来展示数据。

MVC模式的主要优点包括:

提高了代码的复用性和可维护性。
分离了关注点,使得每个部分都专注于其核心功能,简化了开发和测试。
支持多个视图共享同一模型,使得数据可以在不同的界面展示。
控制器可以处理来自不同视图的请求,提高了程序的灵活性。

DispatcherServlet是Spring MVC框架中的核心组件,它扮演着前端控制器的角色。在Spring MVC架构中,所有的HTTP请求首先都会被转发到DispatcherServlet。它的主要职责包括:

初始化上下文:加载配置文件,初始化HandlerMapping、HandlerAdapter、ViewResolver等组件。请求分发:接收HTTP请求,通过HandlerMapping找到合适的处理器(Controller中的方法),并将其与请求映射起来。处理请求:调用相应的处理器处理请求。处理器处理完请求后,返回一个ModelAndView对象,其中包含了要渲染的视图名和模型数据。解析视图:通过ViewResolver找到具体的视图组件,将ModelAndView中的模型数据填充到视图中,生成最终的响应结果。生成响应:将视图渲染的结果返回给客户端。

DispatcherServlet的工作流程如下:

客户端发送HTTP请求到服务器,请求会被转发到DispatcherServlet。
DispatcherServlet根据请求的URL找到对应的HandlerMapping,从而确定处理该请求的Controller和方法。
DispatcherServlet调用HandlerAdapter执行Controller的方法。
Controller处理完请求后,返回一个ModelAndView对象给DispatcherServlet。
DispatcherServlet使用ViewResolver找到具体的视图组件,并将ModelAndView中的数据填充到视图中。
最终,视图渲染的结果被DispatcherServlet包装成HTTP响应,返回给客户端。

通过DispatcherServlet,Spring MVC能够很好地实现MVC模式,将业务逻辑、数据处理和视图渲染分离,提高代码的可读性和可维护性。
在这里插入图片描述
Thymeleaf
• 模板引擎

  • 生成动态的HTML。
    • Thymeleaf
  • 倡导自然模板,即以HTML文件为模板。
    • 常用语法
  • 标准表达式、判断与循环、模板的布局。
    https://www.thymeleaf.org
    在这里插入图片描述

相关代码:

package com.nowcoder.community.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;

@Configuration
public class AlphaConfig {

@Bean
public SimpleDateFormat simpleDateFormat() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}

}

package com.nowcoder.community.controller;

import com.nowcoder.community.service.AlphaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

@Controller
@RequestMapping(“/alpha”)
public class AlphaController {

@Autowired
private AlphaService alphaService;@RequestMapping("/hello")
@ResponseBody
public String sayHello() {return "Hello Spring Boot.";
}@RequestMapping("/data")
@ResponseBody
public String getData() {return alphaService.find();
}@RequestMapping("/http")
public void http(HttpServletRequest request, HttpServletResponse response) {// 获取请求数据System.out.println(request.getMethod());System.out.println(request.getServletPath());Enumeration<String> enumeration = request.getHeaderNames();while (enumeration.hasMoreElements()) {String name = enumeration.nextElement();String value = request.getHeader(name);System.out.println(name + ": " + value);}System.out.println(request.getParameter("code"));// 返回响应数据response.setContentType("text/html;charset=utf-8");try (PrintWriter writer = response.getWriter();) {writer.write("<h1></h1>");} catch (IOException e) {e.printStackTrace();}
}// GET请求// /students?current=1&limit=20
@RequestMapping(path = "/students", method = RequestMethod.GET)
@ResponseBody
public String getStudents(@RequestParam(name = "current", required = false, defaultValue = "1") int current,@RequestParam(name = "limit", required = false, defaultValue = "10") int limit) {System.out.println(current);System.out.println(limit);return "some students";
}// /student/123
@RequestMapping(path = "/student/{id}", method = RequestMethod.GET)
@ResponseBody
public String getStudent(@PathVariable("id") int id) {System.out.println(id);return "a student";
}// POST请求
@RequestMapping(path = "/student", method = RequestMethod.POST)
@ResponseBody
public String saveStudent(String name, int age) {System.out.println(name);System.out.println(age);return "success";
}// 响应HTML数据@RequestMapping(path = "/teacher", method = RequestMethod.GET)
public ModelAndView getTeacher() {ModelAndView mav = new ModelAndView();mav.addObject("name", "张三");mav.addObject("age", 30);mav.setViewName("/demo/view");return mav;
}@RequestMapping(path = "/school", method = RequestMethod.GET)
public String getSchool(Model model) {model.addAttribute("name", "北京大学");model.addAttribute("age", 80);return "/demo/view";
}// 响应JSON数据(异步请求)
// Java对象 -> JSON字符串 -> JS对象

异步请求是一种在网络编程和Web开发中常见的技术,它允许在不阻塞主线程的情况下发送HTTP请求并处理响应。与同步请求相比,异步请求不会暂停程序的执行等待响应,而是继续执行后续的代码,直到响应到达后再处理结果。这种非阻塞的特性对于提高用户体验和程序响应速度至关重要,特别是在处理耗时的网络操作时。

异步请求的优点

提高应用性能:异步请求可以让应用在等待网络响应的同时执行其他任务,避免了长时间的等待导致的UI冻结或程序卡顿。改善用户体验:在Web应用中,用户可以继续与页面交互,即使某些数据正在后台加载。资源高效利用:异步处理可以更有效地利用系统资源,避免线程在等待I/O操作时处于空闲状态。@RequestMapping(path = "/emp", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getEmp() {Map<String, Object> emp = new HashMap<>();emp.put("name", "张三");emp.put("age", 23);emp.put("salary", 8000.00);return emp;
}@RequestMapping(path = "/emps", method = RequestMethod.GET)
@ResponseBody
public List<Map<String, Object>> getEmps() {List<Map<String, Object>> list = new ArrayList<>();Map<String, Object> emp = new HashMap<>();emp.put("name", "张三");emp.put("age", 23);emp.put("salary", 8000.00);list.add(emp);emp = new HashMap<>();emp.put("name", "李四");emp.put("age", 24);emp.put("salary", 9000.00);list.add(emp);emp = new HashMap<>();emp.put("name", "王五");emp.put("age", 25);emp.put("salary", 10000.00);list.add(emp);return list;
}

}

package com.nowcoder.community.dao;

import org.springframework.stereotype.Repository;

@Repository(“alphaHibernate”)
public class AlphaDaoHibernateImpl implements AlphaDao {
@Override
public String select() {
return “Hibernate”;
}
}

package com.nowcoder.community.dao;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

@Repository
@Primary
public class AlphaDaoMyBatisImpl implements AlphaDao{
@Override
public String select() {
return “MyBatis”;
}
}

package com.nowcoder.community.service;

import com.nowcoder.community.dao.AlphaDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Service
//@Scope(“prototype”)
public class AlphaService {

@Autowired
private AlphaDao alphaDao;public AlphaService() {System.out.println("实例化AlphaService");
}@PostConstruct
public void init() {System.out.println("初始化AlphaService");
}@PreDestroy
public void destroy() {System.out.println("销毁AlphaService");
}public String find() {return alphaDao.select();
}

}

package com.nowcoder.community;

import com.nowcoder.community.dao.AlphaDao;
import com.nowcoder.community.service.AlphaService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.text.SimpleDateFormat;
import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class CommunityApplicationTests implements ApplicationContextAware {

private ApplicationContext applicationContext;@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;
}@Test
public void testApplicationContext() {System.out.println(applicationContext);AlphaDao alphaDao = applicationContext.getBean(AlphaDao.class);System.out.println(alphaDao.select());alphaDao = applicationContext.getBean("alphaHibernate", AlphaDao.class);System.out.println(alphaDao.select());
}@Test
public void testBeanManagement() {AlphaService alphaService = applicationContext.getBean(AlphaService.class);System.out.println(alphaService);alphaService = applicationContext.getBean(AlphaService.class);System.out.println(alphaService);
}@Test
public void testBeanConfig() {SimpleDateFormat simpleDateFormat =applicationContext.getBean(SimpleDateFormat.class);System.out.println(simpleDateFormat.format(new Date()));
}@Autowired
@Qualifier("alphaHibernate")
private AlphaDao alphaDao;@Autowired
private AlphaService alphaService;@Autowired
private SimpleDateFormat simpleDateFormat;@Test
public void testDI() {System.out.println(alphaDao);System.out.println(alphaService);System.out.println(simpleDateFormat);
}

}

增加学生
<form method="post" action="/community/alpha/student"><p>姓名: <input type="text" name="name"></p><p>年龄: <input type="text" name="age"></p><p><input type="submit" value="保存"></p>
</form>
Teacher

application
ServerProperties
server.port=8080
server.servlet.context-path=/community

ThymeleafProperties
spring.thymeleaf.cache=false

MyBatis入门

安装数据库
• 安装MySQL Server
• 安装MySQL Workbench
https://dev.mysql.com/downloads/mysql
https://dev.mysql.com/downloads/workbench

下载解压后,添加my.ini文件
在这里插入图片描述
[mysql]
default-character-set=utf8
[mysqld]
port=3306
basedir=E:\work\mysql-8.0.38-winx64\mysql-8.0.38-winx64(修改为MySQL的路径)
max_connections=20
character-set-server=utf8
default-storage-engine=INNODB

然后在系统变量path里配置环境变量
E:\work\mysql-8.0.38-winx64\mysql-8.0.38-winx64\bin

以管理员身份运行cmd
cd E:\work\mysql-8.0.38-winx64\mysql-8.0.38-winx64\bin

mysqld --initialize --console(保存好数据库密码password!!!)
A temporary password is generated for root@localhost: ixNM&0%99Crt
mysqld --install

在这里插入图片描述在这里插入图片描述得在管理员身份运行才能建表成功
MySQL服务启动失败,检查是否是端口号冲突!!!!

MyBatis

• 核心组件

  • SqlSessionFactory:用于创建SqlSession的工厂类。
  • SqlSession:MyBatis的核心组件,用于向数据库执行SQL。
  • 主配置文件:XML配置文件,可以对MyBatis的底层行为做出详细的配置。
  • Mapper接口:就是DAO接口,在MyBatis中习惯性的称之为Mapper。
  • Mapper映射器:用于编写SQL,并将SQL和实体类映射的组件,采用XML、注解均可实现。
    • 示例
  • 使用MyBatis对用户表进行CRUD操作。
    http://www.mybatis.org/mybatis-3
    http://www.mybatis.org/spring

到maven repository官网搜索MySQL复制依赖

com.mysql mysql-connector-j 8.0.33

继续搜索mybatis

org.mybatis.spring.boot mybatis-spring-boot-starter 3.0.3

package com.nowcoder.community;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class MapperTests {

@Autowired
private UserMapper userMapper;@Test
public void testSelectUser() {User user = userMapper.selectById(101);System.out.println(user);user = userMapper.selectByName("liubei");System.out.println(user);user = userMapper.selectByEmail("nowcoder101@sina.com");System.out.println(user);
}@Test
public void testInsertUser() {User user = new User();user.setUsername("test");user.setPassword("123456");user.setSalt("abc");user.setEmail("test@qq.com");user.setHeaderUrl("http://www.nowcoder.com/101.png");user.setCreateTime(new Date());int rows = userMapper.insertUser(user);System.out.println(rows);System.out.println(user.getId());
}@Test
public void updateUser() {int rows = userMapper.updateStatus(150, 1);System.out.println(rows);rows = userMapper.updateHeader(150, "http://www.nowcoder.com/102.png");System.out.println(rows);rows = userMapper.updatePassword(150, "hello");System.out.println(rows);
}

}

application
#ServerProperties
server.port=8080
server.servlet.context-path=/community

#ThymeleafProperties
spring.thymeleaf.cache=false

#DataSourceProperties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000

#MybatisProperties
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.nowcoder.community.entity
mybatis.configuration.useGeneratedKeys=true
mybatis.configuration.mapUnderscoreToCamelCase=true

#logger
logging.level.com.nowcoder.community=debug

user-mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<sql id="insertFields">username, password, salt, email, type, status, activation_code, header_url, create_time
</sql><sql id="selectFields">id, username, password, salt, email, type, status, activation_code, header_url, create_time
</sql><select id="selectById" resultType="User">select <include refid="selectFields"></include>from userwhere id = #{id}
</select><select id="selectByName" resultType="User">select <include refid="selectFields"></include>from userwhere username = #{username}
</select><select id="selectByEmail" resultType="User">select <include refid="selectFields"></include>from userwhere email = #{email}
</select><insert id="insertUser" parameterType="User" keyProperty="id">insert into user (<include refid="insertFields"></include>)values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})
</insert><update id="updateStatus">update user set status = #{status} where id = #{id}
</update><update id="updateHeader">update user set header_url = #{headerUrl} where id = #{id}
</update><update id="updatePassword">update user set password = #{password} where id = #{id}
</update>

相关文章:

  • 网络爬虫基础知识
  • RealMAN:大规模真实录制且经过注释的麦克风阵列数据集
  • Linux常用指令汇总
  • Perl语言入门指南
  • 【MindSpore学习打卡】应用实践-计算机视觉-ShuffleNet图像分类:从理论到实践
  • 使用tkinter拖入excel文件并显示
  • 大数据面试题之Kafka(4)
  • Rocky Linux 9 快速安装docker 教程
  • (原创)可支持最大高度的NestedScrollView
  • STM32——使用TIM输出比较产生PWM波形控制舵机转角
  • Ubuntu20.04 64位 安装docker(有问题可评论沟通交流)
  • 【PHP】实现类的无缝动态扩展,设计模式,php工厂模式应用场景,以下代码是工厂模式在框架设计中的真实使用案例代码
  • No port is available from the preconfigured port range
  • 华为DCN之:SDN和NFV
  • day09了 加油
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 230. Kth Smallest Element in a BST
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • CSS 三角实现
  • C语言笔记(第一章:C语言编程)
  • Koa2 之文件上传下载
  • uni-app项目数字滚动
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 机器学习 vs. 深度学习
  • 悄悄地说一个bug
  • 如何编写一个可升级的智能合约
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​Spring Boot 分片上传文件
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • $nextTick的使用场景介绍
  • (0)Nginx 功能特性
  • (1)虚拟机的安装与使用,linux系统安装
  • (C++20) consteval立即函数
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (poj1.3.2)1791(构造法模拟)
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (四)模仿学习-完成后台管理页面查询
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET Core 2.1路线图
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET MVC 验证码
  • ?
  • ??在JSP中,java和JavaScript如何交互?
  • @Resource和@Autowired的区别