后端开发资料讲解以及技术分享-SpringBoot

1 篇文章 0 订阅
1 篇文章 0 订阅

1、开发框架

1.1 SpringBoot

1.1.1 背景与简介
  • J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大

  • Spring Boot是整个Spring技术栈的一个大整合,用来简化Spring应用开发,遵从约定大于配置, 去繁从简,只要点击运行就能创建一个独立的,产品级别的应用。,其实它不是什么新的框架,它只是默认配置了很多框架的使用方式

1.1.2 优点
  • 快速创建独立运行的Spring项目以及与主流框架集成
  • 使用嵌入式的Servlet容器,应用无需打成WAR包
  • 提供各种’starters’自动依赖与版本控制
  • 大量的自动配置,简化开发,也可修改默认值
  • 无需配置XML,无代码生成,开箱即用
  • 提供准生产环境的运行时应用监控
  • 与云计算的天然集成
1.1.3 HelloWorld示例

功能:浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串
说明:本示例程序采用IntelliJ IDEA进行开发,仅供参考

  1. 使用IDEA创建Maven项目HelloWorld,完成后打开项目根目录下的pom.xml文件,在标签域中添加如下代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>HelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

如果第一次使用Maven可能要稍等一会,项目会向远程仓库下载配置依赖中相关JAR包。

  1. 在项目的src/main/java下创建java类com.test. controller.HelloWorldController,代码如下:
package com.test.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
    @RequestMapping("/hello")
    public String hello() {
        return "hello world!";
    }
}
  1. 在项目的src/main/java下创建java类com.test. HelloWorldMainApplication,代码如下:
package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloWorldMainApplication {
    public static void main(String[] args){
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}
  1. 直接点击main方法左边的绿色三角形按钮即可运行项目
    在这里插入图片描述
  2. 项目启动后打开浏览器,在地址栏输入http://localhost:8080/hello,按下回车,就可以在浏览器中看到Hello World!了,这样一个最简单的SpringBoot应用就创建成功了,这也许是目前为止创建Web应用最简单的方法了
    在这里插入图片描述
1.1.4 HelloWorld简要分析
  1. pom文件中的父项目
    在pom文件中按住CTRL鼠标左键点击父项目可打开一个文件,看到下面的代码:
<parent>
 	<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-dependencies</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
  • 这个项目是Spring Boot的版本仲裁中心,用来管理Spring Boot应用里面的所有依赖版本
  • 以后我们导入依赖默认是不需要写版本号。(没有在dependencies里面管理的依赖自然需要声明版本号)
  1. 启动器starter
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • spring-boot-starter-web:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件
  • Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter,相关场景的所有依赖都会导入进来,要用什么功能就导入什么场景的启动器,SpringBoot的启动器可以参考官方文档进行查看
  1. 主程序类HelloWorldMainApplication
    在这里插入图片描述
  • @SpringBootApplication: SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用
1.1.5 读取参数

当前台传参数给后台时,后台需要能够准确的接受并进行处理。

  1. 简单类型
    功能:字符串类型的userName作为参数将被hello方法接受并输出hello和userName连接后的字符串到前台
@RequestMapping("/hello")
public String hello(String userName) {
    return "hello " + userName + "!";
}

  前台请求:http://localhost:8080/hello?userName=SpringBoot
在这里插入图片描述
  方法会自动接受名称相同参数的值赋给自己,若名称不同可使用@RequestParam注解进行参数说明,也可以达到相同的效果

@RequestMapping("/hello")
public String hello(@RequestParam("userName") String name) {
	return "hello " + name + "!";
}
  1. 复杂类型
    若传入的参数是一个对象,如一个用户对象信息,则需要先创建用户实体类User.java,代码如下:
package com.test.model;
import java.util.List;
import java.util.Map;

public class User {
    private int userId;
    private String userName;
    private String password;
    private List<String> phoneNum;
    private List<Map<Integer,String>> event;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<String> getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(List<String> phoneNum) {
        this.phoneNum = phoneNum;
    }
    public List<Map<Integer, String>> getEvent() {
        return event;
    }
    
    public void setEvent(List<Map<Integer, String>> event) {
        this.event = event;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", phoneNum=" + phoneNum +
                ", event=" + event +
                '}';
    }
}

  然后修改HelloWorldController:
  在hello的参数上需要加上@RequestBody用来将传入的Json数据转换为对象中属性的值,在下面的hello程序将接受输入的user参数并将user.toString()后输出给前端。

@RequestMapping("/hello")
public String hello(@RequestBody User user) {
	return "hello " + user.toString();
}

  最后进行测试:
  使用工具:Postman
  请求地址:http://localhost:8080/hello
  请求方法:Post,application/json
  请求参数如下:

{
	"userId": "1",
	"userName": "jack",
	"password": "123456",
	"phoneNum": ["213123","2312312"],
	"event": [
		{"1": "1年级"},
		{"2": "2年级"},
		{"3": "3年级"}
	]
}

  返回结果:

hello User{userId=1, userName='jack', password='123456', 
phoneNum=[213123, 2312312], event=[{1=1年级}, {2=2年级}, {3=3年级}]}
1.1.6 数据校验

功能:后台对于前台输入的数据往往需要进行校验是否符合规则。

  1. 基本类型参数校验
  • 首先在HelloWorldController类上加上@Validated注解,表示开启数据校验,添加在类上用于校验方法,添加在方法参数中用于校验参数对象
    在这里插入图片描述
  • 然后在参数前面写上校验规则并且该方法抛出异常
@RequestMapping("/hello1")
public String hello1(@NotBlank(message = "用户名字不能为空")
    @Length(min = 2, max = 10, message = "用户名长度必须在 2 - 10 之间")
    @RequestParam("userName") String userName) throws Exception {
	return "hello "+ userName;
}
  • 接下来写一个全局的异常处理程序com.test.exception.GlobalExceptionHandler用于输出校验结果
package com.test.exception;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResponseEntity<String> constraintViolationExceptionHandler(ConstraintViolationException e) {
        return ResponseEntity.badRequest().body(e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessageTemplate)
                .findFirst()
                .orElse(e.getMessage())
        );
    }
}
  • 最后在浏览器中输入请求后的校验结果如下:
    在这里插入图片描述
    在这里插入图片描述
    2、对象类型参数校验:
  • 首先在方法的参数前面加上@Validated注解,并在该方法中加入bindingResult参数用于接受校验信息。
