Spring知识总结

目录

知识复习

一.spring

1.概念

2.常用注解

3.@componentsacn

4.aop

二.mybatis-plus

概念:

1.常见配置yaml

2.设置雪花主键

3.分页配置

4.代码生成器

5.公共字段自动填充

6.Lambda查询

三.Mybatis

概念:

1.xmlMapper文件

2.动态sql

3.自定义返回类型

4.mybatis-config.xml核心配置文件

5.单独使用的示例

6.在spring中的使用

8.事务的使用

9.整合druid连接池

10.整合druid在配置类中配置

四.springmvc

概念:

1.springmvc的在javaweb中的单独使用

2.springmvc在spring中的使用

3.springmvc的参数日期格式转换

4.全局日期参数自动转换

5.拦截器

6.拦截器的路径配置

7.拦截器和过滤器的区别

8.跨域配置

9.放行静态资源

五.springboot

概念:

1.springboot的搭建

2.springboot中开发web项目的依赖

(1).引入springmvc依赖

(2).引入mysql连接依赖**

(3)引入druid启动依赖

(4).引入mybatis-plus依赖**

(5).引入lombok依赖

3.对以上依赖的相关配置

(1)对端口配置

(2).对mysql和druid连接池配置

(3)对mybatis-plus的配置

4.springboot的简单示例

5.分页查询示例

6.LambdQueryWrapper

7.springboot中配置跨域


知识复习

一.spring

1.概念

Spring框架中的核心模块是**IoC(Inversion of Control ,控制反转)**和AOP(Aspect Oriented Programming,面向切面编程)。

  1. IoC(控制反转):IoC是Spring框架的核心特性之一,通过使用依赖注入,将对象的创建和依赖关系管理的责任从应用程序代码中解耦。通过IoC容器,我们可以将对象的创建和组装交由Spring框架来负责,使应用程序更加灵活、可测试和可维护。

  2. AOP(面向切面编程 ):AOP是Spring框架的另一个核心特性,它通过将与业务逻辑无关的横切关注点(如日志、安全性、事务管理)从业务逻辑中分离出来,实现了关注点的模块化。通过使用AOP,我们可以通过声明方式将这些横切关注点应用到我们的应用程序中,而不需要修改业务逻辑代码。

2.常用注解

  1. @Configuration: 标记一个类为配置类,用于替代XML配置文件。

    示例:

    java 复制代码
    @Configuration
    public class AppConfig {
        // 配置Bean的方法
    }
  2. @Bean: 标记一个方法产生一个Bean对象,并由Spring容器进行管理

    示例:

    java 复制代码
    @Configuration
    public class AppConfig {
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
  3. @Scope: 定义Bean的作用范围,默认为单例。

    示例:

    java 复制代码
    @Component
    @Scope("prototype")
    public class UserService {
        // 类的具体实现
    }
  4. @Value: 注入一个值到Bean中,可以是基本类型、字符串、引用等。

    示例:

    java 复制代码
    @Component
    public class UserService {
        @Value("John Doe")
        private String userName;
        
        // 其他方法
    }
  5. @Qualifier: 当存在多个相同类型的Bean时,通过该注解指定注入的Bean。

    示例:

    java 复制代码
    @Autowired
    @Qualifier("userRepository")
    private UserRepository userRepository;
  6. @PostConstruct: 在Bean实例化后执行初始化方法。

    示例:

    java 复制代码
    @Component
    public class UserService {
        @PostConstruct
        public void init() {
            // 初始化逻辑
        }
    }
  7. @PreDestroy: 在Bean销毁前执行清理操作。

    示例:

    java 复制代码
    @Component
    public class UserService {
        @PreDestroy
        public void cleanup() {
            // 清理逻辑
        }
    }

8**.@component注解**

@Component 是Spring中最常用的注解之一,用于标记一个类为组件类,并由Spring容器进行管理。

它的派生注解有以下几种:

  1. @Controller: 标记一个类为控制器(Web MVC)。

    示例:

    java 复制代码
    @Controller
    public class UserController {
        // 控制器的具体实现
    }
  2. @Service: 标记一个类为服务类,通常用于业务逻辑的处理。

    示例:

    java 复制代码
    @Service
    public class UserService {
        // 服务类的具体实现
    }
  3. @Repository: 标记一个类为存储库类,用于数据持久化。

    示例:

    java 复制代码
    @Repository
    public class UserRepository {
        // 存储库类的具体实现
    }

3.@componentsacn

**@ComponentScan是一个Spring框架提供的注解,用于指定要扫描的包路径,将被@Component、@Controller、@Service、@Repository等注解标注的类注册为Spring容器中的Bean。**通过@ComponentScan注解,可以自动扫描并注册指定包路径下的所有符合条件的组件。

@ComponentScan注解通常用在Spring配置类上,作为配置类的注解之一。通过在配置类上添加@ComponentScan注解并指定要扫描的包路径,Spring容器会自动扫描并注册指定包路径下的所有组件。

例如:

java 复制代码
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
    //其他配置信息
}

上述代码中,使用@ComponentScan注解指定要扫描的包路径为"com.example.demo",Spring容器会自动扫描并注册该包路径下的所有组件,包括被@Component、@Controller、@Service、@Repository等注解标注的类

需要注意的是,@ComponentScan注解还可以通过其属性basePackages和value来指定多个包路径进行扫描,以及通过excludeFilters和includeFilters属性来指定过滤条件进行筛选注册的组件。

4.aop

在Spring中使用AOP,不使用XML配置和Spring Boot。可以按照以下步骤进行配置:

  1. 创建一个切面类,使用@Aspect注解标注,并添加@Component注解使其成为Spring的组件:
java 复制代码
@Aspect
@Component
public class LoggingAspect {
​
    @Before("execution(* com.example.demo.service.*.*(..))")
    public void beforeMethodCall(JoinPoint joinPoint) {
        // 在方法调用前执行的逻辑
        String methodName = joinPoint.getSignature().getName();
        System.out.println("Before method call: " + methodName);
    }
​
    // 其他通知方法...
}
  1. 创建一个配置类,使用@Configuration注解标注,并添加@ComponentScan注解指定要扫描的包路径:
java 复制代码
@Configuration
@ComponentScan(basePackages = "com.example.demo")
public class AppConfig {
​
}
  1. 在Spring应用上下文中加载配置类并启动:
java 复制代码
public class Main {
​
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
​
        // 获取切面类作为bean并使用
        LoggingAspect loggingAspect = context.getBean(LoggingAspect.class);
​
        // 调用业务方法
        SomeService someService = context.getBean(SomeService.class);
        someService.doSomething();
​
        context.close();
    }
}

通过以上配置,可以实现在Spring中使用AOP,切面类中定义的通知方法将在相应的切点被触发时执行 逻辑。

注意:在配置类中使用@ComponentScan注解指定要扫描的包路径,以确保Spring能够扫描到切面类作为组件进行注册和使用

二.mybatis-plus

概念:

MyBatis-Plus是基于MyBatis的增强工具,提供了更方便、更强大的功能来简化数据库访问的开发。

