SSM整合配置模板

Maven依赖

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <junit.version>5.7.1</junit.version>
    <servlet.version>4.0.1</servlet.version>
    <mysql.version>8.0.25</mysql.version>
    <druid.version>1.2.5</druid.version>
    <mybatis.version>3.5.7</mybatis.version>
    <spring.version>5.3.8</spring.version>
    <jackson.version>2.12.3</jackson.version>
    <mbg.version>1.4.0</mbg.version>
    <jstl.version>1.2</jstl.version>
    <taglibs.version>1.2.5</taglibs.version>
    <servlet.version>4.0.1</servlet.version>
    <apspectj.version>1.9.6</apspectj.version>
    <hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
    <pagehelper.version>5.2.0</pagehelper.version>
    <mybatis-spring.version>2.0.6</mybatis-spring.version>
    <mybatis-ehcache.version>1.2.1</mybatis-ehcache.version>
    <sl4j.version>1.7.31</sl4j.version>
    <aspectj.version>1.9.6</aspectj.version>
    <logback.version>1.2.3</logback.version>
    <lombok.version>1.18.20</lombok.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- JSTL标签 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>${taglibs.version}</version>
        </dependency>

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Junit单元测试 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring MVC模块 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- Spring ORM模块 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- Spring测试模块(整合Junit) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- aspectj解析切入点表达式 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${apspectj.version}</version>
        </dependency>

        <!-- hibernate-validator支持JSR303数据校验 -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${hibernate-validator.version}</version>
        </dependency>

        <!-- PageHelper分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>${pagehelper.version}</version>
        </dependency>
        <!-- Mybatis Generator代码生成器 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mbg.version}</version>
        </dependency>
        <!-- mybatis-spring适配包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis-spring.version}</version>
        </dependency>
        <!-- Mybatis操作数据库 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- mybatis-ehcache适配包 -->
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>${mybatis-ehcache.version}</version>
        </dependency>

        <!-- slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${sl4j.version}</version>
        </dependency>
        <!-- logback -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <!-- jcl-sl4j适配包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${sl4j.version}</version>
        </dependency>

        <!-- Jackson, 支持@RequestBody和@ResponseBody注解 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <!-- Lombok, 自动生成setter、getter、toString方法 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

    </dependencies>
</dependencyManagement>

数据库

Druid配置文件-dbconfig.properties

jdbc.url=jdbc:mysql://localhost:3306/${数据库名称}?userUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
jdbc.username=${用户名}
jdbc.password=${密码}

#监控统计用filter:stat, 日志用filter:log4j, 防御sql注入用filter:wall
jdbc.filters=stat

#最大连接数
jdbc.maxActive=20
#初始连接数
jdbc.initialSize=1
#获得连接时的最大等待时间
jdbc.minIdle=1

#它有两个作用:
#1.有个【Destroy线程】会每隔timeBetweenEvictionRunsMillis毫秒检测一下连接的空闲时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭连接, 直到连接池中的连接数为minIdle为止
#2.它也是testWhileIdle的判断依据,详细看testWhileIdle属性的说明
jdbc.timeBetweenEvictionRunsMillis=60000
#连接保持空闲而不被关闭的最小时间
jdbc.minEvictableIdleTimeMillis=300000

#用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。
#如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
jdbc.validationQuery=select 'x
#申请连接时,若连接的空闲时间>timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
jdbc.testWhileIdle=true
#申请连接时是否执行validationQuery
jdbc.testOnBorrow=false
#归还连接时是否执行validationQuery
jdbc.testOnReturn=false

#是否缓存PreparedStatement对象(mysql下false, oracle下true)
jdbc.poolPreparedStatements=false
#每个Connection能缓存的PreparedStatement的最大个数
jdbc.maxPoolPreparedStatementPerConnectionSize=-1



~~