@RequestMapping("/hello")
public String hello(@Validated @RequestBody User user,
						BindingResult bindingResult) {
	if(bindingResult.hasErrors()) {
		return bindingResult.getAllErrors().get(0).getDefaultMessage();
	}
	return "hello "+user.toString();
}
  • 然后在实体类需要校验的参数上面加上校验注解:
public class User {
    private int userId;

    @NotBlank(message = "用户名字不能为空")
    @Length(min = 2, max = 10, message = "用户名长度必须在 {min} - {max} 之间")
    private String userName;

    private String password;
    private List<String> phoneNum;
    private List<Map<Integer,String>> event;
  • 最后运行程序使用Postman发请求得到校验结果:
    请求URL地址:http://localhost:8080/hello
    请求方法:Post,application/json
    请求参数1:
{
	"userId": "1",
	"password": "123456",
	"phoneNum": ["213123","2312312"],
	"event": [
		{"1": "1年级"},
		{"2": "2年级"},
		{"3": "3年级"}
	]
}

  校验结果1:

用户名字不能为空

  请求参数2:

{
	"userId": "1",
	"userName": "r12312312321321",
	"password": "123456",
	"phoneNum": ["213123","2312312"],
	"event": [
		{"1": "1年级"},
		{"2": "2年级"},
		{"3": "3年级"}
	]
}

  校验结果2:

用户名长度必须在 2 - 10 之间

1.2 MyBatis

1.2.1 简介
  • MyBatis 是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射
  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
1.2.2 特性
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件和配置几个SQL映射文件,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现
  • 灵活,MyBatis不会对应用程序或者数据库的现有设计强加任何影响
  • SQL写在xml里,便于统一管理和优化。通过SQL语句可以满足操作数据库的所有需求
  • 解除SQL与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL和代码的分离,提高了可维护性
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态SQL
1.2.3 与SpringBoot的整合使用

在SpringBoot应用中使用MyBatis作为与数据库相关的持久层框架,该示例将演示两个简单例子,分别为向数据库中添加数据和前台查询并显示数据库中的数据。
该示例使用MySql数据库,仅供参考。