以下是MyBatis-Plus的一些主要概念:

  1. 实体(Entity):在MyBatis-Plus中,实体是与数据库中的表相映射的Java对象。实体类通常包含表中的字段对应的属性,并使用注解来指定与数据库表的映射关系。

  2. **Mapper:**Mapper是用于执行具体SQL操作的接口。使用MyBatis-Plus时,可以通过继承BaseMapper接口来轻松地实现常见的CRUD操作,也可以自定义SQL语句。

  3. Service:Service是用于封装业务逻辑的组件。MyBatis-Plus提供了BaseService接口,可以用于快速创建Service类,也提供了常用的查询、更新等方法。

  4. Wrapper:Wrapper是用于创建查询条件的封装类。MyBatis-Plus中的Wrapper接口提供了一系列的方法,可以根据具体需求灵活地构建查询条件,如eq、like、gt等方法。

  5. 自动填充(MetaObjectHandler):MyBatis-Plus提供了自动填充功能,可以在插入和更新实体时自动填充额外的字段,如创建时间、更新时间等。可以通过实现MetaObjectHandler接口来自定义填充的逻辑。

  6. 分页支持:MyBatis-Plus提供了方便的分页查询功能,可以通过Page对象进行分页查询,并提供了一系列的Pageable方法进行分页参数的设置。

  7. 主键策略:MyBatis-Plus支持多种主键策略,如自增、UUID、雪花算法等。可以通过注解@TableId来指定主键字段,并使用@KeySequence注解来配置主键生成策略。

通过使用MyBatis-Plus,可以简化数据库访问的开发,提高开发效率,并提供了更多的功能和扩展点,使得开发工作更加便捷。

1.常见配置yaml

以下是一个示例的 MyBatis-Plus 的 yaml 配置文件:

java 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
​
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
​
  # 分页配置
  pagehelper:
    helper-dialect: mysql
    reasonable: true
    support-methods-arguments: true
    params: count=countSql
​
  # 逻辑删除配置
  global-config:
    db-config:
      logic-delete-field: is_deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
​
  # 主键策略配置
  global-config:
    db-config:
      id-type: auto

2.设置雪花主键

要在 MyBatis-Plus 中使用注解方式设置雪花主键生成器,可以按照以下步骤进行设置:

  1. 1在实体类中使用 @TableId 注解标注主键字段,并设置主键生成策略为 IdType.ASSIGN_ID,同时指定一个自定义的主键生成器。
java 复制代码
@Data
@TableName("your_table")
public class YourEntity {
    @TableId(value = "id", type = IdType.ASSIGN_ID, generator = "snowflake")
    private Long id;
    
    // 其他字段...
}
  1. 2创建一个自定义的主键生成器类,实现 IdentifierGenerator 接口,并重写 nextId 方法来生成雪花算法的主键。
java 复制代码
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
​
public class SnowflakeGenerator implements IdentifierGenerator {
    @Override
    public Number nextId(Object entity) {
        return IdWorker.getId();
    }
​
    @Override
    public String nextUUID(Object entity) {
        return IdWorker.get32UUID();
    }
​
    @Override
    public Object nextId(Object entity, String fieldName) {
        return IdWorker.getId();
    }
}
  1. 3启动类或配置类中使用 @Bean 注解来注册自定义的主键生成器。
java 复制代码
@Configuration
public class MybatisPlusConfig {
    @Bean
    public IdentifierGenerator snowflake() {
        return new SnowflakeGenerator();
    }
}

通过以上设置,在使用 MyBatis-Plus 进行插入操作时,会自动调用雪花主键生成器生成全局唯一的 ID 作为主键值,并将其赋给实体类中的 id 字段

3.分页配置

要在 MyBatis-Plus 中使用分页插件,可以按照以下步骤进行设置:

  1. 添加依赖:在项目的 POM 文件中添加 MyBatis-Plus 分页插件的依赖。
XML 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>{version}</version>
</dependency>
  1. 配置分页插件:在启动类或配置类中添加 PaginationInterceptor 的 Bean,来启用分页插件
java 复制代码
@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
  1. 使用分页查询:在需要分页查询的方法中使用 Page 类进行分页操作。
java 复制代码
@Service
public class YourService {
    @Autowired
    private YourMapper yourMapper;
    
    public IPage<YourEntity> getPageData(Integer pageNum, Integer pageSize) {
        // 创建分页对象
        Page<YourEntity> page = new Page<>(pageNum, pageSize);
        
        // 执行分页查询,结果会自动封装在 page 对象中
        IPage<YourEntity> pageData = yourMapper.selectPage(page, null);
        
        return pageData;
    }
}
  1. 获取分页结果:通过分页对象的方法可以获取到分页的相关信息和查询结果。
java 复制代码
IPage<YourEntity> pageData = yourService.getPageData(1, 10);
​
long total = pageData.getTotal(); // 获取总记录数
List<YourEntity> records = pageData.getRecords(); // 获取当前页的记录列表
​
// 分页信息
long current = pageData.getCurrent(); // 当前页码
long pages = pageData.getPages(); // 总页数
long size = pageData.getSize(); // 每页记录数
boolean hasPrevious = pageData.hasPrevious(); // 是否有前一页
boolean hasNext = pageData.hasNext(); // 是否有下一页

4.代码生成器

下面是一个使用 MyBatis-Plus 代码生成器生成代码的示例,不使用 XML 配置文件,并且每行都有注释说明:

1.依赖

XML 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>{version}</version>
</dependency>

2.示例

java 复制代码
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.ibatis.type.JdbcType;
​
public class Generator {
    public static void main(String[] args) {
        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:mysql://localhost:3306/db_name", "root", "root")
                .driver(DbType.MYSQL.getDriver()) // 设置数据库类型
                .type(DbType.MYSQL) // 设置数据库类型
                .build();
​
        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig.Builder()
                .outputDir(System.getProperty("user.dir") + "/src/main/java") // 设置输出目录
                .author("Your Name") // 设置作者
                .openDir(true) // 生成完成后是否打开输出目录
                .dateType(DateType.ONLY_DATE) // 设置日期类型
                .idType(IdType.AUTO) // 设置主键类型
                .fileOverride(true) // 是否覆盖已有文件
                .build();
​
        // 包名配置
        PackageConfig packageConfig = new PackageConfig.Builder()
                .parent("com.example") // 设置父包名
                .moduleName("demo") // 设置模块名
                .entity("entity") // 设置实体类包名
                .mapper("mapper") // 设置Mapper接口包名
                .service("service") // 设置Service类包名
                .controller("controller") // 设置Controller类包名
                .build();
​
        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig.Builder()
                .naming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略,下划线转驼峰命名
                .columnNaming(NamingStrategy.underline_to_camel) // 数据库表字段映射到实体类属性的命名策略,下划线转驼峰命名
                .entityTableFieldAnnotationEnable(true) // 是否生成实体类字段注解
                .entityLombokModel(true) // 是否使用Lombok注解
                .controllerRestStyle(true) // 是否生成@RestController风格控制器
                .controllerMappingHyphenStyle(true) // 是否驼峰转连字符
                .build();
​
        // 代码生成器
        AutoGenerator generator = new AutoGenerator(dataSourceConfig)
                .global(globalConfig)
                .packageInfo(packageConfig)
                .strategy(strategyConfig)
                .template(new TemplateConfig.Builder().build()); // 使用默认模板配置
​
        // 执行生成的代码
        generator.execute();
    }
}

