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 的几个常用注解和作用:
@Getter
和@Setter
: 自动生成字段的 getter 和 setter 方法。@NoArgsConstructor
和@AllArgsConstructor
: 自动生成无参构造函数和包含所有字段的全参构造函数。@ToString
: 自动生成 toString() 方法,用于打印对象的字符串表示形式。@EqualsAndHashCode
: 自动生成 equals() 和 hashCode() 方法,用于对象的相等性比较。@Data
: 组合了@Getter
、@Setter
、@ToString
、@EqualsAndHashCode
的功能,提供了方便的数据对象定义。@Builder
: 自动生成构建器模式相关的代码,用于创建复杂对象实例。@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 框架提供了不同的注解来方便地获取请求参数的值。以下是三个常用的获取参数的注解的详细说明:
-
@RequestParam
:- 作用:用于从请求的 URL 或请求体中获取指定名称的参数值。
- 示例:
@GetMapping("/user") public String getUser(@RequestParam("id") int userId) { // 处理业务逻辑 }
上面的代码中,使用
@RequestParam
注解获取名为 "id" 的参数值,并将其赋给userId
变量。 -
@PathVariable
:- 作用:用于从请求的 URL 中获取路径变量的值。
- 示例:
@GetMapping("/user/{id}") public String getUser(@PathVariable("id") int userId) { // 处理业务逻辑 }
上面的代码中,使用
@PathVariable
注解获取路径中名为 "id" 的变量值,并将其赋给userId
变量。 -
@RequestBody
:- 作用:用于从请求的主体(body)中获取请求的内容,通常用于接收 JSON 或 XML 格式的数据。
- 示例:
@PostMapping("/user") public void createUser(@RequestBody User user) { // 处理业务逻辑 }
上面的代码中,使用
@RequestBody
注解将请求主体中的内容绑定到User
对象上。
这些注解可以与不同的 HTTP 方法(如 GET、POST、PUT、DELETE 等)结合使用,并根据实际需求和请求参数的类型进行选择。它们提供了方便的方式来获取并处理请求中的参数值,使开发过程更加简洁和高效。
@RequestParam
和 @RequestBody
是用于获取请求参数的注解,但它们在获取参数的方式和使用情况上有一些区别:
-
获取参数的方式:
@RequestParam
:从请求的 URL 或请求体中获取指定名称的参数值。参数以键值对的形式传递,并通过 URL 查询字符串或表单数据的形式进行传输。@RequestBody
:从请求的主体(body)中获取请求的内容。参数通常以 JSON、XML 等格式作为请求体传递,适用于接收复杂对象或请求体内容较大的情况。
-
使用场景:
@RequestParam
:适用于获取简单的请求参数,如基本类型、字符串等。常用于处理 GET 请求或表单提交的 POST 请求。@RequestBody
:适用于获取复杂对象或自定义数据类型的请求参数。常用于处理 POST、PUT 等请求,特别是传递 JSON 或 XML 数据的情况。
-
参数传递方式:
@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开发中常用的持久层框架,它们有以下区别:
-
功能扩展:
- MyBatis:MyBatis是一个相对轻量级的持久层框架,提供了基本的SQL映射功能和对象关系映射(ORM)能力。
- MyBatis-Plus:MyBatis-Plus是在MyBatis基础上进行了扩展,提供了更多的功能和便利的操作,如通用的CRUD操作、分页、逻辑删除等。
-
代码生成器:
- MyBatis:MyBatis本身没有内置的代码生成器,需要借助第三方工具或手动编写XML和Java代码。
- MyBatis-Plus:MyBatis-Plus内置了强大的代码生成器,可以根据数据库表结构自动生成实体类、Mapper接口、XML映射文件等,极大地减少了重复编码的工作量。
-
接口和注解支持:
- MyBatis:MyBatis主要通过XML配置文件定义SQL语句和映射关系,使用Mapper接口来调用SQL语句。
- MyBatis-Plus:MyBatis-Plus支持注解方式和接口方式两种。除了可以通过注解直接在方法上编写SQL语句外,还可以通过继承BaseMapper接口来获得CRUD操作的基本方法。
-
分页查询:
- MyBatis:MyBatis需要手动编写分页SQL语句,通常使用数据库特定的语法,如MySQL的LIMIT。
- MyBatis-Plus:MyBatis-Plus提供了更为简洁和易用的分页查询功能,只需在查询方法中传入当前页码和每页数量即可自动生成分页SQL查询。
总体而言,MyBatis-Plus是对MyBatis的增强和扩展,在功能和便利性方面提供了更多的选项和便捷的操作。如果你需要更高级的功能和更少的样板代码,可以考虑使用MyBatis-Plus。如果你对功能要求相对简单或担心引入过多的外部依赖,可以选择使用MyBatis。根据具体项目需求和个人喜好,选择合适的框架来进行开发。
示例说明
好的,我将通过一个具体的例子来说明MyBatis和MyBatis-Plus之间的区别。
假设我们有一个用户管理系统,其中包含用户信息的表。我们使用MyBatis和MyBatis-Plus分别实现对用户信息的增删改查操作。
- 使用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代码来实现对用户表的增删改查操作。
- 使用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请求数据处理和返回相比,通常情况下前者更加高效。下面我将给出一些原因。
-
异步非阻塞模型:Spring Cloud Gateway是基于Reactor框架构建的,利用了非阻塞I/O和异步编程模型。它可以处理大量并发请求而不会阻塞线程,充分利用服务器资源,并且在高负载场景下表现良好。
-
网关缓存:Spring Cloud Gateway可通过配置缓存策略来缓存经过网关的请求和响应,避免每次请求都重新处理。这对于高并发场景特别有益,可以减轻后端服务的压力。
-
熔断和限流:Spring Cloud Gateway集成了熔断器和限流器等机制,可以对请求进行监控和管理。当后端服务发生故障或超过预设的限流阈值时,可以及时进行熔断或限流操作,保证整个系统的稳定性和可靠性。
-
路由和负载均衡:Spring Cloud Gateway提供了灵活且易于配置的路由规则,可以根据请求的URL、方法、标头等动态地将请求转发到后端的不同服务实例上。同时,它还支持负载均衡算法,可以均衡地将请求分发到多个后端服务实例上,提高系统的吞吐量和并发能力。
-
插件机制:Spring Cloud Gateway提供了丰富的过滤器和拦截器插件,用于处理请求和响应。你可以根据实际需求选择和配置相应的插件,以实现自定义的逻辑和功能。
综上所述,使用Spring Cloud Gateway可以利用其异步非阻塞模型、网关缓存、熔断和限流机制、路由和负载均衡以及插件机制等特性,来处理高并发场景下的请求和响应,提供更高效的性能和可伸缩性。
相关文章:
Spring Cloud Gateway系列【7】自定义过滤器
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)