  1. 在pom文件中添加jdbc相关依赖、mysql驱动和mybatis依赖包
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.4</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>
  1. 在src/main/resources目录下创建application.yml配置文件,配置与数据连接的相关数据和声明mybatis配置的路径
spring:
 # 数据源配置信息根据自己的数据库而定
 datasource:
  username: root
  password: root
  url: jdbc:mysql://localhost:3306/test
  driver‐class‐name: com.mysql.jdbc.Driver

mybatis:
 config-location: classpath:mybatis/mybatis.xml
 mapper-locations: classpath:mybatis/mapper/**/*.xml
  1. 在src/main/resources/mybatis目录下创建mybatis.xml配置文件
<?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="cacheEnabled" value="true" />
        <setting name="lazyLoadingEnabled" value="true" />
        <setting name="aggressiveLazyLoading" value="true" />
        <setting name="multipleResultSetsEnabled" value="true" />
        <setting name="useColumnLabel" value="true" />
        <setting name="useGeneratedKeys" value="true" />
        <setting name="autoMappingBehavior" value="PARTIAL" />
        <setting name="defaultExecutorType" value="SIMPLE" />
        <setting name="defaultStatementTimeout" value="3000" />
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
</configuration>
  1. 在test数据库下创建用户表user
create table `user` (
	`user_id` bigint(20) not null auto_increment,
	`user_name` varchar(255) default null,
	`password` varchar(255) default null,
	primary key (`user_id`)
)
  1. 在src/main/java/com/test/mapper下创建mapper接口UserMapper.java
package com.test.mapper;

import com.test.model.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {
    int addUser(User user);
    List<User> getUserInfo();
    User getUserById(@Param("userId") int userId);
}
  1. 在src/main/resources/mybatis/mapper下创建sql映射文件userMapper.xml,其中每个sql语句的id和mapper接口UserMapper.java中的方法名相同。
<?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.test.mapper.UserMapper">

    <!-- 结果集映射 -->
    <resultMap id="userResultMap" type="com.test.model.User">
        <result column="user_id" property="userId" />
        <result column="user_name" property="userName" />
        <result column="password" property="password" />
    </resultMap>

    <select id="getUserInfo" resultMap="userResultMap">
        select user_id, user_name, password from user
    </select>

    <select id="getUserById" resultMap="userResultMap">
        select user_id, user_name, password
        from user where user_id=#{userId}
    </select>
    