5.公共字段自动填充

下面是一个使用 MyBatis-Plus 实现公共字段自动填充的示例:

首先,定义一个公共字段填充处理器:

java 复制代码
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
​
import java.time.LocalDateTime;
​
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
​
    @Override
    public void insertFill(MetaObject metaObject) {
        // 设置创建时间和更新时间字段的值为当前时间
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }
​
    @Override
    public void updateFill(MetaObject metaObject) {
        // 设置更新时间字段的值为当前时间
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }
}

然后,在实体类中添加对应的公共字段,并使用 @TableField 注解进行配置:

java 复制代码
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
​
import java.time.LocalDateTime;
​
@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
​
    private String username;
​
    private String password;
​
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
​
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

最后,在启动类中将公共字段填充处理器添加到 MyBatis-Plus 的自动填充处理器列表中:

java 复制代码
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

6.Lambda查询

MyBatis-Plus 提供了 Lambd 查询,通过使用 Lambda 表达式,可以更加简洁地进行条件查询。下面是一些常见的 Lambd 查询示例:

  1. 等值查询:
java 复制代码
// 使用 lambda 进行等值查询
List<User> userList = userMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getUsername, "admin"));
  1. 模糊查询:
java 复制代码
// 使用 lambda 进行模糊查询
List<User> userList = userMapper.selectList(Wrappers.<User>lambdaQuery().like(User::getUsername, "adm"));
  1. 多条件查询:
java 复制代码
// 使用 lambda 进行多条件查询
List<User> userList = userMapper.selectList(Wrappers.<User>lambdaQuery()
    .eq(User::getGender, "男")
    .like(User::getUsername, "adm")
    .lt(User::getAge, 30));
  1. 自定义查询条件:
java 复制代码
// 使用 lambda 自定义查询条件
List<User> userList = userMapper.selectList(Wrappers.<User>lambdaQuery()
    .eq(User::getGender, "男")
    .and(queryWrapper -> queryWrapper.like(User::getUsername, "adm").or().like(User::getEmail, "test")));
在以上示例中,User::getUsername、User::getGender 等方法引用代表了实体类的属性,可使用 lambda 表达式构建查询条件。

除了查询方法使用了 lambda 之外,还可以使用 UpdateWrapper 进行更新操作,示例代码如下:

// 使用 lambda 进行更新操作
userMapper.update(null, Wrappers.<User>lambdaUpdate()
        .set(User::getUsername, "admin")
        .eq(User::getId, 1));

以上示例演示了一些常见的 Lambd 查询用法,使用 MyBatis-Plus 的 Lambd 查询可以大大简化查询条件的编写,提高开发效率。

三.Mybatis

概念:

MyBatis是一个开源的**持久化框架,简化了数据库访问开发。**它提供了一种将SQL语句与Java方法绑定的方式,使开发人员可以轻松地配置和执行数据库操作。

以下是MyBatis的一些关键概念:

  1. **Mapper XML:**Mapper XML是配置SQL语句的地方。它包含了与数据库交互的具体SQL语句,以及SQL语句与Java方法之间的映射关系。

  2. Mapper接口:Mapper接口定义了与数据库交互的方法。通过在接口方法上使用注解,可以将SQL语句绑定到方法上。

  3. SqlSession:SqlSession是MyBatis与数据库交互的核心类。它提供了数据库操作的方法,如查询、插入、更新等。开发人员可以通过SqlSession执行Mapper接口中定义的方法。

  4. ParameterHandler:ParameterHandler负责处理SQL语句的参数。它将Java对象转换为符合JDBC标准的参数,并将其传递给底层的JDBC驱动程序。

  5. ResultSetHandler:ResultSetHandler负责处理查询结果。它将JDBC查询结果转换为Java对象,并将其返回给应用程序。

  6. Executor:Executor负责执行SQL语句。它根据配置可以使用不同的执行策略,如简单、批处理或重用等。

1.xmlMapper文件

MyBatis 的 XML Mapper 文件是用来定义 SQL 映射关系以及提供 SQL 查询、插入、更新、删除等操作的地方。通常一个实体类对应一个 XML Mapper 文件,其命名规则是实体类名加上 Mapper.xml 后缀。

XML Mapper 文件的基本结构如下:

XML 复制代码
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
​
<mapper namespace="com.example.UserMapper">
​
    <!-- 定义 SQL 查询语句 -->
    <select id="selectUser" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
​
    <!-- 定义 SQL 插入语句 -->
    <insert id="insertUser" parameterType="User">
        INSERT INTO user (username, password) VALUES (#{username}, #{password})
    </insert>
​
    <!-- 定义 SQL 更新语句 -->
    <update id="updateUser" parameterType="User">
        UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}
    </update>
​
    <!-- 定义 SQL 删除语句 -->
    <delete id="deleteUser" parameterType="int">
        DELETE FROM user WHERE id = #{id}
    </delete>
​
</mapper>

2.动态sql

在 MyBatis 的 XML Mapper 文件中,可以使用动态 SQL 来根据条件生成不同的 SQL 语句。这样可以实现在同一个 SQL 查询中根据不同的条件进行灵活地拼接和生成不同的查询语句。

动态 SQL 主要通过以下几个标签来实现:

  1. <if>:用于条件判断,根据给定的条件判断是否包含其中的 SQL 语句。
XML 复制代码
<select id="selectUser" parameterType="Map" resultType="User">
  SELECT * FROM user
  WHERE
    <if test="username != null">username = #{username}</if>
    <if test="gender != null">AND gender = #{gender}</if>
</select>

在上面的例子中,如果传入的参数 usernamegender 都不为空,那么最终生成的 SQL 语句将是 SELECT * FROM user WHERE username = #{username} AND gender = #{gender}

  1. <choose><when><otherwise>:用于条

    XML 复制代码
    <select id="selectUser" parameterType="Map" resultType="User">
      SELECT * FROM user
      <choose>
        <when test="id != null">WHERE id = #{id}</when>
        <when test="username != null">WHERE username = #{username}</when>
        <otherwise>WHERE gender = #{gender}</otherwise>
      </choose>
    </select>

    件选择,根据给定的条件选择其中的一个分支执行。

复制代码

在上面的例子中,根据传入的参数中的 idusernamegender 的值,选择不同的分支执行,生成不同的 SQL 语句。

  1. <foreach>:用于循环处理,将一个集合中的元素逐个拼接到 SQL 语句中。
XML 复制代码
<delete id="deleteByIdList" parameterType="List">
  DELETE FROM user
  WHERE id IN
  <foreach collection="list" item="id" separator="," open="(" close=")">
    #{id}
  </foreach>
</delete>

5<where>:用于条件处理

XML 复制代码
  SELECT * FROM user      AND username = #{username}    AND gender = #{gender}   

3.自定义返回类型

在 XML Mapper 文件中,可以使用 <resultMap> 标签来定义自定义的结果映射。通过 <resultMap> 标签,可以指定查询结果中的列和对象属性之间的映射关系,并定义如何处理结果。