Mybatis配置文件—mybatis-config.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="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启内嵌关联对象的懒加载(使用时再加载) -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 开启内嵌关联对象的轻度懒加载(只要外部对象的任一方法被调用, 就完全加载所有内嵌的关联对象) -->
        <setting name="aggressiveLazyLoading" value="true"/>
        <!-- 将null值映射为Jdbc类型的NULL, 而不是Other -->
        <setting name="jdbcTypeForNull" value="NULL"/>
        <!-- 加载所有映射文件中配置的全局缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 设置对于枚举类型, 默认使用哪个类型处理器, 默认是EnumTypeHandler -->
        <!--<setting name="defaultEnumTypeHandler" value="com.xxx.xxx.MyEnumTypeHandler"/>-->
        <!-- 打印SQL语句到控制台 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!-- 类型别名 -->
    <typeAliases>
        <package name="pers.oneice.ssm.crud"/>
    </typeAliases>

</configuration>


Ehcache配置文件-ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <!-- 缓存的磁盘保存路径 -->
    <diskStore path="D:/Temp/ehcache"/>

    <defaultCache
            maxElementsInMemory="1000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="3600"
            timeToLiveSeconds="3600"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            copyOnRead="true"
            copyOnWrite="true"
    />

    <!--
    属性说明:
    l diskStore:当内存中不够存储时,将数据存储到指定磁盘目录中。
    l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

    以下属性是必须的:
    l maxElementsInMemory - 在内存中缓存的element的最大数目
    l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
    l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
    l overflowToDisk - 设定当内存缓存溢出时, 是否将element缓存到磁盘上

    以下属性是可选的:
    copyOnRead - 设置为true后, 从缓存读数据时, 返回数据的序列化拷贝, 而不是数据本身, 默认false
    copyOnWrite - 设置为true后, 往缓存写数据时, 写入数据的序列化拷贝, 而不是数据本身, 默认false
    l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
    l timeToLiveSeconds - 缓存element的有效生命期, 默认是0, 也就是element存活时间无穷大
     diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
    l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
    l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔, 默认是120秒。
    l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
 -->

</ehcache>


