Java 开发相关知识点回顾 (一)

一、关于mybits mapper问题

springboot menuMapper.java interface MenuMapper 怎么和 MenuMapper.xml 关联起来的?

在 Spring Boot 中,通常会使用 MyBatis 框架来操作数据库。MyBatis 支持通过 XML 文件进行 SQL 语句的编写和映射关系的配置。

在 MenuMapper.java 接口中定义了对数据库表 "menu" 进行操作的方法,例如增删改查等操作。而 MenuMapper.xml 文件则用于配置具体的 SQL 语句以及结果集的映射。

MenuMapper.java 接口和 MenuMapper.xml 文件的关联是通过 MyBatis 框架进行的。MyBatis 框架会扫描指定的包路径,自动将 Mapper(即接口)和对应的 XML 配置文件关联起来。

假设你的 MenuMapper.xml 文件位于路径 "classpath:mapper/MenuMapper.xml" 下,那么在 Spring Boot 的配置文件中可以添加以下配置:

mybatis:
  mapper-locations: classpath:mapper/*.xml

上述配置表示将扫描 classpath:mapper 目录下的所有 XML 文件,并将其与对应的 Mapper 接口自动关联起来。这样,Spring Boot 在启动时就会自动注册所有的 Mapper 接口,并将对应的 XML 配置文件解析为映射关系。

也可以在 MenuMapper.java 接口上使用 @Mapper 注解来指定对应的 XML 文件,例如:

@Mapper
public interface MenuMapper {
    // ...
}

在这种情况下,MenuMapper.xml 文件的名称必须与接口名称相同,并位于同一目录下。

总之,通过 MyBatis 框架和 Spring Boot 的集成配置,可以方便地将 MenuMapper.java 接口和 MenuMapper.xml 文件关联起来,并实现对数据库表的操作。

二、关于pom.xml依赖声明

pom 里边的 和 dependencies 有和区别?

<dependencyManagement><dependencies> 是 Maven 构建工具中用于管理和配置依赖的两个不同元素。

<dependencyManagement> 元素是一个可选的顶层元素,在 Maven 项目的顶级 pom.xml 文件中定义。它的作用是为子模块提供一个统一的、集中管理的依赖版本管理机制。在 <dependencyManagement> 中,你可以列出项目中使用的所有依赖,并指定它们的版本号。但是 <dependencyManagement> 元素本身并不会引入具体的依赖项到项目中,它只是定义了版本等信息。子模块可以通过继承或覆盖这些版本信息来管理自己的依赖关系。

例如,假设父级 pom.xml 文件中有一个 <dependencyManagement> 区域,其中包含一个名为 "my-library" 的依赖项,并指定了版本号为 1.0.0。在子模块的 pom.xml 文件中,如果想要使用 "my-library",则只需声明该依赖项,而无需指定版本号,因为它会自动从父级 pom.xml 文件中继承。

<dependencies> 元素用于声明项目实际需要的依赖项。它通常位于 Maven 项目的模块(子模块)的 pom.xml 文件中,而不是顶级 pom.xml 文件中。在 <dependencies> 中,你需要列出项目需要使用的具体依赖项,包括其坐标(groupId、artifactId 和版本号)等信息。当 Maven 构建项目时,它会根据这些 <dependencies> 来自动下载和管理所需的依赖。

总结来说,<dependencyManagement> 用于定义和管理依赖项的版本信息,供子模块继承或覆盖使用,而 <dependencies> 则用于声明实际需要的依赖项,并指定具体的坐标和版本号。通过结合使用这两个元素,你可以在 Maven 项目中有效地管理和控制依赖。

三、lombok库

Lombok 是一个 Java 库,可以通过自动生成代码来简化 Java 类的开发。它通过使用注解(annotations)来减少冗余的样板代码,例如 getter、setter、构造函数、equals()、hashCode() 等方法。以下是 Lombok 的几个常用注解和作用:

  1. @Getter@Setter: 自动生成字段的 getter 和 setter 方法。
  2. @NoArgsConstructor@AllArgsConstructor: 自动生成无参构造函数和包含所有字段的全参构造函数。
  3. @ToString: 自动生成 toString() 方法,用于打印对象的字符串表示形式。
  4. @EqualsAndHashCode: 自动生成 equals() 和 hashCode() 方法,用于对象的相等性比较。
  5. @Data: 组合了 @Getter@Setter@ToString@EqualsAndHashCode 的功能,提供了方便的数据对象定义。
  6. @Builder: 自动生成构建器模式相关的代码,用于创建复杂对象实例。
  7. @Slf4j: 自动生成日志记录器,简化了使用不同日志框架的配置。

使用 Lombok 可以显著减少样板代码的编写量,提高开发效率,并使代码更加清晰和易读。但需要注意的是,在使用 Lombok 时,IDE 和构建工具(如 Maven 或 Gradle)需要进行相应的配置,以支持 Lombok 注解的处理。

请注意,Lombok 是一个开发工具,它并不会影响实际的运行时行为,所生成的代码在编译时会被自动插入到最终生成的字节码中。因此,在阅读他人的 Lombok 代码时,需要注意查看生成的代码以理解实际执行的逻辑。

import lombok.Data;

@Data
public class Person {
    private String name;
    private int age;
}

上面的代码使用 @Data 注解,相当于使用了 @Getter、@Setter、@ToString 和 @EqualsAndHashCode,提供了方便的数据对象定义。

这些是 Lombok 注解的一些示例,还有其他更多的注解和功能可以根据开发需求使用。使用 Lombok 可以简化代码编写,并使代码更加简洁易读。

四、@RequestParam @PathVariable @RequestBody

当处理 HTTP 请求时,Spring 框架提供了不同的注解来方便地获取请求参数的值。以下是三个常用的获取参数的注解的详细说明:

  1. @RequestParam:

    • 作用:用于从请求的 URL 或请求体中获取指定名称的参数值。
    • 示例:
    @GetMapping("/user")
    public String getUser(@RequestParam("id") int userId) {
       // 处理业务逻辑
    }

    上面的代码中,使用 @RequestParam 注解获取名为 "id" 的参数值,并将其赋给 userId 变量。

  2. @PathVariable:

    • 作用:用于从请求的 URL 中获取路径变量的值。
    • 示例:
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable("id") int userId) {
       // 处理业务逻辑
    }

    上面的代码中,使用 @PathVariable 注解获取路径中名为 "id" 的变量值,并将其赋给 userId 变量。

  3. @RequestBody:

    • 作用:用于从请求的主体(body)中获取请求的内容,通常用于接收 JSON 或 XML 格式的数据。
    • 示例:
    @PostMapping("/user")
    public void createUser(@RequestBody User user) {
       // 处理业务逻辑
    }

    上面的代码中,使用 @RequestBody 注解将请求主体中的内容绑定到 User 对象上。

这些注解可以与不同的 HTTP 方法(如 GET、POST、PUT、DELETE 等)结合使用,并根据实际需求和请求参数的类型进行选择。它们提供了方便的方式来获取并处理请求中的参数值,使开发过程更加简洁和高效。

@RequestParam@RequestBody 是用于获取请求参数的注解,但它们在获取参数的方式和使用情况上有一些区别:

  1. 获取参数的方式:

    • @RequestParam:从请求的 URL 或请求体中获取指定名称的参数值。参数以键值对的形式传递,并通过 URL 查询字符串或表单数据的形式进行传输。
    • @RequestBody:从请求的主体(body)中获取请求的内容。参数通常以 JSON、XML 等格式作为请求体传递,适用于接收复杂对象或请求体内容较大的情况。
  2. 使用场景:

    • @RequestParam:适用于获取简单的请求参数,如基本类型、字符串等。常用于处理 GET 请求或表单提交的 POST 请求。
    • @RequestBody:适用于获取复杂对象或自定义数据类型的请求参数。常用于处理 POST、PUT 等请求,特别是传递 JSON 或 XML 数据的情况。
  3. 参数传递方式:

    • @RequestParam:参数以键值对的形式通过 URL 查询字符串或表单数据进行传输,例如 /user?id=10&name=John
    • @RequestBody:参数以请求主体的形式进行传输,通常以 JSON 或 XML 格式作为请求体内容,需要在请求头中指定 Content-Type。

示例代码:

@GetMapping("/user")
public String getUser(@RequestParam("id") int userId) {
    // 处理业务逻辑
}

@PostMapping("/user")
public void createUser(@RequestBody User user) {
    // 处理业务逻辑
}

在上述示例中,@RequestParam 注解用于获取名为 "id" 的参数值,而 @RequestBody 注解用于从请求主体中接收 User 对象。

总结来说,@RequestParam 适用于获取简单的请求参数,而 @RequestBody 用于获取复杂对象或传递大量数据的请求参数。根据实际需求和数据类型的不同,我们可以灵活选择适合的注解来获取参数。

    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("order:paymentinfo:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = paymentInfoService.queryPage(params);

        return R.ok().put("page", page);
    }

如果请求的 URL 同时携带了键值对参数,并且还有请求主体(body)中的参数,可以同时使用 @RequestParam@RequestBody 来接收这两种类型的参数。

以下是一个示例代码:

@PostMapping("/user")
public void createUser(@RequestParam("id") int userId, @RequestBody User user) {
    // 使用 @RequestParam 接收 URL 中的 "id" 参数,参数类型为 int
    // 使用 @RequestBody 接收请求主体中的 User 对象

    // 处理业务逻辑
}

在上述示例中,使用 @RequestParam 注解来接收 URL 中的 "id" 参数,参数类型为 int。同时使用 @RequestBody 注解来接收请求主体中的 User 对象。

这样,当发送请求时,可以在 URL 中以键值对的形式传递 "id" 参数,同时在请求主体中以 JSON 或 XML 格式传递 User 对象。

通过组合使用 @RequestParam@RequestBody,可以灵活地处理同时携带 URL 参数和请求主体参数的情况。请根据实际需求进行调整和使用。

五、mybatis 和 mybatis-plus

区别

MyBatis和MyBatis-Plus是两个在Java开发中常用的持久层框架,它们有以下区别:

  1. 功能扩展:

    • MyBatis:MyBatis是一个相对轻量级的持久层框架,提供了基本的SQL映射功能和对象关系映射(ORM)能力。
    • MyBatis-Plus:MyBatis-Plus是在MyBatis基础上进行了扩展,提供了更多的功能和便利的操作,如通用的CRUD操作、分页、逻辑删除等。
  2. 代码生成器:

    • MyBatis:MyBatis本身没有内置的代码生成器,需要借助第三方工具或手动编写XML和Java代码。
    • MyBatis-Plus:MyBatis-Plus内置了强大的代码生成器,可以根据数据库表结构自动生成实体类、Mapper接口、XML映射文件等,极大地减少了重复编码的工作量。
  3. 接口和注解支持:

    • MyBatis:MyBatis主要通过XML配置文件定义SQL语句和映射关系,使用Mapper接口来调用SQL语句。
    • MyBatis-Plus:MyBatis-Plus支持注解方式和接口方式两种。除了可以通过注解直接在方法上编写SQL语句外,还可以通过继承BaseMapper接口来获得CRUD操作的基本方法。
  4. 分页查询:

    • MyBatis:MyBatis需要手动编写分页SQL语句,通常使用数据库特定的语法,如MySQL的LIMIT。
    • MyBatis-Plus:MyBatis-Plus提供了更为简洁和易用的分页查询功能,只需在查询方法中传入当前页码和每页数量即可自动生成分页SQL查询。

总体而言,MyBatis-Plus是对MyBatis的增强和扩展,在功能和便利性方面提供了更多的选项和便捷的操作。如果你需要更高级的功能和更少的样板代码,可以考虑使用MyBatis-Plus。如果你对功能要求相对简单或担心引入过多的外部依赖,可以选择使用MyBatis。根据具体项目需求和个人喜好,选择合适的框架来进行开发。

示例说明

好的,我将通过一个具体的例子来说明MyBatis和MyBatis-Plus之间的区别。

假设我们有一个用户管理系统,其中包含用户信息的表。我们使用MyBatis和MyBatis-Plus分别实现对用户信息的增删改查操作。

  1. 使用MyBatis:

首先,我们需要编写User类和对应的Mapper接口和XML映射文件。

public class User {
    private Long id;
    private String username;
    private String email;
    // 省略getter和setter方法
}

public interface UserMapper {
    List<User> getAllUsers();
    User getUserById(Long id);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(Long id);
}

然后,在XML映射文件中定义SQL语句和对象映射关系。

<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <select id="getAllUsers" resultType="com.example.model.User">
        SELECT * FROM user;
    </select>

    <select id="getUserById" parameterType="java.lang.Long" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id};
    </select>

    <insert id="insertUser" parameterType="com.example.model.User">
        INSERT INTO user(username, email) VALUES (#{username}, #{email});
    </insert>

    <update id="updateUser" parameterType="com.example.model.User">
        UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id};
    </update>

    <delete id="deleteUser" parameterType="java.lang.Long">
        DELETE FROM user WHERE id = #{id};
    </delete>
</mapper>

接下来,我们可以使用UserMapper接口进行数据库操作。

public class Main {
    public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

            // 查询所有用户
            List<User> users = userMapper.getAllUsers();
            System.out.println(users);

            // 根据ID查询用户
            User user = userMapper.getUserById(1L);
            System.out.println(user);

            // 插入用户
            User newUser = new User();
            newUser.setUsername("John");
            newUser.setEmail("john@example.com");
            userMapper.insertUser(newUser);

            // 更新用户
            user.setUsername("UpdatedUserName");
            userMapper.updateUser(user);

            // 删除用户
            userMapper.deleteUser(user.getId());

            sqlSession.commit();
        } catch (Exception e) {
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}

以上就是使用MyBatis的示例代码,通过编写XML映射文件和Java代码来实现对用户表的增删改查操作。

  1. 使用MyBatis-Plus:

使用MyBatis-Plus可以大大简化上述代码。首先,我们需要引入MyBatis-Plus的依赖,并配置数据库连接信息。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>最新版本号</version>
</dependency>

然后,我们只需要定义一个继承自BaseMapper的接口,MyBatis-Plus会根据约定自动生成SQL语句和基本的CRUD方法。

public interface UserMapper extends BaseMapper<User> {
}

接下来,我们可以直接使用UserMapper进行数据库操作,无需写SQL语句。

public class Main {
    public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

            // 查询所有用户
            List<User> users = userMapper.selectList(null);
            System.out.println(users);

            // 根据ID查询用户
            User user = userMapper.selectById(1L);
            System.out.println(user);

            // 插入用户
            User newUser = new User();
            newUser.setUsername("John");
            newUser.setEmail("john@example.com");
            userMapper.insert(newUser);

            // 更新用户
            user.setUsername("UpdatedUserName");
            userMapper.updateById(user);

            // 删除用户
            userMapper.deleteById(user.getId());

            sqlSession.commit();
        } catch (Exception e) {
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}

以上就是使用MyBatis-Plus的示例代码。通过继承BaseMapper接口,我们可以直接调用MyBatis-Plus提供的便捷方法,无需手动编写SQL语句。

可以看到,相比MyBatis,使用MyBatis-Plus能够更加简洁和高效地进行数据库操作。尤其是在编写代码和处理增删改查等基本操作时,可以极大地减少重复劳动。

springcloud gateway 自定义过滤器

Spring Cloud Gateway 的Filter分为GatewayFilter和GlobalFilter两种,二者区别如下

  • GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
  • GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。

自定义网关过滤器

需求:编写一个网关过滤器,实现打印请求URI。

  • 方式1 继承AbstractGatewayFilterFactory
  • 方式2 实现GatewayFilter 接口

自定义全局过滤器

自定义全局过滤器需要实现以下两个接口:GlobalFilter,ordered。通过全局过滤器可以实现权限校验,安全性验证等功能。

案例演示之鉴权
需求:对所有请求进行鉴权,校验消息头是否携带了 Spring Security Oauth2 访问令牌,没有则直接拦截,还需要对登录等接口进行放行处理。

Spring Cloud Gateway系列【7】自定义过滤器

springcloud gateway高并发场景

在单体服务中使用Spring Cloud Gateway进行请求过滤和响应处理,与直接使用Spring MVC手写HTTP请求数据处理和返回相比,通常情况下前者更加高效。下面我将给出一些原因。

  1. 异步非阻塞模型:Spring Cloud Gateway是基于Reactor框架构建的,利用了非阻塞I/O和异步编程模型。它可以处理大量并发请求而不会阻塞线程,充分利用服务器资源,并且在高负载场景下表现良好。

  2. 网关缓存:Spring Cloud Gateway可通过配置缓存策略来缓存经过网关的请求和响应,避免每次请求都重新处理。这对于高并发场景特别有益,可以减轻后端服务的压力。

  3. 熔断和限流:Spring Cloud Gateway集成了熔断器和限流器等机制,可以对请求进行监控和管理。当后端服务发生故障或超过预设的限流阈值时,可以及时进行熔断或限流操作,保证整个系统的稳定性和可靠性。

  4. 路由和负载均衡:Spring Cloud Gateway提供了灵活且易于配置的路由规则,可以根据请求的URL、方法、标头等动态地将请求转发到后端的不同服务实例上。同时,它还支持负载均衡算法,可以均衡地将请求分发到多个后端服务实例上,提高系统的吞吐量和并发能力。

  5. 插件机制:Spring Cloud Gateway提供了丰富的过滤器和拦截器插件,用于处理请求和响应。你可以根据实际需求选择和配置相应的插件,以实现自定义的逻辑和功能。

综上所述,使用Spring Cloud Gateway可以利用其异步非阻塞模型、网关缓存、熔断和限流机制、路由和负载均衡以及插件机制等特性,来处理高并发场景下的请求和响应,提供更高效的性能和可伸缩性。


相关文章:
Spring Cloud Gateway系列【7】自定义过滤器

为者常成,行者常至