以下是一个示例:

XML 复制代码
<resultMap id="userResultMap" type="com.example.User">
  <id property="id" column="user_id"/>
  <result property="username" column="user_name"/>
  <association property="address" javaType="com.example.Address">
    <id property="id" column="address_id"/>
    <result property="city" column="address_city"/>
    <result property="country" column="address_country"/>
  </association>
</resultMap>

在以上示例中,<resultMap> 定义了一个名为 "userResultMap" 的结果映射,指定了 User 类型的结果。通过 <result> 标签可以指定列和对象属性之间的映射关系,通过 <association> 标签可以描述对象之间的关联关系

然后,在相应的 SQL 查询语句中,可以使用 <resultMap> 标签来引用定义好的结果映射:

XML 复制代码
<select id="selectUser" parameterType="int" resultMap="userResultMap">
  SELECT * FROM user WHERE id = #{id}
</select>

在以上示例中,<select> 标签的 resultMap 属性指定了结果映射为 "userResultMap"。

4.mybatis-config.xml核心配置文件

当使用MyBatis进行数据库操作时,我们需要一个mybatis-config.xml文件来配置MyBatis的相关设置。下面是一个简单的mybatis-config.xml配置文件的示例:

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>
  <!-- 引入数据库连接信息 -->
  <properties resource="db.properties" />
​
  <!-- 设置MyBatis执行环境 -->
  <environments default="development">
    <environment id="development">
      <!-- 使用JDBC事务管理器 -->
      <transactionManager type="JDBC" />
​
      <!-- 数据库连接池 -->
      <dataSource type="POOLED">
        <!-- 配置数据库连接信息 -->
        <property name="driver" value="${db.driver}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
      </dataSource>
    </environment>
  </environments>
​
  <!-- 注册Mapper接口 -->
  <mappers>
    <mapper resource="com/example/mapper/UserMapper.xml" />
  </mappers>
</configuration>

在上面的示例中,配置文件的主要部分如下:

  • 引入数据库连接信息:使用<properties>元素引入数据库连接信息配置文件(db.properties)。

  • 设置MyBatis执行环境:使用<environments><environment>元素来设置MyBatis的执行环境。在示例中,我们只配置了一个名为"development"的环境,使用JDBC事务管理器和连接池来管理数据库连接。

  • 注册Mapper接口:使用<mappers><mapper>元素来注册Mapper接口。在示例中,我们通过<mapper>标签中的resource属性来指定Mapper接口对应的XML文件路径(com/example/mapper/UserMapper.xml)。

5.单独使用的示例

当在Java中使用MyBatis进行数据库操作时,需要进行以下步骤:

  1. 导入MyBatis的相关依赖包。可以使用Maven或Gradle等构建工具来管理依赖。

  2. 创建一个MyBatis的配置对象,通常通过解析mybatis-config.xml配置文件来创建。

  3. 通过配置对象创建一个SqlSessionFactory,用于创建SqlSession。

  4. 通过SqlSession进行数据库操作,包括查询、插入、更新、删除等。

下面是一个简单的示例演示如何使用MyBatis进行数据查询:

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
​
public class MyBatisExample {
  public static void main(String[] args) {
    // 读取MyBatis配置文件
    try (InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
      // 创建MyBatis配置对象
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​
      // 创建SqlSession
      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
        // 执行查询操作
        List<User> userList = sqlSession.selectList("com.example.mapper.UserMapper.getAllUsers");
​
        // 打印查询结果
        for (User user : userList) {
          System.out.println(user);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

在上面的示例中,我们首先通过Resources.getResourceAsStream()方法加载mybatis-config.xml配置文件。然后使用SqlSessionFactoryBuilder类创建SqlSessionFactory对象来构建SqlSession。最后,使用SqlSession对象执行查询操作并打印结果。

6.在spring中的使用

在Spring中使用MyBatis,可以使用注解配置来整合它们。以下是使用注解配置的示例:

  1. 导入MyBatis和Spring的相关依赖包。可以使用Maven或Gradle等构建工具来管理依赖。

  2. 创建一个MyBatis的配置对象,并配置数据源。

  3. 在Spring的配置类中,配置数据源和SqlSessionFactoryBean,并将MyBatis的配置对象注入到SqlSessionFactoryBean中。同时,使用MapperScan注解扫描Mapper接口所在的包。

  4. 在需要使用数据库操作的地方,注入Mapper接口,通过调用Mapper接口的方法来进行数据库操作。

下面是一个简单的示例演示如何在Spring中使用MyBatis进行数据查询:

java 复制代码
// UserMapper.java
@Mapper
public interface UserMapper {
  @Select("SELECT * FROM user")
  List<User> getAllUsers();
}
​
// UserService.java
@Service
public class UserService {
  @Autowired
  private UserMapper userMapper;
​
  public List<User> getAllUsers() {
    return userMapper.getAllUsers();
  }
}
​
// ApplicationConfig.java
@Configuration
@MapperScan("com.example.mapper")
public class ApplicationConfig {
  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase");
    dataSource.setUsername("root");
    dataSource.setPassword("password");
    return dataSource;
  }
​
  @Bean
  public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    return sessionFactory;
  }
}
​
// Main.java
public class Main {
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
    UserService userService = context.getBean(UserService.class);
    List<User> userList = userService.getAllUsers();
    for (User user : userList) {
      System.out.println(user);
    }
  }
}

在上面的示例中,我们使用了@Mapper注解标记了UserMapper接口,并使用@Select注解定义了查询方法。然后在UserService中注入了UserMapper接口,并在Main类中使用UserService来进行数据库操作。

在Spring的配置类ApplicationConfig中,我们使用@Configuration注解标记了配置类,并使用@MapperScan注解扫描了Mapper接口所在的包

8.事务的使用

在MyBatis中使用事务,可以使用以下几种方式:

  1. 编程式事务管理:

    • 在需要进行事务管理的方法上加上@Transactional注解,表示该方法需要在事务中执行。

    • 在方法内部通过SqlSessionFactoryopenSession方法来获取一个SqlSession对象,并设置true来开启自动提交事务。

    • 在需要提交事务时,调用commit()方法来提交事务;发生异常时,调用rollback()方法来回滚事务。

  2. 声明式事务管理:

    • 在Spring的配置文件中,配置一个事务管理器(例如使用DataSourceTransactionManager)。