MBG配置文件—mbg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!-- 数据库驱动包(如果classpath下已有则可以忽略) -->
    <!--<classPathEntry location="D:/SQL/mysql-8.0.22-winx64/mysql-connector-java-8.0.15.jar"/>-->

    <!--MBG上下文配置
        id: 上下文id
        TODO: 选择合适的targetRuntime
        targetRuntime: 指定要按照哪种形式去生成Java代码, 默认值Mybatis3
                        Mybatis3 生成基本的增删改查, 还会生成"xxxByExample"方法的动态SQL
                        MyBatis3Simple 只生成基本的增删改查
        defaultModelType: 要如何生成实体类, 默认值conditional
                          conditional 和hierarchical类似, 只是当主键列只有一个时, 不会生成只包含主键的实体类
                          flat 只为每张表生成一个实体类(推荐使用)
                          hierarchical 生成三个实体类, 一个只包含主键, 一个只包含BLOB字段, 一个包含其他剩余字段
    -->
    <context id="MyGenerator" targetRuntime="Mybatis3" defaultModelType="flat">
        <!-- 自动给关键字添加分隔符 -->
        <property name="autoDelimitKeywords" value="true"/>
        <!-- 前缀分隔符 -->
        <property name="beginningDelimiter" value="`"/>
        <!-- 后置分隔符 -->
        <property name="endingDelimiter" value="`"/>
        <!-- Java文件编码 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- Java文件格式 -->
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <!-- XML文件格式 -->
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

        <!-- TODO: 根据个人需求选择合适的插件 -->
        <!-- 生成xxxMapper.xml时覆盖原文件, 而不是追加 -->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
        <!-- 生成Equals和HashCode方法 -->
        <!--<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>-->
        <!-- 实现Serializable接口 -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 生成toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

        <!--生成注释-->
        <commentGenerator>
            <!-- 完全禁止生成注释 -->
            <property name="suppressAllComments" value="true"/>
            <!-- 禁止生成时间戳注释 -->
            <property name="suppressDate" value="true"/>
            <!-- 时间戳格式, 要符合SimpleDateFormat -->
            <!--<property name="dateFormat" value="yyyy/MM/dd HH:mm:ss"/>-->
            <!-- 注释是否包含对应表名或列名信息 -->
            <!--<property name="addRemarkComments" value="true"/>-->
        </commentGenerator>

        <!-- TODO: 配置MySQL数据库连接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm_crud?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8"
                        userId="root"
                        password="mysql123">
            <!-- 避免MySQL多次生成SQL映射文件 -->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <!-- 设置JDBC类型和Java类型的映射 -->
        <javaTypeResolver>
            <!--  true:使用BigDecimal对应DECIMAL和NUMERIC数据类型
                  false:默认值
                    scale>0;length>18:使用BigDecimal;
                    scale=0;length[10,18]:使用Long;
                    scale=0;length[5,9]:使用Integer;
                    scale=0;length<5:使用Short -->
            <property name="forceBigDecimals" value="false"/>
            <!-- 是否应该符合JSR-310日期类型, 还是说直接将日期映射成java.util.Date -->
            <property name="useJSR310Types" value="false"/>
        </javaTypeResolver>

        <!-- TODO: 生成Model实体类
            targetProject: 项目源码根目录
            targetPackage: 生成的实体类放在哪个包里
        -->
        <javaModelGenerator targetPackage="pers.oneice.ssm.crud.pojo" targetProject="src/main/java">
            <!-- 是否直接将实体类放在targetPackage包中(废话...) -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否生成有参构造函数
                注意, 当设置为true, 自动生成的resultMap也会采用构造函数来创建POJO, 而不是setter
             -->
            <property name="constructorBased" value="false"/>
            <!-- 是否删除查询结果的前后空格(体现在实体类的set方法中) -->
            <property name="trimStrings" value="false"/>
            <!-- 生成的实体类属性是否不可变 -->
            <property name="immutable" value="false"/>
            <!-- 设置所有实体类的基类 -->
            <!--<property name="rootClass" value=""/>-->
        </javaModelGenerator>

        <!-- TODO: 生成SQL映射文件 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- TODO: 生成映射器接口 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="pers.oneice.ssm.crud.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- TODO: 要逆向分析的表, 多张表需要配置多个table标签
             tableName: 表名
             domainObjectName: 要生成的实体类名称, 会影响【实体类/映射器接口/映射文件】的名称
             可选属性:
                alias: 设置【表别名】和【列别名前缀】
                mapperName: 设置【映射器接口】和【映射文件】的名称
                enableXxx: 是否要为映射器生成Xxx方法, 默认true
        -->
        <table tableName="tb_dept" domainObjectName="Department">
            <!-- 插入数据之后获取自增主键值 -->
            <generatedKey column="dept_id" identity="true" type="post" sqlStatement="MySql"/>
            <!-- 重写列和属性的映射 -->
            <!--<columnOverride property="propertyName" column="LONG_VARCHAR_FIELD" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
            <!-- 忽略某些列的映射 -->
            <!--<ignoreColumn column=""/>-->
        </table>

        <table tableName="tb_emp" domainObjectName="Employee">
            <!-- 插入数据之后获取自增主键值 -->
            <generatedKey column="emp_id" identity="true" type="post" sqlStatement="MySql"/>
            <!-- 重写列和属性的映射 -->
            <columnOverride property="gender" column="gender" javaType="java.lang.Integer"
                            jdbcType="TINYINT"/>
        </table>

    </context>

</generatorConfiguration>


SQL映射文件—xxxMapper.xml

<?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.dao.EmployeeMapper">

    <!--Ehcache全局缓存-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
    
    
</mapper>

