单体应用

目录

1. web.xml

2. .xml

3. 依赖导入方式 spring

4. Spring配置文件 spring-context.xml

5. log4j.properties

6. Spring容器配置

7. Spring Bean注解配置

8. 管理依赖的pom.xml

9. SpringMvc配置

10. slf4j依赖导入

11. 拦截器

12. Spring整合Druid

13. Spring整合MyBatis

14. MyBatis连接数据库应用

15. jQuery Validate表单验证插件(前端)

16.Junit在spring中的应用

17. Spring Validation 表单验证(服务端)

18. 动态Sql

19. datatables

20. sweetalert只是Alert的样式框架

21. treeTable


1.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
         
    <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
  
   <filter>
  	<filter-name>EncodingFilter</filter-name>
  	<filter-class>com.qf.filter.EncodingFilter</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>EncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.hideout.hello.maven.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/servlet/hello</url-pattern>
    </servlet-mapping>
</web-app>

返回目录


2.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.lusifer</groupId>
   <artifactId>project</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>

    <dependencies>
        
    </dependencies>
<project>

返回目录


3. 依赖导入方式 spring

记得导入lombok的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hideout</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.17.RELEASE</version>
        </dependency>
    </dependencies>
</project>

返回目录


4. Spring配置文件 spring-context.xml

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

    <bean id="userService" class="com.hideout.hello.spring.service.impl.UserServiceImpl" />
</beans>

返回目录


5.log4j.properties

log4j.rootLogger=INFO, console, file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.MaxFileSize=1024KB
log4j.appender.A3.MaxBackupIndex=10
log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n

返回目录


6.Spring容器配置

  • 1.web.xml配置
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

返回目录


7. Spring Bean注解配置

spring-context.xml
 <context:annotation-config />
 <context:component-scan base-package="com.qf.hideout.shop"/>

返回目录


8.管理依赖的pom.xml

(1)环境变量

 <properties>
        <!-- 环境配置 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

(2)插件

    <build>
        <plugins>
            <!-- Compiler 插件, 设定 JDK 版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
        </plugins>

        <!-- 资源文件配置 -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>

返回目录


9. SpringMvc配置

  1. 首先要依赖Spring-web-MVC
  2. 配置一个编码过滤器 web.xml
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  1. 再配置一个分发器 web.xml
<servlet>
    <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/spring-mvc*.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  1. 创建spring-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <description>Spring MVC Configuration</description>

    <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:myshop.properties"/>

    <!-- 使用 Annotation 自动注册 Bean,只扫描 @Controller -->
    <context:component-scan base-package="com.lusifer.myshop" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 默认的注解映射的支持 -->
    <mvc:annotation-driven />

    <!-- 定义视图文件解析 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="${web.view.prefix}"/>
        <property name="suffix" value="${web.view.suffix}"/>
    </bean>

    <!-- 静态资源映射 -->
    <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>
</beans>
  1. 创建myshop.properties
#============================#
#==== Framework settings ====#
#============================#

# \u89c6\u56fe\u6587\u4ef6\u5b58\u653e\u8def\u5f84
web.view.prefix=/WEB-INF/views/
web.view.suffix=.jsp
  1. 在Spring-context.xml中添加
<!-- 使用 Annotation 自动注册 Bean,在主容器中不扫描 @Controller 注解,在 SpringMVC 中只扫描 @Controller 注解。-->
<context:component-scan base-package="com.hideout.my.shop">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

7.在webapp文件夹下创建static文件夹,将assets文件移入static文件夹里;

8.在WEB-INF文件夹下创建views文件夹,将jsp文件放入其中。

返回目录