    • 通过在需要进行事务管理的类或方法上加上@Transactional注解,表示该类或方法需要在事务中执行。

下面是一个简单的示例演示如何在MyBatis中使用编程式事务管理:

java 复制代码
@Service
public class UserService {
  @Autowired
  private UserMapper userMapper;
​
  @Transactional
  public void insertUser(User user) {
    try {
      // 开启事务
      SqlSession sqlSession = userMapper.getSqlSessionFactory().openSession(true);
      userMapper.setSqlSession(sqlSession);
​
      // 执行数据库操作
      userMapper.insertUser(user);
​
      // 提交事务
      sqlSession.commit();
    } catch (Exception e) {
      // 回滚事务
      sqlSession.rollback();
      throw e;
    }
  }
}

9.整合druid连接池

如果不使用Spring Boot,可以使用MyBatis和Druid的原生配置方式实现整合。

首先,需要在pom.xml中添加MyBatis和Druid的依赖

XML 复制代码
<!-- MyBatis依赖 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>

<!-- Druid依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>

接下来,创建MyBatis的配置文件mybatis-config.xml,并添加Druid的数据源配置:

XML 复制代码
<!-- mybatis-config.xml -->
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据源 -->
            <dataSource type="com.alibaba.druid.pool.DruidDataSource">
                <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/test" />
                <property name="username" value="root" />
                <property name="password" value="password" />
                <!-- 常用的连接池参数配置 -->
                <property name="initialSize" value="5" />
                <property name="maxActive" value="20" />
                <property name="minIdle" value="5" />
                <property name="maxWait" value="60000" />
                <property name="timeBetweenEvictionRunsMillis" value="60000" />
                <property name="minEvictableIdleTimeMillis" value="300000" />
                <property name="validationQuery" value="SELECT 1 FROM DUAL" />
                <property name="testWhileIdle" value="true" />
                <property name="testOnBorrow" value="false" />
                <property name="testOnReturn" value="false" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 配置Mapper接口所在的包路径 -->
        <package name="com.example.mapper" />
    </mappers>
</configuration>

然后,在代码中通过代码配置加载MyBatis的配置文件和Mapper接口:

java 复制代码
public class Application {
​
    public static void main(String[] args) throws IOException {
        // 创建数据源
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
​
        // 创建SqlSessionFactory
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
        sessionFactory.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
​
        // 创建MapperScannerConfigurer
        MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
        scannerConfigurer.setBasePackage("com.example.mapper");
        scannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
​
        // 创建Spring容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Application.class);
        context.getBeanFactory().registerSingleton("sqlSessionFactory", sessionFactory.getObject());
        context.getBeanFactory().registerSingleton("mapperScannerConfigurer", scannerConfigurer);
        context.refresh();
​
        // 使用Mapper接口
        UserMapper userMapper = context.getBean(UserMapper.class);
        User user = userMapper.getUserById(1L);
        System.out.println(user.getUsername());
​
        context.close();
    }
}

最后,在Mapper接口中使用@Mapper注解标识为MyBatis的映射接口,并使用@Select和@Insert等注解配置SQL语句,与Spring Boot中的使用方式相同。同时,需要在Mapper接口所在的包路径中添加相应的Mapper XML文件,例如UserMapper.xml。

10.整合druid在配置类中配置

可以通过配置类的方式来实现MyBatis和Druid的整合,并配置连接池的一些常用参数。

首先,需要在pom.xml中添加MyBatis和Druid的依赖,与之前的方式相同。

接下来,创建一个配置类来配置MyBatis和Druid的相关内容:

java 复制代码
@Configuration
@MapperScan(basePackages = "com.example.mapper", sqlSessionTemplateRef = "sqlSessionTemplate")
public class MyBatisConfig {
​
    @Value("${spring.datasource.url}")
    private String url;
​
    @Value("${spring.datasource.username}")
    private String username;
​
    @Value("${spring.datasource.password}")
    private String password;
​
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
​
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        // 配置其他连接池参数
        dataSource.setInitialSize(5);
        dataSource.setMaxActive(20);
        dataSource.setMinIdle(5);
        dataSource.setMaxWait(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(300000);
        dataSource.setValidationQuery("SELECT 1 FROM DUAL");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        return dataSource;
    }
​
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
        return sessionFactory.getObject();
    }
​
    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

在配置类中,通过@Value注解来获取配置文件中的相关参数,并创建DruidDataSource作为数据源。然后,再创建SqlSessionFactory和SqlSessionTemplate,并将它们注入到Spring容器中。

接着,在Mapper接口中使用@Mapper注解标识为MyBatis的映射接口,并使用@Select和@Insert等注解配置SQL语句,与Spring Boot中的使用方式相同。同时,需要在Mapper接口所在的包路径中添加相应的Mapper XML文件,例如UserMapper.xml

最后,在主类中通过注解开启Spring容器,并使用Mapper接口进行数据库操作:

java 复制代码
public class Application {
​
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyBatisConfig.class);
​
        // 使用Mapper接口
        UserMapper userMapper = context.getBean(UserMapper.class);
        User user = userMapper.getUserById(1L);
        System.out.println(user.getUsername());
​
        ((AnnotationConfigApplicationContext) context).close();
    }
}

四.springmvc

概念:

Spring MVC是一个基于Java的Web框架 ,用于开发Web应用程序 。它是Spring Framework的一部分 ,提供了一种模型-视图-控制器 (Model-View-Controller,MVC)的架构模式来组织和管理Web应用程序的代码。

以下是Spring MVC的一些关键概念:

  1. **控制器(Controller):**控制器负责接收和处理用户请求,并根据请求的内容执行相应的业务逻辑。它通常使用注解来标识请求处理方法。

  2. **模型(Model):**模型代表Web应用程序中用于处理数据和业务逻辑的对象。它可以是一个Java对象或者一个POJO(Plain Old Java Object)。模型对象的数据可以从数据库、文件、外部API等来源获取。

  3. **视图(View):**视图负责展示模型数据给用户,通常是一个HTML页面或者其他类型的视觉表现形式。它可以通过模板引擎(如Thymeleaf、FreeMarker等)来处理动态内容。

  4. 视图解析器(View Resolver):视图解析器负责将逻辑视图名映射为实际的视图对象。它可以根据配置找到匹配的视图模板,并将模型数据合并到视图中生成最终的响应内容。

  5. 处理器适配器(Handler Adapter):处理器适配器负责将控制器和请求进行适配,使得控制器能够正确地处理请求。它根据控制器的类型和请求的类型选择合适的适配器。

  6. 拦截器(Interceptor):拦截器可以在请求处理的各个阶段进行预处理和后处理操作。它可以用于执行一些通用的任务,如日志记录、权限验证等。

  7. 视图解析器(View Resolver):视图解析器负责将逻辑视图名映射为实际的视图对象。它可以根据配置找到匹配的视图模板,并将模型数据合并到视图中生成最终的响应内容。

  8. 数据绑定(Data Binding):数据绑定允许将请求参数自动绑定到控制器方法的参数或模型对象的属性上。它通过将请求参数转换为相应的数据类型来简化数据处理。

Spring MVC提供了丰富的功能和扩展性,使得开发人员可以高效地构建、测试和维护Web应用程序。

1.springmvc的在javaweb中的单独使用

以下是一个简单的Spring MVC示例:

  1. 创建Maven项目并引入依赖:
XML 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.10</version>
</dependency>
  1. 配置web.xml文件:
XML 复制代码
<web-app>
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  1. 创建spring-mvc.xml文件:
XML 复制代码
<context:component-scan base-package="com.example.controller" />
    
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>
  1. 创建Controller类:
java 复制代码
@Controller
public class HelloWorldController {
    
    @RequestMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello World!");
        return "hello";
    }
}
  1. 创建视图文件hello.jsp:
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>${message}</h1>
</body>
</html>

这个示例中创建了一个简单的Controller类HelloWorldController,其中定义了一个请求路径为/hello的方法hello。该方法使用Model对象将消息添加到模型中,并返回视图名称hello