Web配置文件—web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置ContextLoaderListener, 加载Spring父容器 (父类的initWebApplicationContext()方法中)
        可以从ServletContext中根据 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 这个key来找到Spring容器
    -->
    <context-param>
        <!-- 指定Spring配置文件位置 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <!-- 该监听器将根据contextConfigLocation参数加载Spring配置文件, 初始化Spring应用上下文 -->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--
        配置DispatcherServlet, 加载Spring MVC子容器 (父类的initWebApplicationContext()方法中)
        可以从ServletContext中根据 FrameworkServlet.SERVLET_CONTEXT_PREFIX+Servlet名称 作为key来找到Spring MVC容器
    -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!-- 指定Spring MVC配置文件位置, 默认是 /WEB-INF/<servlet-name>-servlet.xml -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 随Tomcat一起启动 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- / 接收所有请求, 除了jsp -->
        <!-- /* 接收所有请求, 包括jsp -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置Spring Security权限控制的Filter -->
    <!-- 放在最前面!! -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置字符编码过滤器, 用于设置请求和响应的编码 -->
    <!-- 放在最前面!! -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--UTF-8编码-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <!-- 强制设置响应编码, 不强制设置请求编码(当请求中未指定编码时才设置) -->
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置HTTP方法过滤器, 实现REST风格的增删改查 -->
    <!-- 该过滤器根据指定的请求参数(默认是"_method")来修改请求的类型 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置表单内容过滤器, 实现REST风格的增删改查 -->
    <!-- 该过滤器会将PUT/PATCH/DELETE请求中的表单数据暴露成Servlet request parameters, 保证数据绑定器能获取到请求参数 -->
    <!-- 该过滤器和HiddenHttpMethodFilter配置其中一个即可 -->
    <!--<filter>-->
    <!--    <filter-name>FormContentFilter</filter-name>-->
    <!--    <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>-->
    <!--</filter>-->
    <!--<filter-mapping>-->
    <!--    <filter-name>FormContentFilter</filter-name>-->
    <!--    <url-pattern>/*</url-pattern>-->
    <!--</filter-mapping>-->

</web-app>

Spring配置文件—applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd 
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--配置Spring包扫描器, Spring负责管理数据源/事务控制/AOP/业务逻辑等操作 -->
    <context:component-scan base-package="com.oneice.crowdfunding">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController"/>
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestControllerAdvice"/>
    </context:component-scan>
    
    <!--============================数据源的配置============================-->
    <!-- 引入JDBC配置文件 -->
    <context:property-placeholder location="classpath:dbconfig.properties" file-encoding="UTF-8"/>

    <!-- 配置数据源(Druid连接池) -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="filters" value="${jdbc.filters}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
        <property name="minIdle" value="${jdbc.minIdle}"/>
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
        <property name="validationQuery" value="${jdbc.validationQuery}"/>
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}"/>
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}"/>
        <property name="testOnReturn" value="${jdbc.testOnReturn}"/>
        <property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}"/>
        <property name="maxPoolPreparedStatementPerConnectionSize"
                  value="${jdbc.maxPoolPreparedStatementPerConnectionSize}"/>
    </bean>


    <!--============================Spring-Mybatis整合配置============================-->
    <!-- SqlSessionFactoryBean, 用于创建SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 指定Mybatis配置文件位置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 以下设置既可以写在Mybatis配置文件中, 也可以在这里显式给出 -->
        <!-- 指定SQL映射文件位置 -->
        <property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
        <!-- 配置Mybatis插件 -->
<!--        <property name="plugins">-->
<!--            <array>-->
<!--                <bean class="com.github.pagehelper.PageInterceptor">-->
<!--                    <property name="properties">-->
<!--                        <props>-->
<!--                            &lt;!&ndash; 使用下面的方式配置参数, 一行配置一个 &ndash;&gt;-->
<!--                            &lt;!&ndash; 分页合理化, pageNum<=0 时查询第一页,pageNum>pages时查询最后一页 &ndash;&gt;-->
<!--                            <prop key="reasonable">true</prop>-->
<!--                            &lt;!&ndash; SQL方言 &ndash;&gt;-->
<!--                            <prop key="helperDialect">mysql</prop>-->
<!--                            &lt;!&ndash; pageSize为0时查询所有数据 &ndash;&gt;-->
<!--                            <prop key="pageSizeZero">true</prop>-->
<!--                            &lt;!&ndash; 支持分页查询模型, 即 PageHelper.startPage(Object params) 这种用法 &ndash;&gt;-->
<!--                            <prop key="support-methods-arguments">true</prop>-->
<!--                        </props>-->
<!--                    </property>-->
<!--                </bean>-->
<!--            </array>-->
<!--        </property>-->
    </bean>
    
    <!-- MapperScannerConfigurer, 扫描指定包下的mapper接口, 创建mapper实例并注册到Spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 指定mapper接口所在的包 -->
        <property name="basePackage" value="pers.oneice.ssm.crud.dao"/>
        <!-- (可选) 只扫描带了Resource注解的mapper接口 (适用于拓展MBG生成的mapper接口) -->
        <!--<property name="annotationClass" value="javax.annotation.Resource"/>-->
        <!-- (可选) 如果容器中有多个SqlSessionFactory, 必须指定使用哪一个 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- 配置一个用于批量操作的SqlSessionTemplate, 它是线程安全的, 也不需要我们手动close -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
        <constructor-arg name="executorType" value="BATCH"/>
    </bean>


    <!--============================事务管理的配置============================-->
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 开启事务管理的注解驱动, 扫描@Transactional等注解 -->
    <!--<tx:annotation-driven/>-->

    <!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 配置事务属性 -->
        <tx:attributes>
            <!-- tx:method用来指定要为切入点中的哪些方法开启事务, 并进行更精细的配置 -->
            <!-- 配置查询方法 -->
            <tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
            <tx:method name="count*" read-only="true" propagation="SUPPORTS"/>
            <!-- 配置增删改方法 -->
            <tx:method name="save*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="insert*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="remove*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="delete*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="update*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="modify*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <tx:method name="batch*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/>
            <!-- 配置其他方法 (如果不配置将不会为其开启事务) -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- AOP配置 -->
    <aop:config>
        <!-- 配置切入点表达式 -->
        <aop:pointcut id="servicePt" expression="execution(* pers.oneice.ssm.crud.service..*.*(..))"/>
        <!-- 配置切面, 将Pointcut和Advice关联起来 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePt"/>
    </aop:config>

</beans>

Spring MVC配置文件—springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- 配置Spring MVC包扫描器, Spring MVC只负责网站跳转逻辑这部分 -->
    <context:component-scan base-package="com.oneice.crowdfunding.mvc" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController"/>
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestControllerAdvice"/>
    </context:component-scan>

    <!-- 开启Spring Security注解支持, @PreAuthorize、@PostAuthorize、@PreFilter 和 @PostFilter -->
    <security:global-method-security pre-post-annotations="enabled"/>

    <!--开启Spring MVC注解驱动, 支持基于注解的JSR303校验, 处理Ajax请求, 映射动态请求等
         validator: 将指定的校验器注册进WebDataBinder
         conversion-service: 将指定的ConversionService注册进HandlerAdapter
    -->
    <mvc:annotation-driven/>

    <!-- 将静态资源(或没有一个控制器可以映射的请求)交给Tomcat的默认Servlet处理 -->
    <mvc:default-servlet-handler/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 路径前缀 -->
        <property name="prefix" value="/WEB-INF/views/"/>
        <!-- 路径后缀 -->
        <property name="suffix" value=".jsp"/>
        <!-- 设置默认视图 -->
        <!-- 默认视图只会应用于不包含 "redirect:" 和 "forward:" 前缀的视图名 -->
        <!--        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
    </bean>


    <!-- 下面都是可选配置, 可根据个人需要进行配置 -->

    <!--
    path: 请求路径
    view-name: 视图名
    status-code: 状态码, 默认是200
    -->
    <!--    <mvc:view-controller path="/toLoginPage" view-name="login"/>-->
    
<!--    &lt;!&ndash; 配置SimpleMappingExceptionResolver异常解析器 &ndash;&gt;-->
<!--    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">-->
<!--        &lt;!&ndash; 设置解析器的优先级别, 越小越优先 (默认优先级最低) &ndash;&gt;-->
<!--        <property name="order" value="-1024"/>-->
<!--        &lt;!&ndash; 配置哪些异常对应哪些视图名 (错误页面) &ndash;&gt;-->
<!--        <property name="exceptionMappings">-->
<!--            <props>-->
<!--                <prop key="java.lang.ArithmeticException">myerror</prop>-->
<!--                <prop key="java.lang.NullPointerException">myerror</prop>-->
<!--            </props>-->
<!--        </property>-->
<!--        &lt;!&ndash; 设置任意异常对应的默认视图名 &ndash;&gt;-->
<!--        <property name="defaultErrorView" value="myerror"/>-->
<!--        &lt;!&ndash; 设置要排除的异常 &ndash;&gt;-->
<!--        &lt;!&ndash;<property name="excludedExceptions" value="java.lang.ClassNotFoundException"/>&ndash;&gt;-->
<!--        &lt;!&ndash; 设置只解析哪些控制器抛出的异常, 默认是所有控制器 &ndash;&gt;-->
<!--        &lt;!&ndash;<property name="mappedHandlerClasses" value="com.controller.MyExceptionHandler"/>&ndash;&gt;-->
<!--        &lt;!&ndash; 设置要存进请求域的异常key, 以便在页面中可以取出异常, 默认是"exception" &ndash;&gt;-->
<!--        &lt;!&ndash;<property name="exceptionAttribute" value="ex"/>&ndash;&gt;-->
<!--    </bean>-->

    <!-- 配置拦截器 -->
    <!--    <mvc:interceptors>-->
    <!--        &lt;!&ndash; 配置一个全局拦截器,拦截所有请求 &ndash;&gt;-->
    <!--        <bean class="com.controller.MyFirstInterceptor"/>-->
    <!--        &lt;!&ndash; 配置一个拦截指定路径的拦截器 &ndash;&gt;-->
    <!--        <mvc:interceptor>-->
    <!--            &lt;!&ndash; 要拦截的路径, 支持ant风格 &ndash;&gt;-->
    <!--            <mvc:mapping path="/test01/**"/>-->
    <!--            &lt;!&ndash; 不拦截的路径 &ndash;&gt;-->
    <!--            <mvc:exclude-mapping path=""/>-->
    <!--            &lt;!&ndash; 要使用的拦截器 &ndash;&gt;-->
    <!--            <bean class="com.controller.MySecondInterceptor"/>-->
    <!--        </mvc:interceptor>-->
    <!--    </mvc:interceptors>-->

    <!--配置指定的ConversionService, 用于类型转换和数据格式化-->
    <!--    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">-->
    <!--        &lt;!&ndash;注册自定义的类型转换器&ndash;&gt;-->
    <!--        <property name="converters">-->
    <!--            <set>-->
    <!--                <bean class="com.controller.MyStringToEmployeeConverter"/>-->
    <!--            </set>-->
    <!--        </property>-->
    <!--    </bean>-->

    <!-- 配置校验器 -->
    <!--    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">-->
    <!--        &lt;!&ndash; 校验器,使用hibernate校验器 &ndash;&gt;-->
    <!--        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>-->
    <!--        &lt;!&ndash; 指定表示校验信息的资源文件,在文件中配置校验的错误信息,如果不指定则默认使用classpath下面的ValidationMessages.properties文件 &ndash;&gt;-->
    <!--        <property name="validationMessageSource" ref="messageSource"/>-->
    <!--    </bean>-->

    <!-- 配置国际化资源文件 -->
    <!--    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">-->
    <!--        &lt;!&ndash; 资源文件名 &ndash;&gt;-->
    <!--        <property name="basenames">-->
    <!--            <list>-->
    <!--                <value>classpath:errors</value>-->
    <!--            </list>-->
    <!--        </property>-->
    <!--        &lt;!&ndash; 资源文件编码格式 &ndash;&gt;-->
    <!--        <property name="defaultEncoding" value="utf-8"/>-->
    <!--        &lt;!&ndash; 对资源文件的缓存时间, 单位秒 &ndash;&gt;-->
    <!--        <property name="cacheSeconds" value="120"/>-->
    <!--    </bean>-->

    <!--配置multipart解析器, 用于解析文件上传请求-->
    <!--    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">-->
    <!--        &lt;!&ndash;设置一个请求能上传的总大小&ndash;&gt;-->
    <!--        <property name="maxUploadSize" value="#{1024*1024*10}"/>-->
    <!--        &lt;!&ndash;设置上传的每个文件的最大大小&ndash;&gt;-->
    <!--        <property name="maxUploadSizePerFile" value="#{1024*1024}"/>-->
    <!--        &lt;!&ndash;设置上传内容能保留在内存中的最大大小 (字节), 超过这个大小将会被写入临时目录, 默认为10240&ndash;&gt;-->
    <!--        <property name="maxInMemorySize" value="10240"/>-->
    <!--        &lt;!&ndash;设置存储上传文件的临时目录 ( 默认为servlet容器的临时目录)&ndash;&gt;-->
    <!--        &lt;!&ndash;        <property name="uploadTempDir" value=""/>&ndash;&gt;-->
    <!--        &lt;!&ndash;设置解析请求用的编码&ndash;&gt;-->
    <!--        <property name="defaultEncoding" value="UTF-8"/>-->
    <!--    </bean>-->

    <!--合并其他Spring MVC配置文件-->
    <!--    <import resource="springmvc2.xml"/>-->

</beans>


Git .gitignore文件

# Created by .ignore support plugin (hsz.mobi)
### Example user template template
### Example user template

# IntelliJ project files
.idea
*.iml
out
gen
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar

### Java template
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

### Example user template template
### Example user template

# IntelliJ project files
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### Example user template template
### Example user template

# IntelliJ project files
### Example user template template
### Example user template

# IntelliJ project files
### Eclipse template
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# PyDev specific (Python IDE for Eclipse)
*.pydevproject

# CDT-specific (C/C++ Development Tooling)
.cproject

# CDT- autotools
.autotools

# Java annotation processor (APT)
.factorypath

# PDT-specific (PHP Development Tools)
.buildpath

# sbteclipse plugin
.target

# Tern plugin
.tern-project

# TeXlipse plugin
.texlipse

# STS (Spring Tool Suite)
.springBeans

# Code Recommenders
.recommenders/

# Annotation Processing
.apt_generated/
.apt_generated_test/

# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet

# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSM(Spring + Spring MVC + MyBatis)是一种经典的Java开发框架组合,而Thymeleaf是一种流行的模板引擎。下面是SSM整合Thymeleaf的基本步骤: 1. 首先,确保你已经正确配置好了Spring、Spring MVC和MyBatis。 2. 添加Thymeleaf的依赖到你的项目中。你可以在Maven的pom.xml文件中添加以下依赖: ```xml <dependencies> <!-- 其他依赖... --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> ``` 3. 在Spring配置文件中启用Thymeleaf视图解析器。在Spring MVC的配置文件(例如`springmvc.xml`)中添加以下配置: ```xml <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 其他配置... --> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".html" /> <property name="order" value="2" /> <!-- 设置优先级,确保Thymeleaf视图解析器在其他视图解析器之前 --> </bean> <bean id="thymeleafViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.ThymeleafView" /> <property name="templateEngine" ref="templateEngine" /> <property name="order" value="1" /> <!-- 设置优先级,确保Thymeleaf视图解析器优先于其他视图解析器 --> </bean> <bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver" /> </bean> <bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix" value=".html" /> <property name="templateMode" value="HTML" /> </bean> ``` 4. 创建Thymeleaf的模板文件。在`/WEB-INF/templates/`目录下创建HTML模板文件,例如`index.html`。 5. 在你的Controller中返回Thymeleaf视图。在你的Controller方法中,使用`ModelAndView`对象返回Thymeleaf视图的名称(不包含后缀),例如: ```java @GetMapping("/index") public ModelAndView getIndexPage() { ModelAndView modelAndView = new ModelAndView("index"); // 设置模型数据 modelAndView.addObject("message", "Hello, Thymeleaf!"); return modelAndView; } ``` 6. 在Thymeleaf模板文件中使用模型数据。在Thymeleaf模板文件中,使用Thymeleaf的表达式语法来展示模型数据。例如,在`index.html`中展示消息: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>SSM with Thymeleaf</title> </head> <body> <h1 th:text="${message}"></h1> </body> </html> ``` 这样,你就完成了SSM和Thymeleaf的整合。当访问`/index`路径时,将会渲染`index.html`模板并显示消息 "Hello, Thymeleaf!"。请根据你的项目需求进行适当的配置和调整。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值