    <insert id="addUser" parameterType="com.test.model.User"
            useGeneratedKeys="true" keyProperty="userId">
        insert into user(user_name, password)
        value(#{userName}, #{password})
    </insert>
</mapper>
  1. 在应用的主程序类上加注解@MapperScan(“com.test.mapper”),表示将自动扫描mapper接口。
@MapperScan("com.test.mapper")
@SpringBootApplication
public class HelloWorldMainApplication {
    public static void main(String[] args){
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}
  1. 在HelloWorldController中加入如下代码进行测试:
@RequestMapping("/user/addUser")
public int addUser(@RequestBody User user){
    return userMapper.addUser(user);
}

@RequestMapping("/user/getUserInfo")
public List<User> getUserInfo(){
    return userMapper.getUserInfo();
}

@RequestMapping("/user/getUserById")
public User getUserInfo(int userId){
    return userMapper.getUserById(userId);
}
  1. 首先使用Postman调用addUser方法添加两个用户:
    请求链接:http://localhost:8080/user/addUser
    请求参数(用下面两个参数分别请求两次):
    参数1:
{
    "userName": "jack",
    "password": "123456"
}

  参数2:

{
    "userName": "mary",
    "password": "ABCDEFG"
}

  执行完车后查看数据库中的信息,可以看到数据被成功插入进数据库了:

SELECT * FROM `user`
userId  userName  paaword  
------  --------  ---------
     1  jack      123456   
     2  mary      ABCDEFG  
  1. 调用getUserInfo和getUserById方法在浏览器中查看用户信息:
    浏览器请求:http://localhost:8080/user/getUserInfo
    将会得到下面的结果:
[
  {
    "userId": 1,
    "userName": "jack",
    "password": "123456",
    "phoneNum": null,
    "event": null
  },
  {
    "userId": 2,
    "userName": "mary",
    "password": "ABCDEFG",
    "phoneNum": null,
    "event": null
  }
]

  浏览器请求:http://localhost:8080/user/getUserById?userId=2
  将会得到下面的结果:

{
  "userId": 2,
  "userName": "mary",
  "password": "ABCDEFG",
  "phoneNum": null,
  "event": null
}

  到此一个简单的SpringBoot应用和MyBatis的整合就完成了。

1.2.4 MyBatis映射文件探究
  1. 插入数据后自动生成主键赋予传入参数中的主键字段
useGeneratedKeys="true" keyProperty="userId"
<insert id="addUser" parameterType="com.test.model.User"
        useGeneratedKeys="true" keyProperty="userId">
    insert into user(userName, password)
    value(#{userName}, #{password})
</insert>

在插入一个user后会把user中的userId字段设置成插入数据库中主键。
修改HelloWorldController中的addUser方法,使得方法的返回值是新插入用户的id:

    @RequestMapping("/user/addUser")
    public int addUser(@RequestBody User user){
        userMapper.addUser(user);
        return user.getUserId();
    }

重新运行程序后使用postman发送请求http://localhost:8080/user/addUser
请求参数:

{
    "userName": "tom",
    "password": "@#$%%^^&**"
}

结果:
在这里插入图片描述
2. 参数传入

  • 单个参数
    可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数,不需要经过任何处理。
    如在userMapper.xml中直接使用user对象中的属性:
    int addUser(User user);
    
    <insert id="addUser" parameterType="com.test.model.User"
           useGeneratedKeys="true" keyProperty="userId">
           insert into user(userName, password)
           value(#{userName}, #{password})
    </insert>
    
  • 多个参数
    任意多个参数,都会被MyBatis重新包装成一个Map传入。Map的key是param1,param2…,值就是参数的值。

  在UserMapper.java中添加根据用户名和密码获取用户信息的方法

User getUserByNameAndPsd(String userName, String password);

  在userMapper.xml中添加SQL

<select id="getUserByNameAndPsd" resultMap="userResultMap">
    select user_id, user_name, password from `user`
    where user_name=#{param1} and password=#{param2}
</select>

  #{param1}的值就是传入的userName,#{param2}的值就是传入的password
  最后在HelloWorldController.java中添加代码进行请求测试

@RequestMapping("user/getUserInfoByNameAndPsd")
public User getUserInfo(String userName, String password) {
    return userMapper.getUserByNameAndPsd(userName, password);
}

  运行程序后使用post请求:http://localhost:8080/user/getUserInfoByNameAndPsd?userName=jack&password=123456
  输出结果为:
在这里插入图片描述
  #{param1}和#{param2}亦可以换成#{arg0}和#{arg1},结果相同

  • 命名参数
    为参数使用@Param起一个名字,MyBatis就会将这些参数封装进map中,key就是我们自己指定的名字
    为上面的方法getUserByNameAndPsd添加命名参数
User getUserByNameAndPsd(@Param("userName") String userName,
                         @Param("password") String password);

  修改userMapper.xml中的SQL

<select id="getUserByNameAndPsd" resultMap="userResultMap">
    select user_id, user_name, password from `user`
    where user_name=#{userName} and password=#{password}
</select>

  重新运行程序后可得到和上面相同的结果

  • POJO
    当这些参数属于我们业务POJO时,我们直接传递POJO
  • Map
    我们也可以封装多个参数为map,直接传递
  1. 参数处理
    #{key}:获取参数的值,预编译到SQL中,安全。
    ${key}:获取参数的值,直接拼接到SQL中。有SQL注入问题。
    #{userName}, #{password}
    
  2. 结果返回
    对于简单类型的数据直接返回,复杂类型可自定义resultMap进行接收。resultMap将查询的结果与POJO中的属性对于起来,这样在执行完SQL后就可以在POJO中得到结果。
    使用自定义的resultMap作为结果,将在数据库中查询结果的列名和对象属性名进行一一映射
     <resultMap id="userResultMap" type="com.test.model.User">
         <result column="user_id" property="userId" />
         <result column="user_name" property="userName" />
         <result column="password" property="password" />
     </resultMap>
    

  resultMap还支持继承、定义数组、结果集嵌套和分步查询等
  假设现在我们需要在查询用户信息结果中添加用户号码信息,我们需要将用户的电话号码信息保存到数据库中,为此在数据库中创建电话表并且插入数据:

CREATE TABLE `phone` (
  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` BIGINT(20) UNSIGNED DEFAULT NULL,
  `phone_num` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO phone(user_id, phone_num) 
VALUES
(1,'123456789'),
(1,'14567'),
(1,'213123'),
(2,'123213'),
(2,'33256'),
(3,'3333333');

  定义获取用户号码的SQL

<select id="getPhoneNum" resultType="java.lang.String">
    select phone_num from phone where user_id=#{userId}
</select>

  定义新的resultMap继承自userResultMap并新增获取用户电话号码集合

<resultMap id="newUserResultMap" extends="userResultMap" 
		   type="com.test.model.User">
    <collection property="phoneNum" column="{userId=user_id}"
                select="getPhoneNum" />
</resultMap>

  使用newUserResultMap作为获取用户信息的结果映射

<select id="getUserInfo" resultMap="newUserResultMap">
    select user_id, user_name, password from user
</select>

  最后需要在User实体类上添加注解@JsonIgnoreProperties({“handler”}),否则会报错
在这里插入图片描述
  重新运行程序使用postman发送请求:http://localhost:8080/user/getUserInfo
  查询结果为:
结果

1.2.5 MyBatis动态SQL

动态SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作。MyBatis 采用功能强大的基于OGNL 的表达式来简化操作

  1. If
    若传入的userId为空或为空字符串,查询的sql语句将不会被执行
<select id="getUserById" resultType="com.test.model.User">
	<if test="userId!=null and userId!=''">
		select userId, userName, password from user where userId=#{userId}
	</if>
</select>
  1. choose(when,otherwise)
    和if相似,相当于if-else,满足条件执行一个分支,否则执行另一个分支
<select id="getUserById" resultType="com.test.model.User">
    select userId,userName,password
    from user
    <where>
        <choose>
            <when test="userId!=null and userId!=''">userId=#{userId}</when>
            <otherwise>userId=-1</otherwise>
        </choose>
    </where>
</select>
  1. foreach
    动态SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建IN 条件语句的时候
    根据多个id查询用户信息,传入的参数应为List ids:
<select id="getUserByIds" resultType="com.test.model.User">
    select userId,userName,password
    from user where userId in
    <foreach collection="ids" item="userId" separator="," open="(" close=")">
        #{userId}
    </foreach>
</select>
  1. trim (where, set)
    主要为了去除动态SQL语句中多余的符号,如(and,or,逗号等),使SQL能够正确执行
<update id="updateUserInfoById" parameterType="com.test.model.User">
    update `user`
    <trim prefix="set" suffixOverrides=",">
        <if test="userName!=null">user_name=#{userName},</if>
        <if test="password!=null">password=#{password},</if>
    </trim>
    where user_id=#{userId}
</update>

  上面的update语句不管userName或password是否为空,都会在后面多出一个逗号,但是 suffixOverrides="," 配置会将多余的逗号给去掉,不会影响SQL的正常执行
更多信息可以参考mybatis官方文档

2 开发工具

2.1 Apache Maven

2.1.1 简介
  • Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具
  • Maven的核心功能便是合理叙述项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包
  • 在pom.xml中添加以下代码就可以给项目导入mysql-connector-java.jar的依赖包,提供访问MySql数据库的功能
    在这里插入图片描述
2.1.2 与IDEA整合使用
  • 首先应该安装与配置maven,可参考百度,上面一堆教程。
  • 安装配置好maven以后,在IDEA中点击File-settings,然后搜索maven即可找到maven的配置,选择maven的安装目录即可。配置完成后我们就可以在IDEA中创建maven项目了。
    在这里插入图片描述
  • Maven的项目结构:
    在这里插入图片描述

2.2 Postman

2.2.1 简介
  • Postman是一款强大的接口测试工具,可以模拟各种Http方法,如Post、Get、Put、Delete等,可以传给后台各种类型的数据,数据的可视化也非常不错,比用浏览器测试要好上太多。
2.2.2 简单使用
  1. text简单参数
    在这里插入图片描述
  2. json参数
    在这里插入图片描述
  3. 返回结果展示,结果若是json会自动美化,方面查看
    结果

2.3 Git

参考百度~~

最后附上源码链接:https://pan.baidu.com/s/1R8l0UK0_KqLch5WgYEZyrw 提取码:dfj7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值