在视图hello.jsp中,使用EL表达式${message}来显示传递的消息。

启动项目后,在浏览器中访问http://localhost:8080/hello,将会显示"Hello World!"的消息。

2.springmvc在spring中的使用

以下是一个完全基于注解配置的Spring整合Spring MVC的示例,前端不使用JSP,返回数据为JSON:

  1. 创建Maven项目并引入必要依赖:
html 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.10</version>
</dependency>
  1. 创建Java配置类AppConfig,包含如下内容:
java 复制代码
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class AppConfig implements WebMvcConfigurer {
​
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp(); // 禁用JSP视图解析器
    }
​
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable(); // 启用默认的Servlet处理器
    }
​
    @Bean
    public MappingJackson2HttpMessageConverter jsonConverter() {
        return new MappingJackson2HttpMessageConverter();
    }
​
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jsonConverter()); // 注册Json转换器
    }
}
  1. 创建Controller类:
java 复制代码
@RestController
public class HelloWorldController {
​
    @RequestMapping("/hello")
    public Map<String, String> hello() {
        Map<String, String> response = new HashMap<>();
        response.put("message", "Hello World!");
        return response;
    }
}
  1. 启动项目后,在浏览器中访问http://localhost:8080/hello,将会返回一个JSON对象:
java 复制代码
{
  "message": "Hello World!"
}

在这个示例中,配置类AppConfig中禁用了JSP视图解析器,启用了默认的Servlet处理器,并注册了一个MappingJackson2HttpMessageConverter,用于将Controller方法返回的对象自动转换为JSON

3.springmvc的参数日期格式转换

在Spring MVC中,可以使用@DateTimeFormat注解和Converter进行日期的转换。

首先,在Controller中的方法参数上使用@DateTimeFormat注解进行日期格式的指定,如下所示

java 复制代码
@RequestMapping("/hello")
public String hello(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
    // 处理日期参数
    return "hello";
}

在上述示例中,@DateTimeFormat中的pattern属性指定了日期的格式。

接下来,创建一个自定义的日期转换器实现Converter接口,用于将字符串转换为java.util.Date类型。示例如下:

java 复制代码
@Component
public class StringToDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return dateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

在上述示例中,StringToDateConverter实现了将字符串转换为java.util.Date类型的逻辑,使用SimpleDateFormat进行字符串到日期的转换。

最后,在配置类中注册日期转换器,如下所示:

java 复制代码
@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Autowired
    private StringToDateConverter stringToDateConverter;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(stringToDateConverter);
    }
}

在上述配置中,通过addConverter方法将自定义的日期转换器注册到FormatterRegistry中。

这样,在使用@DateTimeFormat注解指定日期格式的方法参数上,Spring MVC会自动将字符串转换为对应的日期类型

4.全局日期参数自动转换

要在Spring MVC中全局有效地自定义日期消息转换器,你可以按照以下步骤进行操作:

首先,创建一个类实现HandlerMethodArgumentResolver接口,用于自定义日期消息转换逻辑。示例如下:

java 复制代码
@Component
public class CustomDateArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Date.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String parameterValue = webRequest.getParameter(parameter.getParameterName());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.parse(parameterValue);
    }
}

在上述示例中,CustomDateArgumentResolver实现了自定义日期消息转换逻辑,在resolveArgument方法中,将请求中携带的日期字符串转换为java.util.Date类型。

然后,在配置类中注册自定义的日期消息转换器,如下所示:

java 复制代码
@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Autowired
    private CustomDateArgumentResolver customDateArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(customDateArgumentResolver);
    }
}

在上述配置中,通过addArgumentResolvers方法将自定义的日期消息转换器添加到Spring MVC的参数解析器列表中。

这样,不需要使用@DateTimeFormat注解,全局有效地自定义日期消息转换器就会生效,Spring MVC会自动将请求中的日期字符串转换为对应的日期类型

5.拦截器

在Spring MVC中,拦截器是一种机制,用于在请求处理的不同阶段进行拦截和处理。拦截器可以在请求进入Controller之前或者之后进行一些处理,例如身份验证、日志记录、权限校验等。以下是在Spring MVC中使用拦截器的步骤:

  1. 创建一个实现HandlerInterceptor接口的拦截器类,示例如下
java 复制代码
@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在Controller处理请求之前进行拦截处理
        // 返回true表示继续执行后续的拦截器和请求处理,返回false表示终止请求处理流程
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在Controller处理请求之后、视图渲染之前进行拦截处理
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在视图渲染之后进行拦截处理,进行资源清理等操作
    }
}

在上述示例中,CustomInterceptor类实现了HandlerInterceptor接口,并通过preHandlepostHandleafterCompletion方法可以在请求处理的不同阶段进行对应的拦截处理。

  1. 在配置类中注册拦截器:
java 复制代码
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private CustomInterceptor customInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor).addPathPatterns("/**");
    }
}

在上述配置中,通过addInterceptors方法将自定义的拦截器注册到Spring MVC的拦截器列表中,使用addPathPatterns方法指定拦截的URL路径。

通过以上步骤,就可以在Spring MVC中使用拦截器来拦截和处理请求。拦截器可以在Controller之前或者之后进行一些通用的处理逻辑,提供了一种灵活且低耦合的机制来增强应用

6.拦截器的路径配置

在Spring MVC中,拦截器的路径配置可以通过以下方式来实现:

  1. 拦截所有请求
java 复制代码
registry.addInterceptor(customInterceptor).addPathPatterns("/**");

通过使用"**"作为路径模式,可以拦截应用中的所有请求。这样配置的拦截器将会应用于所有的请求路径。

  1. 拦截指定路径的请求:
java 复制代码
registry.addInterceptor(customInterceptor).addPathPatterns("/path1", "/path2");

可以使用字符串参数来指定拦截器要拦截的具体路径。在上述示例中,拦截器将会应用于路径为/path1/path2的请求。

  1. 拦截特定路径下的所有请求
java 复制代码
registry.addInterceptor(customInterceptor).addPathPatterns("/api/*");

可以使用通配符"*"来匹配路径的部分内容。在上述示例中,拦截器将会应用于以/api/开头的所有请求路径。

  1. 排除拦截某些请求路径
java 复制代码
registry.addInterceptor(customInterceptor).excludePathPatterns("/path1", "/path2");

除了指定拦截的路径外,还可以使用excludePathPatterns方法来排除某些路径不被拦截。在上述示例中,拦截器将不会应用于路径为/path1/path2的请求

通过以上方式,可以灵活地配置拦截器的路径,以满足不同场景下的需求。

7.拦截器和过滤器的区别