10. slf4j依赖导入

 <!--slf4j star-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j-api.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j-log4j12.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${jcl-over-slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jul-to-slf4j</artifactId>
                <version>${jul-to-slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!--slf4j end-->
            
            
         <log4j.version>1.2.17</log4j.version>
        <jul-to-slf4j.version>1.7.25</jul-to-slf4j.version>
        <jcl-over-slf4j.version>1.7.25</jcl-over-slf4j.version>
        <slf4j-log4j12.version>1.7.25</slf4j-log4j12.version>
        <slf4j-api.version>1.7.25</slf4j-api.version>

返回目录


11.拦截器

- 在Spring-MVC.xml中的配置
<!-- 拦截器配置,拦截顺序:先执行后定义的,排在第一位的最后执行。-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/static/**"/>
        <mvc:exclude-mapping path="/login"/>
        <bean class="com.hideout.my.shop.web.interceptor.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
- 书写方式
  • 步骤
    • 实现接口HandlerInterceptor,该接口定义了3个方法preHandle(), postHandle(), afterCompletion()
      • perhandle(req,resp);该方法的返回值是布尔类型。相当于初始判断是否符合条件,符合则拦截,不符则放行。
        1. 当返回值是false时,不再进行后两个方法,拦截;
        2. 当返回值是true时,放行。
      • postHandle(req,resp)该方法主要是执行内处理
      • afterCompletion(req,response)主要是是资源清理工作
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

返回目录


12. Spring 整合 Druid

1.添加依赖
  • druid;
  • mysql-connector-java;(与MySQL的版本相同)
2.配置数据库连接

(项目名称).properties

# JDBC
# MySQL 8.x: com.mysql.cj.jdbc.Driver
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/myshop?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456

# JDBC Pool
jdbc.pool.init=1
jdbc.pool.minIdle=3
jdbc.pool.maxActive=20

# JDBC Test
jdbc.testSql=SELECT 'x' FROM DUAL
3. Spring集成Druid,创建spring-context-druid.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

    <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties"/>

    <!-- 数据源配置, 使用 Druid 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
        <property name="driverClassName" value="${jdbc.driverClass}"/>

        <!-- 基本属性 url、user、password -->
        <property name="url" value="${jdbc.connectionURL}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="${jdbc.pool.init}"/>
        <property name="minIdle" value="${jdbc.pool.minIdle}"/>
        <property name="maxActive" value="${jdbc.pool.maxActive}"/>

        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000"/>

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>

        <property name="validationQuery" value="${jdbc.testSql}"/>
        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>

        <!-- 配置监控统计拦截的filters -->
        <property name="filters" value="stat"/>
    </bean>
</beans>
4. 配置Druid监控中心 ,在web.xml文件中添加
<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>
5.检查是否创建成功

访问该网站:检验是否创建成功 (<–可点击)

返回目录


13.Spring整合MyBatis

1. 添加依赖
  • mybatis
  • mybatis-spring
  • spring-jdbc
2. 配置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>
        <!-- 打印 SQL 语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />

        <!-- 使全局的映射器启用或禁用缓存。 -->
        <setting name="cacheEnabled" value="false"/>

        <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
        <setting name="lazyLoadingEnabled" value="true"/>

        <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
        <setting name="aggressiveLazyLoading" value="true"/>

        <!-- 是否允许单条 SQL 返回多个数据集 (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>

        <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>

        <!-- 允许 JDBC 生成主键。需要驱动器支持。如果设为了 true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false  -->
        <setting name="useGeneratedKeys" value="false"/>

        <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不映射 PARTIAL:部分 FULL:全部  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        <!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) -->
        <setting name="defaultExecutorType" value="SIMPLE"/>

        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
        <setting name="localCacheScope" value="SESSION"/>

        <!-- 设置 JDBC 类型为空时,某些驱动程序 要指定值, default:OTHER,插入空值时不需要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>
</configuration>
3. 配置spring-context-mybatis.xml的spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置 SqlSession -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 用于配置对应实体类所在的包,多个 package 之间可以用 ',' 号分割 -->
        <property name="typeAliasesPackage" value="com.hideout.my.shop.domain"/>
        <!-- 用于配置对象关系映射配置文件所在目录 -->
        <property name="mapperLocations" value="classpath:/mapper/**/*.xml"/>
        <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
    </bean>

    <!-- 扫描 Mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.hideout.my.shop.web.admin.dao" />
    </bean>
</beans>

返回目录


14. MyBatis连接数据库应用

1. 首先建立与数据库中表相对应的的实体类
2. 建立数据访问接口,即dao层
@Repository
//dao层的注解
public interface TbUserDao {

    /**
     * 查询全部用户信息
     * @return
     */
    public List<TbUser> selectAll();
}
3.业务逻辑层的接口,即实现。

接口

package com.hideout.my.shop.web.admin.service;

import com.hideout.my.shop.domain.TbUser;

import java.util.List;

public interface TbUserService {

    /**
     * 查询全部用户信息
     * @return
     */
    public List<TbUser> selectAll();
}

实现

@Service
public class TbUserServiceImpl implements TbUserService {

    @Autowired
    private TbUserDao tbUserDao;

    @Override
    public List<TbUser> selectAll() {
        return tbUserDao.selectAll();
    }
}
4. 单元测试

(注意导包:spring-test,junit)


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml", "classpath:spring-context-druid.xml", "classpath:spring-context-mybatis.xml"})
public class TbUserServiceTest {

    @Autowired
    private TbUserDao tbUserDao;

    @Test
    public void testSelectAll() {
        List<TbUser> tbUsers = tbUserDao.selectAll();
        for (TbUser tbUser : tbUsers) {
            System.out.println(tbUser.getUsername());
        }
    }
}

返回目录


15.jQuery Validate表单验证插件(前端)

1.导包
<script src="/static/assets/global/plugins/jquery-validation/js/jquery.validate.min.js" type="text/javascript"></script>
<script src="/static/assets/global/plugins/jquery-validation/js/additional-methods.min.js" type="text/javascript"></script>
<!--中文提示语标记-->
<script src="/static/assets/global/plugins/jquery-validation/js/localization/messages_zh.min.js" type="text/javascript"></script>
<!--自己定义的规则-->
<script src="/static/custom_validation.js" type="text/javascript"></script>
2.创建custom_validation.js文件编写规则(全部copy,根据注释提示做更改)
/**
 *自定义表单验证
 */
var Validation = function () {
//手机号格式验证--自定义验证"phone"要与一致
    var handlerInit = function () {
        jQuery.validator.addMethod("phone", function (value, element) {
            var length = value.length;
            var mobile = /^(((13[0-9]{1})|(15[0-9]{1}))+\d{8})$/;
            return this.optional(element) || (length == 11 && mobile.test(value));
        }, "手机格式错误");
    }
    // basic validation
    var handleValidation1 = function(form) {
        // for more info visit the official plugin documentation:
        // http://docs.jquery.com/Plugins/Validation

        var form1 = $('#'+form);
        var error1 = $('.alert-danger', form1);
        var success1 = $('.alert-success', form1);

        form1.validate({
            errorElement: 'span', //default input error message container
            errorClass: 'help-block help-block-error', // default input error message class
            focusInvalid: false, // do not focus the last invalid input
            ignore: "",  // validate all fields including form hidden input
            //自定义规则,与id一致,以防万一请将id与name的值写一致
            rules: {
                username: {
                    minlength: 2,
                    required: true
                },
                email: {
                    required: true,
                    email: true
                },
                oldPassword: {
                    minlemgth:3,
                    required: true
                },
                phone:{
                    phone:true
                },
                newPassword:{
                    minlemgth:3,
                    required: true
                },
                rePassword:{
                    equalTo:"#newPassword",
                    required: true
                }
            },
            //一下部分不太懂大致的意思,但最好全部写上不要省略
            invalidHandler: function (event, validator) { //display error alert on form submit
                success1.hide();
                error1.show();
                App.scrollTo(error1, -200);
            },

            errorPlacement: function (error, element) { // render error placement for each input type
                var cont = $(element).parent('.input-group');
                if (cont.size() > 0) {
                    cont.after(error);
                } else {
                    element.after(error);
                }
            },

            highlight: function (element) { // hightlight error inputs

                $(element)
                    .closest('.form-group').addClass('has-error'); // set error class to the control group
            },

            unhighlight: function (element) { // revert the change done by hightlight
                $(element)
                    .closest('.form-group').removeClass('has-error'); // set error class to the control group
            },

            success: function (label) {
                label
                    .closest('.form-group').removeClass('has-error'); // set success class to the control group
            },

            submitHandler: function (form) {
                success1.show();
                error1.hide();
            }
        });


    }

    //return方法是必须运行部分,把所有的方法写入其中
    return {
        //规则初始化
        init: function (form) {
            handleValidation1 (form);
            handlerInit();
            }
    }
}();
//该方法要初始化所有的表单,所有的表单的id都要写入
jQuery(document).ready(function () {
    Validation.init('form1');
    Validation.init('pwd');
})

返回目录


16.Junit在spring中的应用

1,导入依赖
            <!--Junit star-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
            <!--有注解时需要导入-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring-test.version}</version>
                <scope>test</scope>
            </dependency>
            <!--Junit END-->
2.测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml", "classpath:spring-context-druid.xml", "classpath:spring-context-mybatis.xml"})
public class update {
    @Autowired
    IUserService userService;
    @Test
    public void TestUpdate(){
        User tbUser = new User();
        tbUser.setPassword("dfad");
        tbUser.setUsername("pky");
        tbUser.setPhone("520");
        tbUser.setEmail("df");
        tbUser.setId(37);
        User user = userService.UserModify(tbUser);
        System.out.println(user);

    }

返回目录


17. Spring Validation 表单验证(服务端)

1. 导入依赖
<!--hibernate-validator  star-->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>${hibernate-validator.version}</version>
</dependency>
<!--hibernate-validator  end-->
2. 添加工具类(BeanValidator.java)(不需要修改)
package com.hideout.my.shop.commons.validator;

import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * JSR303 Validator(Hibernate Validator)工具类.
 * <p>
 * ConstraintViolation 中包含 propertyPath, message 和 invalidValue 等信息.
 * 提供了各种 convert 方法,适合不同的 i18n 需求:
 * 1. List<String>, String 内容为 message
 * 2. List<String>, String 内容为 propertyPath + separator + message
 * 3. Map<propertyPath, message>
 * <p>
 * 详情见wiki: https://github.com/springside/springside4/wiki/HibernateValidator
 *
 * <p>Title: BeanValidator</p>
 * <p>Description: </p>
 *
 * @author Lusifer
 * @version 1.0.0
 * @date 2018/6/26 17:21
 */
public class BeanValidator {

    @Autowired
    private static Validator validator;

    public static void setValidator(Validator validator) {
        BeanValidator.validator = validator;
    }

    /**
     * 调用 JSR303 的 validate 方法, 验证失败时抛出 ConstraintViolationException.
     */
    private static void validateWithException(Validator validator, Object object, Class<?>... groups) throws ConstraintViolationException {
        Set constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            throw new ConstraintViolationException(constraintViolations);
        }
    }

    /**
     * 辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 中为 List<message>.
     */
    private static List<String> extractMessage(ConstraintViolationException e) {
        return extractMessage(e.getConstraintViolations());
    }

    /**
     * 辅助方法, 转换 Set<ConstraintViolation> 为 List<message>
     */
    private static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
        List<String> errorMessages = new ArrayList<>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.add(violation.getMessage());
        }
        return errorMessages;
    }

    /**
     * 辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 Map<property, message>.
     */
    private static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
        return extractPropertyAndMessage(e.getConstraintViolations());
    }

    /**
     * 辅助方法, 转换 Set<ConstraintViolation> 为 Map<property, message>.
     */
    private static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
        Map<String, String> errorMessages = new HashMap<>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
        }
        return errorMessages;
    }

    /**
     * 辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 List<propertyPath message>.
     */
    private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
        return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
    }

    /**
     * 辅助方法, 转换 Set<ConstraintViolations> 为 List<propertyPath message>.
     */
    private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
        return extractPropertyAndMessageAsList(constraintViolations, " ");
    }

    /**
     * 辅助方法, 转换 ConstraintViolationException 中的 Set<ConstraintViolations> 为 List<propertyPath + separator + message>.
     */
    private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
        return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
    }

    /**
     * 辅助方法, 转换 Set<ConstraintViolation> 为 List<propertyPath + separator + message>.
     */
    private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations, String separator) {
        List<String> errorMessages = new ArrayList<>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage());
        }
        return errorMessages;
    }

    /**
     * 服务端参数有效性验证
     *
     * @param object 验证的实体对象
     * @param groups 验证组
     * @return 验证成功:返回 null;验证失败:返回错误信息
     */
    public static String validator(Object object, Class<?>... groups) {
        try {
            validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = extractMessage(ex);
            list.add(0, "数据验证失败:");

            // 封装错误消息为字符串
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {
                String exMsg = list.get(i);
                if (i != 0 ){
                    sb.append(String.format("%s. %s", i, exMsg)).append(list.size() > 1 ? "<br/>" : "");
                } else {
                    sb.append(exMsg).append(list.size() > 1 ? "<br/>" : "");
                }
            }

            return sb.toString();
        }

        return null;
    }
}
3. 修改实体类,编写规则。
@Length(min = 6, max = 20, message = "用户名长度必须介于 6 和 20 之间")
private String username;
@Length(min = 6, max = 20, message = "密码长度必须介于 6 和 20 之间")
private String password;
@Pattern(regexp = RegexpUtils.PHONE, message = "手机号格式不正确")
private String phone;
@Pattern(regexp = RegexpUtils.EMAIL, message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
@NotBlank(message = "手机号码不能为空")
private String phone;

4. JSR提供的校验注解:
JSR提供的校验注解:         
@Null   被注释的元素必须为 null    
@NotNull    被注释的元素必须不为 null    
@AssertTrue     被注释的元素必须为 true    
@AssertFalse    被注释的元素必须为 false    
@Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
@Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
@DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
@DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
@Size(max=, min=)   被注释的元素的大小必须在指定的范围内    
@Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内    
@Past   被注释的元素必须是一个过去的日期    
@Future     被注释的元素必须是一个将来的日期    
@Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式    
5. Hibernate Validator提供的校验注解
Hibernate Validator提供的校验注解:  
@NotBlank(message =)   验证字符串非null,且长度必须大于0    
@Email  被注释的元素必须是电子邮箱地址    
@Length(min=,max=)  被注释的字符串的大小必须在指定的范围内    
@NotEmpty   被注释的字符串的必须非空    
@Range(min=,max=,message=)  被注释的元素必须在合适的范围内
6. 书写验证方法,创建工具抽象类AbstractBaseController.java(可以直接用)。

//<T extends AbstractBaseEntity >确保被校验的对象所属的实体类集成该抽象类
//AbstractBaseEntity,这个抽象类自己编写,注意该类注解上@data(实现lombok依赖)
public abstract class AbstractBaseController<T extends AbstractBaseEntity > {

    //当参数的类型是Model时
    protected void addMessage(Model model, String message) {
        model.addAttribute(ConstantUtil.MESSAGE, message);
    }
    
    //当参数是Redirect Attributes,重定向后请求不改变,保留数据
    protected void addMessage(RedirectAttributes redirectAttributes, String message) {
        redirectAttributes.addFlashAttribute(ConstantUtil.MESSAGE, message);
    }

    protected boolean CheckBean(T entity, Model model){
        String result = BeanValidator.validator(entity);
//        验证失败
        if (StringUtils.isNoneBlank(result)){
            if(model instanceof RedirectAttributes) {
                RedirectAttributes redirectAttributes = (RedirectAttributes) model;
                addMessage(redirectAttributes,result);
            }else {
                addMessage(model,result);
            }

            return false;
        }
        return true;
    }
}
7. 校验的实现(控制器所在的类继承抽象类,直接调用AddMessage方法)

@Controller
public class MainController extends AbstractBaseController{

    @PostMapping(value = "userinfo/modify")
    public String userInfoModify(User user, HttpServletRequest request, RedirectAttributes redirectAttributes){
        //验证信息符合要求
        if (CheckBean(user,redirectAttributes)){
            user = userService.UserModify(user);
            request.getSession().setAttribute(ConstantUtil.WEB_KEY_USER,user);
            addMessage(redirectAttributes,ConstantUtil.UPDATE_SUCCESS);
        }
        return "admin/user_info";
    }

    @PostMapping(value = "updateUserPwd")
    public String UpdateUserPwd(String oldPassword, String newPassword, String rePassword, RedirectAttributes redirectAttributes, User user){
        String message = userService.UpdatePWD(oldPassword, newPassword, rePassword, user);
        addMessage(redirectAttributes,message);
        return "redirect:/userinfo#tab_1_3";
    }

}

返回目录


18. 动态Sql

  1. if
  • 当你的查找条件不确定的时候可以用if
<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG 
  WHERE state = ‘ACTIVE’ 
  <if test="title != null">
    AND title like #{title}
  </if>
</select>
  1. choose,when,otherwise
  • 相当于java中的switch语句
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
        <when test="title != null">
            AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
            AND author_name like #{author.name}
        </when>
        <otherwise>
            AND featured = 1
        </otherwise>
  </choose>
</select>
  1. trim,where,set
  • where
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG 
  <where> 
    <if test="state != null">
         state = #{state}
    </if> 
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:(在特殊情况下,可以自定义)

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

where 元素主要是用在查询里,

还有一个set元素使用在修改语句中,例子如下:

<update id="updateUserById" parameterType="com.ys.po.User">
    UPDATE user AS 'u'
        <set>
            <if test="username != null and username != ''">
                u.username = #{username},
            </if>
            <if test="sex != null and sex != ''">
                u.sex = #{sex}
            </if>
        </set>
     WHERE id=#{id}
</update>
  1. 模糊查询 (concat,like)
<select id="selectByName" resultType="TbUser">
    SELECT
      a.id,
      a.username,
      a.password,
      a.phone,
      a.email,
      a.created,
      a.updated AS "update"
    FROM
      tb_user AS a
    WHERE
      a.username LIKE CONCAT ('%', #{username}, '%')
</select>
  1. 定义SQL片段
  • 定义
<sql id = "a">
<---被定义的SQL语句片段--->
</sql>
  • 引入
<include refid="a"></include>
  1. foreach语句
<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">
    select * from user
    <where>
        <!--
            collection:指定输入对象中的集合属性         (ids--是一个关于id 的集合)
            item:每次遍历生成的对象
            open:开始遍历时的拼接字符串
            close:结束时拼接的字符串
            separator:遍历对象之间需要拼接的字符串
            select * from user where 1=1 and (id=1 or id=2 or id=3)
          -->
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

返回目录


19. dataTables

什么是dataTable

dataTable 是一个jQuery表格插件,它主要有以下几个功能:

  • 分页,即时搜索和排序
  • 几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
  • 支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
  • 各式各样的扩展: Editor, TableTools, FixedColumns
  • 丰富多样的option和强大的API
  • 支持国际化(可以设置语言)

可参考的文档

中文官网

使用DataTable基本手册

在线API

他人总结

如何使用,简略方法
  1. 导入js,css文件

  2. 如果使用的是模板,查找table的id,按住Ctrl键找到该table使用的js文件,重写js文件,如果是长长的一串js的代码在这里格式化一下,然后修改该js,并引入该js,记得修改table的id,具体写法可参考这里

  3. 在前端的网页写一个$(function(){})方法,调用js里的方法,具体写法可参考这里

  4. ajax 里记得填写url地址,JS会自动接收地址

  5. 项目记得添加Jackson依赖,因为ajax接收的数据是Jackson格式的。

  6. 封装一个DataTables数据源参考这里

EG:
  1. 部分jsp文件
 <div class="table-container">
    <table class="table table-striped table-bordered table-hover table-checkable" id="datatable_me">
        <thead>
            <th width="5%">
                <label class="mt-checkbox mt-checkbox-single mt-checkbox-outline">
                    <input type="checkbox" class="group-checkable" data-set="#sample_2 .checkboxes" />
                    <span></span>
                </label>
            </th>
            <th width="15%"> 用户名</th>
            <th width="15%"> 邮箱 </th>
            <th width="15%"> 电话 </th>
            <th width="15%">更新时间 </th>
            <th width="30%"> 操作 </th>
        </thead>

    </table>
</div>
  1. 重写的js文件
var TableDatatablesAjax_me = function() {
    InitDateTablesAjax = function(url, columns) {
        var grid = new Datatable;
        grid.init({
            src: $("#datatable_me"),
            /**
             * 数据装载成功后的回调
             * @param grid DataTable
             * @param response 服务器返回的 JSON 数据
             */
            onSuccess: function(grid, response) {},
            /**
             * 请求失败的回调
             * @param grid
             */
            onError: function(grid) {},
            /**
             * 装载完 Ajax 数据之后的回调
             * @param grid
             */
            onDataLoad: function(grid) {},
            loadingMessage: "加载中...",
            dataTable: {
                "lengthMenu": [[10, 20, 50, 100, 150, -1], [10, 20, 50, 100, 150, "All"]],
                "pageLength": 5,
                "ajax": {
                    url: url,
                },
                /**
                 * 启用排序true
                 */
                "dom": "<'row' <'col-md-12'B>><'row'<'col-md-6 col-sm-12'l><'col-md-6 col-sm-12'f>r><'table-scrollable't><'row'<'col-md-5 col-sm-12'i><'col-md-7 col-sm-12'p>>", // horizobtal scrollable datatable
                "pagingType": 'bootstrap_extended', // pagination type
                "ordering": false,
                "searching": false,
                "columns": columns,
                "lengthChange": false,
                "language": {
                    "metronicAjaxRequestGeneralError": "无法完成请求,请检查你的网络",
                    "sProcessing": "处理中...",
                    "sLengthMenu": "显示 _MENU_ 项结果",
                    "sZeroRecords": "没有匹配结果",
                    "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
                    "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
                    "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
                    "sInfoPostFix": "",
                    "sSearch": "搜索:",
                    "sUrl": "",
                    "sEmptyTable": "表中数据为空",
                    "sLoadingRecords": "载入中...",
                    "sInfoThousands": ",",
                    "oPaginate": {
                        "sFirst": "首页",
                        "sPrevious": "上页",
                        "sNext": "下页",
                        "sLast": "末页",
                        "page": "页码",
                        "pageOf": "/"
                    },
                    "oAria": {
                        "sSortAscending": ": 以升序排列此列",
                        "sSortDescending": ": 以降序排列此列"
                    },
                },
                buttons: [],
            },
        });
        return grid;
    }

    return{
        init: function(url , columns){
            return InitDateTablesAjax(url , columns)
        }
    }
}();
  1. jsp中的调用函数书写
$(function () {
    TableDatatablesAjax_me.init("/user/list/page", [
        {"data": function (row, type,set,meta) {
               return '<label class="mt-checkbox mt-checkbox-single mt-checkbox-outline">' +
                   '     <input type="checkbox" class="checkboxes" value="1">' +
                   '     <span></span>' +
                   ' </label>'
        }},
        { "data": "username" },
        { "data": "email" },
        { "data": "phone" },
        { "data": "updated" },
        { "data":function (row, type, set, meta) {
            return '<a href="/user/list/getById?id='+row.id+' " class="btn btn-circle green">编辑' +
                '      <i class="fa fa-font"></i>' +
                '  </a>' +
                '  <a href="/user/list/lookUser?id='+row.id+' " class="btn btn-circle blue">' +
                '      <i class="fa fa-file-o"></i> 查看' +
                '  </a>' +
                '  <a onclick="del('+ row.id+')" class="btn btn-circle purple mt-sweetalert">' +
                '      <i class="fa fa-times"></i> 删除' +
                '  </a>';
            }        
        }
    ]);
});
  1. controller
    @ResponseBody
    @PostMapping(value = "page")
    public DataTable<User>  page(User user, HttpServletRequest request){

        DataTable<User> dataTable = new DataTable<>();

        String strDraw = request.getParameter("draw");
        String strStart = request.getParameter("start");
        String strLength = request.getParameter("length");

        int draw = StringUtils.isBlank(strDraw) ? 1 : Integer.parseInt(strDraw);
        int start = StringUtils.isBlank(strStart) ? 0 : Integer.parseInt(strStart);
        int length = StringUtils.isBlank(strLength) ? 10 : Integer.parseInt(strLength);

        PageInfo<User> pageInfo = userListService.page(user, start, length);
        dataTable.setDraw(draw);
        dataTable.setRecordsTotal(pageInfo.getTotal());
        dataTable.setRecordsFiltered(pageInfo.getTotal());
        dataTable.setData(pageInfo.getData());

        return dataTable;
    }
  1. 封装一个DataTables数据源
package com.qf.hideout.web.shop.dto;

import com.qf.hideout.web.shop.abstracts.AbstractBaseEntity;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * 用于封装 DataTable 数据源
 * <p>Title: DataTable</p>
 * <p>Description: </p>
 *
 */
@Data
public class DataTable<T extends AbstractBaseEntity> implements Serializable {
    private int draw;
    private int recordsTotal;
    private int recordsFiltered;
    private List<T> data;
}

返回目录


20. sweetalert只是Alert的样式框架

具体操作参考该网站

例子:

<a onclick="del(id)" class="btn btn-circle purple mt-sweetalert">   
    <i class="fa fa-times"></i> 删除
</a>
function del(rid) {
    swal({
            title: "你是否确定?",
            text: "你要删除该数据!",
            type: "warning",
            showCancelButton: true,
            confirmButtonClass: "btn-danger",
            confirmButtonText: "确定删除",
            cancelButtonText: "取消删除",
            closeOnConfirm: false,
            closeOnCancel: false,

        },
        function(isConfirm) {
            if (isConfirm) {
                swal({
                    title:"操作成功",
                    text:"你已经删除了该条数据",
                    confirmButtonClass: "success",
                },function () {
                    $.post("/user/list/detele",{ id: rid });
                    window.location="/user/list/all";
                })
            } else {
                swal("操作失败", "你已经取消了删除", "error");
            }
        })
}

返回目录


21. treeTable

返回目录


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值