拦截器和过滤器是在Web开发中常用的两种组件,它们的作用都是对请求进行处理和拦截,但是在实现机制上有一些区别。

  1. 生命周期:
  • 过滤器(Filter)是Servlet规范中的一部分,在请求进入Servlet容器之后、进入Servlet之前,以及响应返回客户端之前的各个阶段都可以通过过滤器进行处理。过滤器的生命周期由Servlet容器管理,即在容器启动时就会被加载,请求结束后被销毁。

  • 拦截器(Interceptor)是Spring MVC框架中的一部分,它的生命周期由Spring容器管理。拦截器在DispatcherServlet前后以及Controller处理请求之前和之后进行拦截。

  1. 执行顺序:
  • 过滤器(Filter)在请求进入Servlet容器之后第一个执行,然后按照指定的顺序依次执行后续过滤器。最后在请求返回客户端之前,以相反的顺序执行过滤器的销毁方法。

  • 拦截器(Interceptor)在请求进入Servlet之前和Controller处理请求之前执行,然后按照指定的顺序依次执行后续拦截器。再在Controller处理请求之后、视图渲染之前执行,最后以相反的顺序执行拦截器的销毁方法。

  1. 使用范围:
  • 过滤器(Filter)可以对所有的请求进行拦截,包括静态资源和动态请求。它是在Servlet容器级别进行拦截,所以可以拦截任何类型的请求。

  • 拦截器(Interceptor)通常用于拦截对应用中的指定请求进行处理。它是在Web框架级别进行拦截,所以只能拦截到由该框架进行处理的请求。

总的来说,过滤器(Filter)是对请求进行全局的处理和拦截,适合处理一些与业务无关的通用逻辑,如字符编码、安全认证、日志记录等。拦截器(Interceptor)更加灵活,它是在框架级别进行拦截,适合处理与业务相关的请求处理逻辑,如权限验证、日志记录、事务管理等

8.跨域配置

在Spring MVC中配置跨域请求可以通过两种方式实现

  1. 使用注解@Configuration和类CorsRegistry 创建一个配置类,使用@Configuration注解标注该类,然后定义一个方法来配置跨域请求。在该方法上添加@Bean注解,返回一个WebMvcConfigurer对象,通过重写addCorsMappings方法来配置跨域请求的规则。

例子:

java 复制代码
@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins("http://localhost:8080")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedHeaders("*")
                        .allowCredentials(false)
                        .maxAge(3600);
            }
        };
    }
}

上述例子中,配置了允许来自"http://localhost:8080"的跨域请求访问"/api/**"路径下的资源,并指定了允许的请求方法、请求头、是否允许携带凭证和预检请求的缓存时间。

  1. 使用过滤器实现跨域请求 创建一个过滤器,在doFilter方法中添加相关的跨域请求处理逻辑,并在web.xml或Servlet注册类中配置该过滤器。

例子:

java 复制代码
@WebFilter(urlPatterns = "/*")
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
​
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "false");
​
        chain.doFilter(req, res);
    }
}

9.放行静态资源

在Spring MVC中,如果需要放行静态资源,可以通过配置WebMvcConfigurer的addResourceHandlers方法来实现。

在你的配置类中,添加如下代码:

java 复制代码
@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}

上述例子中,配置了访问路径为"/static/"**的静态资源,并将它们的位置设置为"classpath:/static/"。

假设你的静态资源都位于src/main/resources/static目录下,那么你可以直接在浏览器中访问http://localhost:8080/static/xxx.xxx 来获取静态资源(这里的xxx.xxx是静态资源文件名)。

这样配置之后,Spring MVC会优先匹配静态资源的访问路径,如果匹配成功则返回对应的静态资源,如果不匹配则继续匹配其他的请求路径

五.springboot

概念:

Spring Boot是一个用于创建和部署独立、生产级别的Spring应用程序的框架 。它是基于Spring框架的扩展 ,旨在简化Spring应用程序的开发和配置。下面是Spring Boot的一些关键概念:

  1. 自动配置(Auto-configuration) :Spring Boot采用了约定大于配置 的原则,根据应用程序的依赖关系**自动配置Spring和第三方库。**通过自动配置,开发人员可以更方便地快速启动和部署应用程序。

  2. 起步依赖(Starter Dependencies):Spring Boot提供了一系列的"起步依赖",这些依赖可以为特定的场景或应用程序类型提供必需的库和配置。开发人员可以根据自己的需求选择合适的起步依赖,而不需要手动引入和配置依赖。

  3. 嵌入式服务器(Embedded Server):Spring Boot内置了多种嵌入式服务器,如Tomcat、Jetty等。开发人员可以将应用程序打包成一个可执行的JAR文件,并直接运行,而不需要额外安装和配置服务器。

  4. 简化的配置(Configuration Simplification):Spring Boot通过提供默认配置和约定大于配置的原则,减少了开发人员需要编写的配置代码。开发人员可以通过application.properties或application.yml文件进行自定义配置。

  5. 健康检查(Health Check):Spring Boot提供了健康检查功能,开发人员可以通过HTTP端点或管理界面查看应用程序的健康状态。这对于监控和故障排除非常有帮助。

  6. 外部化配置(Externalized Configuration):Spring Boot支持将应用程序的配置从代码中分离出来,可以使用环境变量、属性文件、命令行参数等多种方式进行配置。这使得应用程序的配置更加灵活和易于管理。

Spring Boot的目标是让开发人员能够更快、更容易地创建独立的、生产级别的Spring应用程序。它提供了丰富的功能和扩展性,同时保持了Spring框架的灵活性和强大性。

1.springboot的搭建

要在IntelliJ IDEA中快速搭建一个Spring Boot项目,可以按照以下步骤进行操作:

  1. 打开IntelliJ IDEA,点击 "Create New Project"(或者在欢迎界面点击 "New Project")

  2. 在弹出的 "New Project" 窗口中,选择 "Spring Initializr" 选项,并点击 "Next"

  3. 在下一个界面中,选择以下配置项:

    • 选择项目类型为 "Maven"

    • 填写 "Group" 和 "Artifact" 信息,作为项目的唯一标识,一般以com.xxx

    • 选择项目的 "Language",选择 Java

  4. 选择项目的默认配置项,如"Packaging"(打包方式)为jar包

  5. 在 "Project SDK" 配置中,选择您已经安装好的 Java ,jdk版本为8。

  6. 点击 "Next",然后选择项目的名称和保存路径

  7. 点击 "Finish",IntelliJ IDEA 将会根据您的配置下载所需的依赖项并创建项目

  8. 创建完成后,可以在项目的 "src/main/java" 目录下找到启动类(例如:DemoApplication.java),这是一个 Spring Boot 应用的入口类

  9. 在main下面新建一个resources目录,然后在该目录中新建一个application.yml配置文件,该文件为springboot的配置文件

2.springboot中开发web项目的依赖

在pom.xml文件中引入依赖:

(1).引入springmvc依赖
  1. <dependencies> 标签内添加如下依赖项:
XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
(2).引入mysql连接依赖**
XML 复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

(3)引入druid启动依赖

XML 复制代码
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>xxx</version><!-- 替换为最新版本号 -->
</dependency>
(4).引入mybatis-plus依赖**
XML 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>{版本号}</version>
</dependency>
(5).引入lombok依赖
XML 复制代码
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>{版本号}</version>
</dependency>

以上就可以基本实现一个增删改查的项目了

3.对以上依赖的相关配置

application.yml文件中添加相关配置

(1)对端口配置
XML 复制代码
server:
  port:  8080
(2).对mysql和druid连接池配置
XML 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydatabase
    username: root
    password: your_password
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource  # 指定使用Druid数据源
    druid:
      initial-size: 5  # 初始连接数
      min-idle: 5  # 最小空闲连接数
      max-active: 20  # 最大活跃连接数
      test-on-borrow: false  # 从连接池中取出连接时是否进行测试,默认为false
      filters: stat,wall  # 过滤器配置,可根据需要添加更多过滤器
(3)对mybatis-plus的配置
XML 复制代码
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  global-config:
    db-config:
      id-type: auto  # 主键生成策略,可选值有:AUTO、INPUT、ID_WORKER、ID_WORKER_STR、UUID、NONE
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰命名转换

其他配置看上面的mybatis-plus配置

好了,以上就对基本的相关做了配置,下面我们来做一个简单示例:

4.springboot的简单示例
  1. 创建实体类 创建一个名为 User 的实体类,同时使用 Lombok 的 @Data 注解标记该类,并指定表名为 tb_user,标记 id 为主键,策略为雪花。代码如下:
java 复制代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
​
@Data
@TableName("tb_user")
public class User {
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    private String username;
    private String password;
}
  1. 创建 Mapper 接口 mapper 包下 创建名为 UserMapper 的接口,继承 BaseMapper 接口,并为 User 实体类指定泛型。代码如下:
java 复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
​
@Repository
public interface UserMapper extends BaseMapper<User> {
}
  1. 创建 Service 接口和实现类 service 包下 创建名为 UserService 的接口,继承 IService 接口,并为 User 实体类指定泛型。代码如下:
java 复制代码
import com.baomidou.mybatisplus.extension.service.IService;
​
public interface UserService extends IService<User> {
    // 可自行定义其他业务方法
}

接着,service.impl 下创建名为 UserServiceImpl 的实现类,继承 ServiceImpl 类,并为 User 实体类和 UserMapper 接口指定泛型。代码如下:

java 复制代码
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
​
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
​
    @Override
    public boolean saveUser(User user) {
        return save(user);
    }
​
    @Override
    public boolean updateUser(User user) {
        return updateById(user);
    }
​
    @Override
    public boolean deleteUser(String id) {
        return removeById(id);
    }
​
    @Override
    public User getUserById(String id) {
        return getById(id);
    }
​
    @Override
    public List<User> getAllUsers() {
        return list();
    }
​
    @Override
    public List<User> getUsersByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return list(queryWrapper);
    }
}
  1. 创建 Controller 类 controller 下创建名为 UserController 的类,使用 @RestController 注解标识该类为控制器类,代码如下:
java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
​
@RestController
@RequestMapping("/users")
public class UserController {
​
    @Autowired
    private UserService userService;
​
    @PostMapping
    public boolean saveUser(@RequestBody User user) {
        userService.save(user);
    }
​
    @PutMapping
    public boolean updateUser(@RequestBody User user) {
        userService.updateById(user);
    }
​
    @DeleteMapping("/{id}")
    public boolean deleteUser(@PathVariable String id) {
        userService.removeById(id);
    }
​
    @GetMapping("/{username}")
    public List<User> getUserById(@PathVariable String username) {
        return userService.getByUserName(username);
    }
}

这样,您已经完成了一个简单的增删改查示例。请确保正确配置数据库连接信息和 MyBatis Plus 的配置,以及各个包的扫描路径等

5.分页查询示例
  1. 创建一个配置类 MyBatisPlusConfig,配置分页拦截器:
java 复制代码
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
@Configuration
public class MyBatisPlusConfig {
​
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
  1. 创建一个分页查询的 Controller:
java 复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
public class UserController {
​
    @Autowired
    private UserService userService;
​
    @GetMapping("/users")
    public IPage<User> getUsersByPage(@RequestParam(defaultValue = "1") Integer pageNum,
                                      @RequestParam(defaultValue = "10") Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return userService.page(page);
    }
}
  1. 创建一个 Service 接口和实现类,使用 MyBatis-Plus 提供的分页查询方法:
java 复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
​
public interface UserService extends IService<User> {
​
    IPage<User> getUsersByPage(Integer pageNum, Integer pageSize);
}
​
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
​
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
​
    @Override
    public IPage<User> getUsersByPage(Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return baseMapper.selectPage(page, null);
    }
}
6.LambdQueryWrapper

好的,下面是使用 LambdaQueryWrapper 进行模糊查询、等值查询和比较查询的示例:

  1. 模糊查询示例:
java 复制代码
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
public class UserController {
​
    @Autowired
    private UserService userService;
​
    @GetMapping("/users")
    public List<User> getUsers(@RequestParam String keyword) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(User::getUsername, keyword);
        return userService.list(lambdaQueryWrapper);
    }
}

在上面的示例中,我们使用 like 方法进行模糊查询,查询条件为 username 字段中包含关键字的记录。使用 LambdaQueryWrapper 可以直接通过实体类的属性进行字段的操作。

  1. 等值查询示例:
java 复制代码
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
public class UserController {
​
    @Autowired
    private UserService userService;
​
    @GetMapping("/users")
    public List<User> getUsers(@RequestParam Integer age) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAge, age);
        return userService.list(lambdaQueryWrapper);
    }
}

在上面的示例中,我们使用 eq 方法进行等值查询,查询条件为 age 字段等于给定的年龄值。

  1. 比较查询示例:
java 复制代码
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
public class UserController {
​
    @Autowired
    private UserService userService;
​
    @GetMapping("/users")
    public List<User> getUsers(@RequestParam Integer minAge, @RequestParam Integer maxAge) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.between(User::getAge, minAge, maxAge);
        return userService.list(lambdaQueryWrapper);
    }
}

在上面的示例中,我们使用 between 方法进行比较查询,查询条件为 age 字段在给定的最小年龄值和最大年龄值之间的记录。

7.springboot中配置跨域

在Spring Boot中配置跨域请求可以通过以下几种方式来实现:

  1. 使用@CrossOrigin注解:可以在具体的Controller类或者某个特定的方法上使用此注解来配置跨域请求。
java 复制代码
@RestController
@CrossOrigin(origins = "http://localhost:8080")
public class MyController {
    // Controller的方法
}

上述代码将允许来自http://localhost:8080的跨域请求访问该Controller。

  1. 使用全局配置CorsFilter:创建一个全局过滤器来处理跨域请求,在WebConfig类中进行配置。
java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
​
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://localhost:8080");
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

上述代码中,config.addAllowedOrigin("http://localhost:8080")指定了允许跨域请求的源。config.addAllowedMethod("*")允许所有HTTP方法,config.addAllowedHeader("*")允许所有头部信息。

  1. 使用自定义拦截器:可以创建一个拦截器来处理跨域请求,在拦截器中完成相关配置。
java 复制代码
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
​
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

上述代码中,通过重写addCorsMappings方法来添加跨域配置。

相关推荐
FF在路上27 分钟前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
真的很上进34 分钟前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
众拾达人1 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.1 小时前
Mybatis-Plus
java·开发语言
不良人天码星1 小时前
lombok插件不生效
java·开发语言·intellij-idea
守护者1701 小时前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云2 小时前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络2 小时前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。2 小时前
Docker学习
java·开发语言·学习
如若1232 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python