前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSM整合案例

SSM整合案例

作者头像
大忽悠爱学习
发布2021-11-15 14:32:15
4.1K0
发布2021-11-15 14:32:15
举报
文章被收录于专栏:c++与qt学习c++与qt学习

SSM整合案例


关于jdbcurl后面跟的参数问题

解释jdbcUrl后面的参数useUnicode Mysql jdbc URL连接参数useSSL、serverTimezone 相关问题


SpringBoot中lombok提供的注解如下:

@Data注解如何使用 java添加@Data注解的步骤 @Data注解使用/注解getset不起作用


功能

在这里插入图片描述
在这里插入图片描述

技术

在这里插入图片描述
在这里插入图片描述

需要的依赖

代码语言:javascript
复制
        <!--导入spring的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--导入aspectj的坐标-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.4</version>
        </dependency>
        <!--引入Spring测试坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--junit坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
        </dependency>
        <!--spring tx的坐标,处理事务的-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--spring jdbc的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <!--SpringWeb模块相关的坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--jstl的依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--标准标签库的依赖-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- maven管理引入springmvc注解数据校验所需jar包:-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.0.Final</version>
        </dependency>
        <!--文件上传的依赖-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <!--引入jquery的依赖-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1-2</version>
        </dependency>

        <!--jackSon的依赖===>ajax-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.0</version>
        </dependency>

        <!--MyBaits依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--log4j日志依赖-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>

        <!--ehcache第三方专业缓存框架的依赖-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.8</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.3</version>
        </dependency>

        <!--除了log4j,还需要导入slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
            <scope>test</scope>
        </dependency>

        <!--mysql驱动的坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <!--c3p0数据库连接池的坐标-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!--druid数据库连接池坐标-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!--mybaits和spring整合包的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>


        <!--lombok注解-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

        <!--jsp相关依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <!--pagehelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.0.3</version>
        </dependency>
        <!-- pagehelper的依赖包:jsqlparser -->
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>0.9.5</version>
        </dependency>
        <!--mybatis的逆向工程-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>
        <!--使用插件启动mbg-->
        <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.7</version>
        </dependency>

        <!-- maven管理引入springmvc注解数据校验所需jar包:-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.0.Final</version>
        </dependency>

通过cdn引入bootstrap及注意事项

代码语言:javascript
复制
   <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
    <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

引用时的注意事项


使用MBG逆向工程

MBG逆向工程使用说明


数据库环境搭建—含外键关联

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

maven静态资源导出问题—在web.xml中进行配置

代码语言:javascript
复制
        <!--让IDEA不要忽略src目录下的xml文件-->
        <!--静态资源导出问题-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

在spring核心配置容器中配置可以执行批量sqlsession

代码语言:javascript
复制
    <!--配置可以执行批量sqlsession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg  name="sqlSessionFactory"  ref="sqlSessionFactoryBean"></constructor-arg>
        <constructor-arg name="executorType" value="BATCH"></constructor-arg>
    </bean>
代码语言:javascript
复制
/*使用spring的单元测试*/
//指定spring配置文件的位置
@ContextConfiguration(locations = {"classpath:Spring/applicationContext.xml"})
//运行单元测试使用spring环境
@RunWith(SpringJUnit4ClassRunner.class)
public class TestDao {
    //直接注入我们需要使用的组件
    @Autowired
    departmentMapper departmentMapper;
    @Autowired
    employeeMapper eMapper;
    //批量的sqlsession
    @Autowired
    SqlSession sqlSession;
    @Test
    public void testDao()
    {
        //生成员工数据,插入员工
        eMapper.insertSelective(new employee(null,"王五","男","3076679687@qq.com",4));
        employeeMapper mapper=sqlSession.getMapper(employeeMapper.class);
        for(int i=0;i<50;i++)
        {
            //每一次生成不重复的随机字符串,截取前五个字符
            String uid = UUID.randomUUID().toString().substring(0, 5);
            mapper.insertSelective(new employee(null,uid,"男","@307667968"+i+"@qq.com",1));
        }
    }
}

Spring核心配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
    <!--Spring配置文件,这里注意配置和业务逻辑有关的-->

    <!--spring除了控制器不要,剩下的业务逻辑组件都要,包括dao,包括service-->
    <context:component-scan base-package="Com">
        <!--扫描排除不写use,使用默认扫描规则-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--加载外部的properties文件-->
    <!--当前要加载的properties文件在资源文件下,前面需要加上classpath:-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--
  c3p0:自动化操作(自动化加载配置文件,并且可以自动设置到对象中)
-->
    <!--配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--通过键值的方式引入值-->
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        <property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
        <!--关闭连接后不自动commit-->
        <property name="autoCommitOnClose" value="false"/>
        <!--获取连接超时时间-->
        <property name="checkoutTimeout" value="10000"/>
        <!--获取连接失败重试的次数-->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

    <!--配置使用Mybaits操作数据库-->
    <!--可以根据配置文件得到SqlSessionFactory-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--指定mybaits全局配置文件的位置·-->
        <property name="configLocation" value="classpath:MyBaits/mybaits-config.xml"></property>
        <property name="dataSource" ref="dataSource"></property>
        <!-- 指定xml映射文件位置-->   <!--所有xml都是我们的映射文件-->
        <property name="mapperLocations" value="classpath:MyBaits/mapper/*.xml"></property>
    </bean>
    <!--配置扫描器: 我们要把dao接口的实现加入到ioc容器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--扫描所有dao接口的实现,加入到IOC容器中-->
        <property name="basePackage" value="Com.Dao"></property>
        <!--            因为会自动装配 SqlSessionFactory和SqlSessionTemplate
                    所以没 有 必 要 去 指 定 SqlSessionFactory或 SqlSessionTemplate
                    因此可省略不配置;
                    但是,如果你使 用了一个 以上的 DataSource,那么自动装配可能会失效。
                    这种 情况下,你可以使用sqlSessionFactoryBeanName或sqlSessionTemplateBeanName属性来设置正确的 bean名称来使用;-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
    </bean>

    <!--配置可以执行批量sqlsession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg  name="sqlSessionFactory"  ref="sqlSessionFactoryBean"></constructor-arg>
        <constructor-arg name="executorType" value="BATCH"></constructor-arg>
    </bean>

    <!--配置事务控制,配置事务管理器,控制住数据源里面的链接的关闭和提交-->
    <!--创建事务管理器对象-->
    <!--需要导入aspectj的坐标,即面向切面编程的坐标-->
    <!--这里的id可以随便写-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--操作事务需要连接对象,连接对象在连接池中(数据源)-->
        <!--控制数据源,通过操作connection连接,来进行事务的回滚,自动提交操作-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--基于xml配置事务,哪些方法切入事务还需要写切入点表达式-->
    <aop:config>
        <!--配置切入点表达式-->
        <aop:pointcut id="tx" expression="execution(* Com.service.*.*(..))"/>
        <aop:advisor advice-ref="myTx" pointcut-ref="tx"/>
    </aop:config>

    <!--配置事务增强,事务如何切入-->
    <tx:advice id="myTx" transaction-manager="transactionManager"><!--这里不写transaction-manager
    ,那么默认会去找id为transactionManager的-->
        <tx:attributes>
            <!--所有方法都是事务方法,任何事务方法出现任何异常都回滚-->
            <tx:method name="*" rollback-for="java.lang.Exception"/>
            <!--以get开始的所有方法-->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
</beans>

SpringMVC的核心配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/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">
   <!--SpringMVC配置文件,包含网站跳转逻辑的控制和配置-->

    <!--SpringMVC只扫描控制器:禁用默认过滤规则-->
    <context:component-scan base-package="Com" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--文件上传解析器: id必须是multipartFile-->
    <bean  id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--设置文件上传最大量为5m-->
        <property name="maxUploadSize" value="5242880"></property><!--spel运算符,计算最大可上传文件体积-->
        <!--设置默认的编码-->
        <property name="defaultEncoding" value="utf-8"></property>
    </bean>

    <!--扫描静态资源-->
    <mvc:default-servlet-handler/>
    <!--扫描动态资源,也支持一些高级功能:JSR303校验,快捷的ajax请求-->
    <mvc:annotation-driven/>
</beans>

Mybaits核心配置文件

代码语言:javascript
复制
<?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"/>
        <!-- 打印sql日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
        <!--开启延迟加载开关-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--开启属性按需加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!--开启全局缓存开关-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
   <!-- 给自定义POJO包下的所有类起别名,默认都是类名-->
    <typeAliases>
        <package name="Com.POJO"/>
    </typeAliases>
    <!--配置pageHelper-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--分页参数合理化,当小于0时,查询第一页,当大于总页数时,查询最后一页-->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>
</configuration>

web.xml配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <!--配置Spring的ioc容器启动-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <!--指定spring配置文件位置-->
    <param-value>classpath:Spring/applicationContext.xml</param-value>
  </context-param>

  <!--配置监听器-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--配置springmvc的前端控制器-->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <!--这里我们spring和springmvc分离开了,这里相当于配置springmvc的ioc容器启动-->
      <param-value>classpath:SpringMVC/springmvc.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>

  <!--两个标准配置-->
  <!--字符编码-->
  <!--配置一个字符编码的Filter,放在所有过滤器之前-->
  <filter>
    <filter-name>CharacterEncodingFilter</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>forceRequestEncoding</param-name>
      <param-value>true</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>

  <!--支持REST风格的filter,将put或者delete请求转换为put请求-->
  <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>

<!--spring提供的过滤器解决解决ajax直接发送put请求-->
  <filter>
    <filter-name>HttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>HttpMethodFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>


  <!--设置session过期时间-->
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>
</web-app>

使用分页插件

pageHelper----Mybaits分页插件


controller层

查询所有员工并分页显示的方法

代码语言:javascript
复制
    //查询所有员工,分页展示
    @RequestMapping("/emps")
    public String getEmps(@RequestParam(value = "pn",defaultValue = "1") Integer pn, Model model)
    {
        //传入当前显示的页码和每页显示记录的条数,查询语句紧跟在后面
        PageHelper.startPage(pn,5);
        List<employee> emps = es.getAll();
        //使用pageINfo包装查询后的结果
        //封装了详细的分页信息,包括查询出来的数据,传入连续显示的页数
        PageInfo page=new PageInfo(emps,5);
        model.addAttribute("info",page);
        return "list";
    }

如何通过spring单元测试,完成对上面controller层代码的测试呢? 看下面的步骤

代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration//加了这个注解后,才能获取到springmvc的ioc容器
@ContextConfiguration(locations = {"classpath:Spring/applicationContext.xml","classpath:SpringMVC/springmvc.xml"})
public class SpringMVCTers {
    //传入springmvc的ioc
    @Autowired
    WebApplicationContext context;
    //虚拟mvc请求,获取到处理结果
    MockMvc mockMvc;
    @Before
    public void initMokcMvc()
    {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }
@Test
    public void testPage() throws Exception {
        //模拟请求,拿到返回值
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "1")).andReturn();
        //请求成功以后,请求域中会有info,我们可以取出info进行验证
        MockHttpServletRequest request=result.getRequest();
        PageInfo pi= (PageInfo) request.getAttribute("info");
        System.out.println("当前页码:"+pi.getPageNum());
        System.out.println("总页码:"+pi.getPages());
        System.out.println("总记录数:"+pi.getTotal());
        System.out.println("在页面需要连续显示的页码:");
        int[] nums = pi.getNavigatepageNums();
        for(int i:nums)
        {
            System.out.println(" "+i);
        }
        //获取员工数据
        List<employee> list = pi.getList();
for(employee e:list)
    System.out.println("姓名:"+e.getEmpName()+"   "+"性别: "+e.getGender());
    }
}
在这里插入图片描述
在这里插入图片描述

查询员工的思路—ajax

在这里插入图片描述
在这里插入图片描述

员工展示页面:

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%pageContext.setAttribute("ctx",request.getContextPath());%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<html>
<head>
    <title>员工信息展示页面</title>
</head>
<body>
<%--搭建展示页面--%>
<div class="container">

    <%--标题--%>
  <div class="row">
      <div class="col-md-12">
          <h1 style="font-style: italic" >大忽悠集团员工展示页面</h1>
      </div>
  </div>

    <div class="row">
        <%--按钮--%>
        <div  class="col-md-4 col-md-offset-8">
            <button class="btn btn-primary">新增</button>
            <button class="btn btn-danger">删除</button>
        </div>
        <%--显示表格数据--%>
        <div class="row">
            <div class="col-md-12">
                <table class="table table-hover" id="emps_table">
                    <thead>
                    <tr class="info">
                        <th>#</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>邮箱</th>
                        <th>部门名字</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                 <tbody>
                 <%--使用ajax向里面添加内容--%>
                 </tbody>
                </table>
            </div>
        </div>
    </div>

    <%--显示分页信息--%>
    <div class="row">
        <%--分页文字信息--%>
        <div class="col-md-6" id="page_info-area">
      <%--使用ajax显示相关信息--%>
        </div>
        <%--分页条信息--%>
        <div class="col-md-6" id="page_info_nav">
<%--使用ajax显示相关信息--%>
        </div>
    </div>
</div>
<script>
    //1.页面加载完成以后,直接发送ajax请求,要到分页数据
    $(function (){
        //一开始去首页
       toPage(1)
    })

    //跳转到指定页码号
    function toPage(pn){
        $.ajax({
            url:"${ctx}/emps",
            data:"pn="+pn,
            type:"get",
            success:function (result)
            {
                //1。解析并显示员工数据
                build_emps_table(result);
                //2。解析并显示分页信息
                build_page_info(result);
                //3.解析显示分页条数据
                build_page_nav(result);
            },
            dataType:"json"
        })
    }

        function  build_emps_table(result){
        //每次调用该方法前,需要先请客表格,因为ajax是无刷更新,每一次调用都会重复追加
            $("#emps_table tbody").empty();
            //拿到员工数组
      var e=result.extent.info.list;
        $.each(e,
            function(index,item)
            {
                //动态创建标签并向里面添加内容
                var empID=$("<td></td>").append(item.empId);
                var empName=$("<td></td>").append(item.empName);
                var empGender=$("<td></td>").append(item.gender);
                var empEmail=$("<td></td>").append(item.email);
                var deptName=$("<td></td>").append(item.department.depName);
                //构建两个按钮                         addClass方法调用后,返回原来的元素
                var editBtn=$("<button></buttom>").addClass("btn btn-primary btn-sm")
                    .append("<span></span>").addClass("glyphicon glyphicon-pencil").append("编辑");
                var delBtn=$("<button></buttom>").addClass("btn btn-danger btn-sm")
                    .append("<span></span>").addClass("glyphicon glyphicon-trash").append("删除");
                //将两个按钮追加到一个单元格里面
                var btnTd=$("<td></td>").append(editBtn).append(" ").append(delBtn);
                //append方法执行完成之后还是返回原来的元素
                $("<tr></tr>").append(empID).append(empName).append(empGender)
                .append(empEmail).append(deptName).append(btnTd).
                appendTo("#emps_table tbody");//整个表格构建完成以后,添加到对应位置中
            }
            )
        }
//解析显示分页信息
    function build_page_info(result)
    {
        //每次调用前,先清空所有之前添加的内容
        $("#page_info-area").empty();

          $("#page_info-area").append("当前第"+result.extent.info.pageNum+"页,总"+result.extent.info.pages+"共页,总共" +
              result.extent.info.total + "条记录");
    }
//解析显示分页条,点击分页要能去下一页
        function build_page_nav(result) {
            //每次调用前,先清空所有之前添加的内容
            $("#page_info_nav").empty();

            var ul = $("<ul></ul>").addClass("pagination");
            //attr赋值后,还是会返回当前元素,这里不能点击跳转,所以传入#,跳转到本页
            var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href", "#"));
            var prePageLi = $("<li></li>").append($("<a></a>").append("&laquo;"));
            //如果是首页,那么前进一页不能点击
            if (result.extent.info.hasPreviousPage == false) {
                firstPageLi.addClass("disabled");
                prePageLi.addClass("disabled");
            } else
            {
                firstPageLi.click(function (){
                    toPage(1);
                });
                prePageLi.click(function (){
                    toPage(result.extent.info.pageNum+1);
                });
            }
            var nextPageLi=$("<li></li>").append($("<a></a>").append("&raquo;"));
            var lastPageLi=$("<li></li>").append($("<a></a>").append("末页").attr("href","#"));
            //如果是末页,没有下一页对应也不能点
            if(result.extent.info.hasNextPage==false)
            {
                nextPageLi.addClass("disabled");
                lastPageLi.addClass("disabled");
            }else
            {
                lastPageLi.click(function (){
                    toPage(result.extent.info.pages);
                });
                nextPageLi.click(function (){
                    toPage(result.extent.info.pageNum+1);
                });
            }
            //添加首页和前一页的提示
            ul.append(firstPageLi).append(prePageLi);
            //遍历页码号
            $.each(result.extent.info.navigatepageNums,function (index,item){
                var numLi=$("<li></li>").append($("<a></a>").append(item));
                if(result.extent.info.pageNum==item)
                {
                    //如果是当前页,那么对于页码处于激活状态
                    numLi.addClass("active");
                }
                numLi.click(function (){
                    toPage(item);
                });
                ul.append(numLi);
            });
            //添加下一页和末尾的提示
            ul.append(nextPageLi).append(lastPageLi);
            //把ul加入到nav中
            var navEle=$("<nav></nav>").attr("aria-label","Page navigation").append(ul);
            navEle.appendTo("#page_info_nav");
        }

</script>
</body>
</html>

目前controller层:

代码语言:javascript
复制
@Controller
public class EmployeeController {
    @Autowired
    EmployueeService es;
    //跳转到首页
    @RequestMapping("/emp")
    public String getEmps()
    {
        return "list";
    }
    @RequestMapping("/tolist")
   public String toList(user u)
   {
       System.out.println("tolist");
       user admin = es.getUser();
        if(u.getName().equals(admin.getName())&&u.getPassword().equals(admin.getPassword()))
       return "redirect:/emp";
        return "redirect:/index.jsp";
   }

   //使用ajax技术,显示信息
   @RequestMapping("/emps")
   @ResponseBody//这里需要导入json的依赖
   public msg getEmpWithPageinfo(@RequestParam(value = "pn",defaultValue = "1") Integer pn, Model model)
   {
       //传入当前显示的页码和每页显示记录的条数,查询语句紧跟在后面
       PageHelper.startPage(pn,5);
       List<employee> emps = es.getAll();
       //使用pageINfo包装查询后的结果
       //封装了详细的分页信息,包括查询出来的数据,传入连续显示的页数
       PageInfo page=new PageInfo(emps,5);
       model.addAttribute("info",page);
       System.out.println("emps");
       //以json形式返回---包含info信息和失败成功信息
       return msg.success().add("info",page);
   }
}

目前效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新增员工的思路

在这里插入图片描述
在这里插入图片描述

ajax使用时需要注意的问题:当我们使用ajax向某个标签中追加数据的时候。例如点击一个按钮,向一个div追加5条记录,那么下一次点击按钮,又会调用一次ajax请求,向里面追击五条与先前重复的记录,因此每一次在追加之前,需要先将之前追加的记录或者追加的标签属性清除


jquery中的正则表达式以及其他常用函数

jQuery中的正则表达式

Jquery中的正则表达式注意事项

在这里插入图片描述
在这里插入图片描述

jquery中append()和appendTo()的区别

jQuery 文档操作 - empty() 方法

jQuery中empty和remove方法

jquery的each遍历,this指向

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

jQuery的change()事件 jquery attr和data给元素添加自定义属性

在这里插入图片描述
在这里插入图片描述

jQuery中.find()方法?


js清除表单内容的reset方法

在这里插入图片描述
在这里插入图片描述

使用jquery获取到要重置的表单后,需要取出数组中的dom表单对象

代码语言:javascript
复制
        //清除表单数据(表单重置)---DOM里面的方法,而不是jquery里面的方法
        $("#myModal form")[0].reset();

java中string类里面的matches校验正则表达式函数

Java字符串:matches() 方法


使用springmvc的JSR303数据校验需要引入一下的依赖

在这里插入图片描述
在这里插入图片描述

低版本tomcat需要引入validation-api,高版本不需要

代码语言:javascript
复制
  <!-- maven管理引入springmvc注解数据校验所需jar包:-->
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>1.1.0.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.1.0.Final</version>
    </dependency>

@Pattern注解中常用的校验正则表达式笔记

@Pattern注解中常用的校验正则表达式笔记

@Pattern进行正则校验


jQuery之$(document)和on(events,[selector],[data],fn)方法

jQuery之$(document)


jquery中的val可以获取或者设置对应的value值,设置单、多选框中被选中的状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

springmvc两篇好文

SpringMVC学习01:请求路径匹配和参数绑定 SpringMVC01----请求匹配、参数绑定、常用注解


占位符参数也会尝试去绑定函数中同名参数或者对象中同名属性

在这里插入图片描述
在这里插入图片描述

ajax可以直接发送put和delete请求

代码语言:javascript
复制
 $.ajax({
             //这里把员工id传递到更新按钮上,这样这里的id参数就可以直接从按钮上获得
             url:"${ctx}/updateEmp/"+$(this).attr("edit-id"),
             type:"put",
             data:$("#updateModel form").serialize(),//表单序列化,这里是rest风格的url,因此请求参数中要附带一个_method参数
             success:function (res){
                 alert("成功")
                 alert(res.msg);
             }

ajax发送put请求引发的血案

代码语言:javascript
复制
    //员工更新方法
    @RequestMapping(value = "/updateEmp/{empId}",method = RequestMethod.PUT)
    @ResponseBody
    public msg updateEmp(employee e)
    {
        System.out.println("=======================================");
        System.out.println("员工更新方法");
        System.out.println(e);
        System.out.println("=======================================");
        System.out.println(e);
            es.updateEmp(e);
        return msg.success();
    }
在这里插入图片描述
在这里插入图片描述

问题: 使用ajax直接发送put请求,封装的数据值为null

在这里插入图片描述
在这里插入图片描述

原因,这里也揭示了参数绑定的原理

在这里插入图片描述
在这里插入图片描述

getParamter()里面传入的参数是POJO对象每个属性的名字,他会尝试把每一个属性的名字作为key去请求参数中进行匹配获取


血案:

在这里插入图片描述
在这里插入图片描述

注意如果不是直接使用ajax发送put请求,而是下面这种:

在这里插入图片描述
在这里插入图片描述

直接通过ajax发送put请求的解决方案:

解决方案:在web.xml中配置spring提供的过滤器解决

代码语言:javascript
复制
  <filter>
    <filter-name>HttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
  </filter>
  <filter-mapping>
  <filter-name>HttpMethodFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
在这里插入图片描述
在这里插入图片描述

删除员工

在这里插入图片描述
在这里插入图片描述

jquery中获取所有祖先并可以加以筛选的函数

在这里插入图片描述
在这里插入图片描述

弹出框confirm()的使用

弹出框confirm()的使用


ctrl+f快捷查找某个标签,变量在当前页面的具体位值


length函数,返回查找到的元素个数

在这里插入图片描述
在这里插入图片描述

查找被选中的元素—checked

在这里插入图片描述
在这里插入图片描述

prop函数,设置单选框是否被选中,使用true或者false

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

jquery中的each方法来遍历数组和对象

在这里插入图片描述
在这里插入图片描述

在后代元素中进行筛选—find函数

在这里插入图片描述
在这里插入图片描述

js中的substring和substr的区别

js中substring()与substr()方法的区别


项目完整逻辑链代码

主页:这里是采用的模板,具体链接如下

登录模板

在这里插入图片描述
在这里插入图片描述

员工展示页面,即增删查改页面

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java"  %>
<%pageContext.setAttribute("ctx",request.getContextPath());%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<html>
<head>
    <title>员工信息展示页面</title>
</head>
<body>

<!-- 修改员工的模态框---bootstrap -->
<div class="modal fade" id="updateModel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" >
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalUpdate">修改员工信息</h4>
            </div>
            <div class="modal-body">

                <%--表单添加在此处--%>
                <form class="form-horizontal" method="post">


                    <div class="form-group">
                        <label for="inputName" class="col-sm-2 control-label">姓名:</label>
                        <div class="col-sm-10">
                            <p class="form-control-static" id="UpdateEmpName"></p>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">性别:</label>
                        <div class="col-sm-10">
                            <label class="radio-inline">
                                <input type="radio" name="gender"  value="男" checked="checked"> 男
                            </label>
                            <label class="radio-inline">
                                <input type="radio" name="gender"  value="女" > 女
                            </label>
                        </div>
                    </div>


                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label" >邮箱</label>
                        <div class="col-sm-10">
                            <input type="email" class="form-control" id="updateEmail3"  name="email" placeholder="请输入邮箱">
                            <span class="help-block"></span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">部门</label>
                        <div class="col-sm-4">
                            <select class="form-control" name="dpId" >
                                <%--下拉列表的内容是动态从数据库中取出的,并且部门提交部门id即可--%>
                                <%--通过ajax显示所有员工信息--%>


                            </select>
                        </div>
                    </div>


                </form>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" id="update_btn">更新</button>
            </div>
        </div>
    </div>
</div>





<!-- 新增员工的模态框---bootstrap -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" >
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">添加新员工</h4>
            </div>
            <div class="modal-body">

                <%--表单添加在此处--%>
                    <form class="form-horizontal" method="post">


                        <div class="form-group">
                            <label for="inputName" class="col-sm-2 control-label">姓名:</label>
                            <div class="col-sm-10">
                                <input type="text" class="form-control" id="inputName" name="empName" placeholder="请输入员工姓名" >
                                <span class="help-block"></span>
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">性别:</label>
                            <div class="col-sm-10">
                                <label class="radio-inline">
                                    <input type="radio" name="gender"  value="男" checked="checked"> 男
                                </label>
                                <label class="radio-inline">
                                    <input type="radio" name="gender"  value="女" > 女
                                </label>
                            </div>
                        </div>


                        <div class="form-group">
                            <label for="inputEmail3" class="col-sm-2 control-label" >邮箱</label>
                            <div class="col-sm-10">
                                <input type="email" class="form-control" id="inputEmail3"  name="email" placeholder="请输入邮箱">
                                <span class="help-block"></span>
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">部门</label>
                            <div class="col-sm-4">
                                <select class="form-control" name="dpId" >
                                    <%--下拉列表的内容是动态从数据库中取出的,并且部门提交部门id即可--%>
                                    <%--通过ajax显示所有员工信息--%>


                                </select>
                            </div>
                        </div>


                    </form>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" id="emp_save">保存</button>
            </div>
        </div>
    </div>
</div>




<%--搭建展示页面--%>
<div class="container">

    <%--标题--%>
  <div class="row">
      <div class="col-md-12">
          <h1 style="font-style: italic" >大忽悠集团员工展示页面</h1>
      </div>
  </div>

    <div class="row">
        <%--按钮--%>
        <div  class="col-md-4 col-md-offset-8">
            <button class="btn btn-primary" id="add_btn">新增</button>
            <button class="btn btn-danger" id="del_btn">删除</button>
        </div>
        <%--显示表格数据--%>
        <div class="row">
            <div class="col-md-12">
                <table class="table table-hover" id="emps_table">
                    <thead>
                    <tr class="info">
                        <th>
                            <input type="checkbox" id="check-all"/>
                        </th>
                        <th>#</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>邮箱</th>
                        <th>部门名字</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                 <tbody>
                 <%--使用ajax向里面添加内容--%>
                 </tbody>
                </table>
            </div>
        </div>
    </div>

    <%--显示分页信息--%>
    <div class="row">
        <%--分页文字信息--%>
        <div class="col-md-6" id="page_info-area">
      <%--使用ajax显示相关信息--%>
        </div>
        <%--分页条信息--%>
        <div class="col-md-6" id="page_info_nav">
<%--使用ajax显示相关信息--%>
        </div>
    </div>
</div>
<script>
    //1.页面加载完成以后,直接发送ajax请求,要到分页数据
    $(function (){
        //一开始去首页
       toPage(1)
    })
       //用一个全局变量,保存总的记录数
    var totalNum;
    //定义一个全局变量,保存当前页码
     var curNum;
    //跳转到指定页码号
    function toPage(pn){
        $.ajax({
            url:"${ctx}/emps",
            data:"pn="+pn,
            type:"get",
            success:function (result)
            {
                //1。解析并显示员工数据
                build_emps_table(result);
                //2。解析并显示分页信息
                build_page_info(result);
                //3.解析显示分页条数据
                build_page_nav(result);
            },
            dataType:"json"
        })
    }

        function  build_emps_table(result){
        //每次调用该方法前,需要先请客表格,因为ajax是无刷更新,每一次调用都会重复追加
            $("#emps_table tbody").empty();
            //拿到员工数组
      var e=result.extent.info.list;
        $.each(e,
            function(index,item)
            {
                //还需要追加一个多选框用于批量删除
                var checkBoxId=$("<td><input type='checkbox' class='check-item'/></td>");
                //动态创建标签并向里面添加内容
                var empID=$("<td></td>").append(item.empId);
                var empName=$("<td></td>").append(item.empName);
                var empGender=$("<td></td>").append(item.gender);
                var empEmail=$("<td></td>").append(item.email);
                var deptName=$("<td></td>").append(item.department.depName);
                //构建两个按钮                         addClass方法调用后,返回原来的元素
                var editBtn=$("<button></buttom>").addClass("btn btn-primary btn-sm edit_btn")//添加一个edit-btn属性方便操作
                    .append("<span></span>").addClass("glyphicon glyphicon-pencil").append("编辑");
                //为编辑按钮添加一个自定义的属性,来表示当前员工id
                editBtn.attr("edit-id",item.empId);
                var delBtn=$("<button></buttom>").addClass("btn btn-danger btn-sm del_btn")
                    .append("<span></span>").addClass("glyphicon glyphicon-trash").append("删除");
                //为删除按钮添加一个自定义的属性,来表示当前员工的id
                delBtn.attr("del-id",item.empId);
                //将两个按钮追加到一个单元格里面
                var btnTd=$("<td></td>").append(editBtn).append(" ").append(delBtn);
                //append方法执行完成之后还是返回原来的元素
                $("<tr></tr>").append(checkBoxId).append(empID).append(empName).append(empGender)
                .append(empEmail).append(deptName).append(btnTd).
                appendTo("#emps_table tbody");//整个表格构建完成以后,添加到对应位置中
            }
            )
        }

//解析显示分页信息
    function build_page_info(result)
    {
        //每次调用前,先清空所有之前添加的内容
        $("#page_info-area").empty();

          $("#page_info-area").append("当前第"+result.extent.info.pageNum+"页,总"+result.extent.info.pages+"共页,总共" +
              result.extent.info.total + "条记录");
        totalNum=result.extent.info.total;
        curNum=result.extent.info.pageNum;
    }

//解析显示分页条,点击分页要能去下一页
        function build_page_nav(result) {
            //每次调用前,先清空所有之前添加的内容
            $("#page_info_nav").empty();

            var ul = $("<ul></ul>").addClass("pagination");
            //attr赋值后,还是会返回当前元素,这里不能点击跳转,所以传入#,跳转到本页
            var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href", "#"));
            var prePageLi = $("<li></li>").append($("<a></a>").append("&laquo;"));
            //如果是首页,那么前进一页不能点击
            if (result.extent.info.hasPreviousPage == false) {
                firstPageLi.addClass("disabled");
                prePageLi.addClass("disabled");
            } else
            {
                firstPageLi.click(function (){
                    toPage(1);
                });
                prePageLi.click(function (){
                    toPage(result.extent.info.pageNum+1);
                });
            }
            var nextPageLi=$("<li></li>").append($("<a></a>").append("&raquo;"));
            var lastPageLi=$("<li></li>").append($("<a></a>").append("末页").attr("href","#"));
            //如果是末页,没有下一页对应也不能点
            if(result.extent.info.hasNextPage==false)
            {
                nextPageLi.addClass("disabled");
                lastPageLi.addClass("disabled");
            }else
            {
                lastPageLi.click(function (){
                    toPage(result.extent.info.pages);
                });
                nextPageLi.click(function (){
                    toPage(result.extent.info.pageNum+1);
                });
            }
            //添加首页和前一页的提示
            ul.append(firstPageLi).append(prePageLi);
            //遍历页码号
            $.each(result.extent.info.navigatepageNums,function (index,item){
                var numLi=$("<li></li>").append($("<a></a>").append(item));
                if(result.extent.info.pageNum==item)
                {
                    //如果是当前页,那么对于页码处于激活状态
                    numLi.addClass("active");
                }
                numLi.click(function (){
                    toPage(item);
                });
                ul.append(numLi);
            });
            //添加下一页和末尾的提示
            ul.append(nextPageLi).append(lastPageLi);
            //把ul加入到nav中
            var navEle=$("<nav></nav>").attr("aria-label","Page navigation").append(ul);
            navEle.appendTo("#page_info_nav");
        }


      //重置表单的函数
    function  reset_form(ele)
    {
        //清空表单里面的内容体
        $(ele)[0].reset();
        //清空之前给可能会给表单添加的样式
        //清除表单下面所有后代中含有这两个属性的
        $(ele).find("*").removeClass("has-error has-success");
        $(ele).find(".help-block").text("");
    };

    //按钮被点击,显示模态框
    $("#add_btn").click(function (){
        //清除表单数据(表单重置)---DOM里面的方法,而不是jquery里面的方法
        //这里的表单重置,不应该只是重置表单里面的内容体,包括给表单添加的样式
        reset_form("#myModal form");
        //发送ajax请求,查出部门信息,显示在下拉列表中
         getDepts("#myModal select");
        $('#myModal').modal({
            backdrop:false //点击页面其他地方,模态框也不会关闭,或者这里可以写static
        });
    })

    //查出所有部门信息,并显示在下拉列表中
    function getDepts(ele)
    {
        //每次调用该方法前,先将之前添加在下拉列表中的数据清除---ajax使用的主要问题
        $(ele).empty();
        $.ajax({
            url:"${ctx}/depts",
            type: "GET",
            success:function (result){
                //显示部门信息在下拉列表中
                $.each(result.extent.depts,function (){
                    //this指代当前遍历的元素
                    var  optionEle=$("<option></option>").append(this.depName).attr("value",this.depId);
                    //模态框下面只有一个select标签
                      optionEle.appendTo(ele);
                })
            }
        })
    }

      //校验表单数据
    function  valid_add_form()
    {
     //1.拿到要检验的数据,使用正则表达式
        var empName=$("#inputName").val();
        //正则表达式
        var regName=/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/
        //每一次给当前标签添加样式前,应该清除掉之前添加的样式
        if(!regName.test(empName))
        {
            //调用抽取出来的显示校验结果的方法
            show_valid_msg("#inputName","error","用户名可以是2-5位中文或者6-16位英文和数字的组合");
            return false;
        }else
        {
            show_valid_msg("#inputName","success","");
        }

        //校验邮箱
        var email=$("#inputEmail3").val();
        var regEmail=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
        if(!regEmail.test(email))
        {
            show_valid_msg("#inputEmail3","error","邮箱格式有误");
            return false;
        }
        else
        {
            show_valid_msg("#inputEmail3","success","");
        }
        return true;
    }

    //抽取出展示校验结果信息的方法
    function show_valid_msg(ele,status,msg)
    {
        //清除当前元素的校验状态---移除多个属性,用空格分隔开来
        $(ele).parent().removeClass("has-success has-error")
        $(ele).next("span").text("");
            if(status=="success")
            {
                $(ele).parent().addClass("has-success");
                $(ele).next("span").text(msg);
            }
            if(status=="error")
            {
                $(ele).parent().addClass("has-error");
                $(ele).next("span").text(msg);
            }
    }

     //将用户名提交到后端,验证是否可用---用户名是否重复---前端校验
   $("#inputName").change(function (){
        //获取输入框的value值
        var empName=this.value;
        //发送ajax请求校验用户名是否可用
        $.ajax({
            url:"${ctx}/checkEmp",
            data:"empName="+empName,
            type:"post",
            success:function (result){
                if(result.code==100)
                {
                    show_valid_msg("#inputName","success","用户名可用");
                    //如果校验成功了,给保存按钮上增加一个自定义属性
                    $("#emp_save").attr("ajax-va","success");
                }else
                {
                    //这里如果错误了,那么动态显示是用户名重复错误,还是校验错误
                    show_valid_msg("#inputName","error",result.extent.va_msg);
                    $("#emp_save").attr("ajax-va","error");
                }
            }
        });
    });


    //当保存按钮点击以后,提交表单的数据
    $("#emp_save").click(function (){
        //1.模态框中填写的表单数据提交给服务器进行保存
        //先对要提交给服务器的数据进行数据校验

        if(!valid_add_form())
            return false;

        //下面是前端校验用户名是否重复
        //1.判断之前的用户名校验是否成功,获取到当前按钮的校验状态,上面设置的自定义校验属性
        //这里还有一个问题需要处理,那就是当我们第一次添加一名符合规定的员工后,下一次打开表单还是上一次符合规定的员工
        //并且如果我们不对数据进行修改,那么它的用户名校验状态就是合法的,那么直接再次提交,也不会发送ajax请求进行用户名校验
        //这样就会造成人员重复添加的问题,因此这里每一次点击新增按钮,弹出模态对话框的时候,对表单进行清除操作

        if($(this).attr("ajax-va")=="error")
            return false;

        //2.发送ajax请求保存员工
        $.ajax({
urL:"${ctx}/emp",
            type:"post",
            data:$("#myModal form").serialize(),//序列化表格内容为字符串。
            success:function (result){
    //员工保存成功:
                //关闭模态框之前查看后端校验结果
                if(result.code==100)
                {
                    //1.关闭模态框
                    $("#myModal").modal("hide");
                    //2.来到最后一页,显示添加的这条记录
                    //发送ajax请求,显示最后一页数据
                    //将总记录数当做页码,分页插件如果页码大于总页码,显示最后一页,直接在xml中配置过了
                    toPage(totalNum);
                }
                else
                {

                    //后端校验用户名是否重复
                    if(undefined!=result.extent.errorName)
                    {
                        alert("用户名重复");
                        show_valid_msg("#inputName","error",result.extent.errorName);
                    }

                    //这里可以将前端校验的方法注释掉,检验后端检验正确与否
                    //有哪个字段有错误,就显示哪个字段的错误信息
                    //如果这里某个字段没有错误信息,那么会显示undefined
                      if(undefined!=result.extent.errorFields.email)
                      {
                          alert("1");
                          //显示邮箱错误信息
                          show_valid_msg("#inputEmail3","error","后端检验发现邮箱格式有误");
                      }
                     if(undefined!=result.extent.errorFields.empName)
                    {
                        alert("2");
                        //显示名字错误信息
                        show_valid_msg("#inputName","error","后端检验发现用户名格式有误");
                    }


                }
            }
        });
    });

    //此处不能直接绑定click的原因是因为,发送ajax请求动态往标签体内增加内容是在页面加载完成以后做的
    //修改员工
    //1.我们是按钮创建之前就绑定了click,所以绑定不上事件
    //2.1.我们可以在创建按钮的时候绑定,但是很麻烦
    //2.2.我们可以live函数,但是新版jquery已经废弃了这个函数,使用on进行替代
    $(document).on("click",".edit_btn",function (){
        //首先查出员工的信息,显示要修改的员工的信息
        //查出部门信息,并显示部门列表
        getDepts("#updateModel select");
        getEmp($(this).attr("edit-id"));//获取刚才给新增按钮添加的自定义属性,里面存放员工id

        //3.把员工的id传递给模态框的更新按钮
        $("#update_btn").attr("edit-id",$(this).attr("edit-id"));
$("#updateModel").modal({
    backdrop:"static"
})
    })

    //查询员工信息的方法
    //思路: 获取到员工id--->去数据库中查找对应员工,返回给前端---->前端获取数据,直接将数据回显在对应的位置
    function  getEmp(id)
    {
       $.ajax({
           url:"${ctx}/emp/"+id,
           type:"get",
           success:function (result){
              var empData=result.extent.emp;
               $("#UpdateEmpName").text(empData.empName);
               $("#updateEmail3").val(empData.email);//给输入框赋值,直接往val里面填入参数即可
               $("#updateModel input[name=gender]").val(empData.gender);
               $("#updateModel select").val(empData.dpId);
           }
       })
    }

    //点击更新,更新员工信息
    $("#update_btn").click(function (){
//验证邮箱是否合法
        //校验邮箱
        var email=$("#updateEmail3").val();
        var regEmail=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
        if(!regEmail.test(email))
        {
            show_valid_msg("#updateEmail3","error","邮箱格式有误");
            return false;
        }
        else
        {
            show_valid_msg("#updateEmail3","success","");
        }
        //2.发送ajax请求保存更新的员工数据
         $.ajax({
             //这里把员工id传递到更新按钮上,这样这里的id参数就可以直接从按钮上获得
             url:"${ctx}/emp/"+$(this).attr("edit-id"),
             type:"put",
             data:$("#updateModel form").serialize(),//表单序列化,这里是rest风格的url,因此请求参数中要附带一个_method参数
             success:function (res){
                //1.关闭模态框
                 $("#updateModel").modal("hide");
                 //2.回到主页面
               toPage(curNum);
             }

         })
    })

    //删除某个员工
    //给删除按钮搞上点击事件---注意使用on函数
    $(document).on("click",".del_btn ",function (){
        //1.弹出确认删除的对话框
        //获取要删除的人的名字
        var empName=$(this).parents("tr").find("td:eq(2)").text()
        //获取要删除的员工的id---通过在创建删除按钮的时候,直接添加一个属性记录当前id即可
        var empId=$(this).attr("del-id");
        if(confirm("确认删除"+empName+"员工吗?"))
        {

           //确认,发送ajax请求
$.ajax({
    url:"${ctx}/emp/"+empId,
    type:"delete",
    success:function (res){
        //回到本页
        toPage(curNum);
    }
})
        }
    })

    //完成全选和全不选的功能
    $("#check-all").click(function (){
//attr获取check是undefined
//对于原生的dom属性建议使用prop获取,而attr用来获取自定义属性的值
 //使用prop修改和读取dom原生属性的值
        $(".check-item").prop("checked",$(this).prop("checked"));
    });

    //此处不能直接绑定click的原因是因为,发送ajax请求动态往标签体内增加内容是在页面加载完成以后做的
    //如果单个选择框当前页全部选满了,那么最大的选择框也会被选中
    $(document).on("click",".check-item",function (){
        var flag=$(".check-item:checked").length==$(".check-item").length;
        $("#check-all").prop("checked",flag);
    })

    //点击全部删除按钮,就进行批量删除
    $("#del_btn").click(function ()
    {
        var empNames="";
        var del_idstr="";//组装员工id的字符串
          //遍历单个被选中的选择框
        $.each($(".check-item:checked"),function (){
            //当前正在遍历的item
            //获取每个单选框对应的员工名字
           empNames+=$(this).parents("tr").find("td:eq(2)").text()+",";
           //组装员工id的字符串
            del_idstr+=$(this).parents("tr").find("td:eq(1)").text()+"-";
        });
        //去除empNames字符串最后一个多余的逗号
        empNames=empNames.substring(0,empNames.length-1);//最后一个多余的逗号去掉
        //取出组装id得到的字符串的最后一个-
        del_idstr=del_idstr.substring(0,del_idstr.length-1)
        if(confirm("确认删除"+empNames+"等员工吗?"))
        {
           //发送ajax请求删除
           $.ajax({
               url:"${ctx}/emp/"+del_idstr,
               type:"DELETE",
               success:function (res){
                   //回到当前页面
                   toPage(curNum);
               }
           })
        }
    });
</script>
</body>
</html>
在这里插入图片描述
在这里插入图片描述

POJO层除了逆向工程自动生成的四个类外,还额外增添了一个消息类msg,将其作为json字符串返回给前端,并且使用链式编程和静态函数,方便直接调用

代码语言:javascript
复制
package Com.POJO;

import java.util.HashMap;
import java.util.Map;

//通用的json返回类
public class msg
{
    //状态码  100--成功  200---失败
    private  int code;
    //提示信息
    private  String msg;
    //用户要返回的给浏览器的数据放在map中
    private Map<String,Object> extent=new HashMap<String, Object>();

    public static msg success()
    {
        msg result=new msg();
        result.setCode(100);
        result.setMsg("处理成功");
        return result;
    }
    public static msg fail()
    {
        msg result=new msg();
        result.setCode(200);
        result.setMsg("处理失败");
        return result;
    }

 public msg add(String key,Object value)
 {
     this.getExtent().put(key,value);
     return this;
 }


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Map<String, Object> getExtent() {
        return extent;
    }

    public void setExtent(Map<String, Object> extent) {
        this.extent = extent;
    }
}
在这里插入图片描述
在这里插入图片描述

Dao层就是逆向工程自动生成的三个接口


注意:Dao层对应的三个逆向工程自动生成的.xml文件中,我们还需要增添两个查出员工的同时查出部门信息的方法,一个是单个员工,一个是多个员工,这里使用的是联合查询里面的左连接

代码语言:javascript
复制
<!--查出员工表的同时,查出部门信息-->
  <resultMap id="DeptResultMap" type="Com.POJO.employee">
    <id column="emp_id" jdbcType="INTEGER" property="empId" />
    <result column="emp_name" jdbcType="VARCHAR" property="empName" />
    <result column="gender" jdbcType="CHAR" property="gender" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="dp_id" jdbcType="INTEGER" property="dpId" />
    <!--使用association封装查询出来的自定义对象-->
    <association property="department" javaType="Com.POJO.department">
      <id column="dep_id" property="depId"/>
      <result column="dep_name" property="depName"/>
    </association>
  </resultMap>
  <sql id="WithDept_column_list">
    emp_id, emp_name, gender, email,dep_id,dep_name
  </sql>
  <select id="selectByExampleWithDepartmnet" resultMap="DeptResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="WithDept_column_list" />
    /*联合查询需要对此处进行修改*/
    FROM employee LEFT JOIN department ON dep_id=dp_id
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKeyWithDepartmnet" parameterType="java.lang.Integer" resultMap="DeptResultMap">
    select
    <include refid="Base_Column_List" />
    FROM employee LEFT JOIN department ON dep_id=dp_id
  </select>

service层—两个类,一个处理部门的数据库操作,一个处理员工的数据库操作

在这里插入图片描述
在这里插入图片描述

deptService:

代码语言:javascript
复制
package Com.service;

import Com.Dao.departmentMapper;
import Com.POJO.department;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class deptService {

    @Autowired
    private departmentMapper dm;

    public List<department>  getDepets()
    {
        return dm.selectByExample(null);//没有筛选条件,就是全部查出
    }
}

EmployueeService:

代码语言:javascript
复制
package Com.service;

import Com.Dao.employeeMapper;
import Com.Dao.userMapper;
import Com.POJO.departmentExample;
import Com.POJO.employee;
import Com.POJO.employeeExample;
import Com.POJO.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployueeService {
    @Autowired
  employeeMapper em;
    @Autowired
    userMapper um;
    //查询所有员工
   public List<employee> getAll()
   {

       //参数是筛选条件
       return em.selectByExampleWithDepartmnet(null);
   }
   //获取登录的信息
    public user  getUser()
    {
        return um.getUser();
    }
    //保存员工
    public int saveEmp(employee e)
    {
        //这里不插入id,因此是有选择的插入
       return em.insertSelective(e);
    }
   //后端检验用户名是否可用
    public boolean checkEmp(String empName)
    {
        //判断用户名在数据库中有几个
        employeeExample ee=new employeeExample();
        employeeExample.Criteria criteria=ee.createCriteria();
        criteria.andEmpNameEqualTo(empName);
        long count=em.countByExample(ee);
       return count==0;//如果用户名只有一个,为真,否则为假
    }

    public employee getEmp(Integer id)
    {
        return em.selectByPrimaryKey(id);
    }

    public void updateEmp(employee e) {
       em.updateByPrimaryKeySelective(e);//根据主键有选择的更新---例如员工名字不可修改,因此封装的对象的名字为null
    }

    public void deleteEmp(Integer id) {
       em.deleteByPrimaryKey(id);
    }

    public void deleteBatch(List<Integer> ids)
    {
        employeeExample ee=new employeeExample();
        employeeExample.Criteria criteria = ee.createCriteria();
        criteria.andEmpIdIn(ids);//要批量删除的id位于某个集合内
        em.deleteByExample(ee);//按照条件删除
    }
}

controller层对应也有两个类,一个处理部门请求,一个处理员工请求

DeptController:

代码语言:javascript
复制
package Com.Controller;

import Com.POJO.department;
import Com.POJO.msg;
import Com.service.deptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/*
* 处理和部门有关的请求
* */
@Controller
public class DeptController
{
    @Autowired
    private deptService ds;


    //查出所有部门信息
    @RequestMapping("/depts")
    @ResponseBody
  public msg getDepts()
  {
      return msg.success().add("depts",ds.getDepets());
  }

}

EmployeeController:

代码语言:javascript
复制
@Controller
public class EmployeeController {
    @Autowired
    EmployueeService es;
    //跳转到首页
    @RequestMapping("/emp")
    public String getEmps()
    {
        return "list";
    }

    @RequestMapping("/tolist")
   public String toList(user u)
   {
       System.out.println("tolist");
       user admin = es.getUser();
        if(u.getName().equals(admin.getName())&&u.getPassword().equals(admin.getPassword()))
       return "redirect:/emp";
        return "redirect:/index.jsp";
   }

   //使用ajax技术,显示信息
   @RequestMapping("/emps")
   @ResponseBody//这里需要导入json的依赖
   public msg getEmpWithPageinfo(@RequestParam(value = "pn",defaultValue = "1") Integer pn, Model model)
   {
       //传入当前显示的页码和每页显示记录的条数,查询语句紧跟在后面
       PageHelper.startPage(pn,5);
       List<employee> emps = es.getAll();
       //使用pageINfo包装查询后的结果
       //封装了详细的分页信息,包括查询出来的数据,传入连续显示的页数
       PageInfo page=new PageInfo(emps,5);
       model.addAttribute("info",page);
       System.out.println("emps");
       //以json形式返回---包含info信息和失败成功信息
       return msg.success().add("info",page);
   }


   //保存员工的方法:保存之前进行后端校验,因为有方法可以绕过前端校验,因此后端校验必须要有
    //后端校验是在点击保存按钮,数据库返回给数据库后,进行校验,然后才会显示相关错误信息
    //与前端你写错后,立马提示你有错误不同
    @RequestMapping(value = "/emp",method = RequestMethod.POST)
    @ResponseBody
    //@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
    //javaBean后面紧跟一个BindingResult,这个BindingResult就是封装前一个bean的校验结果
    public msg saveEmp(@Valid employee e,BindingResult result)
    {
        //后端校验用户名和邮箱格式是否正确
        if(result.hasErrors())
        {
            //校验失败,应该返回失败,在模态框中显示校验失败的错误信息
            List<FieldError> errors = result.getFieldErrors();
            Map<String ,Object> map=new HashMap<String, Object>();
            for(FieldError e1:errors)
            {
                System.out.println("错误的字段名:"+e1.getField());
                System.out.println("错误信息:"+e1.getDefaultMessage());
                map.put(e1.getField(),e1.getDefaultMessage());
            }
            return msg.fail().add("errorFields",map);
        }
        //这里添加一个后端校验用户名是否重复
        //校验用户名是否重复
        if(!es.checkEmp(e.getEmpName()))
        {
           return msg.fail().add("errorName","后端校验发现用户名不可用");
        }
        es.saveEmp(e);
        return msg.success();
    }


    //验证用户名是否可用的方法
    @RequestMapping("/checkEmp")
    @ResponseBody
    public msg checkEmp( String empName)//
    {
        //先判断用户名是否是合法表达式
        String regx="(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5}$)";
        if(!empName.matches(regx))
        {
            return msg.fail().add("va_msg","用户名必须是6-16位数字和字母的组合或者是2-5位的中文");
        }
        //数据库用户名重复校验
        boolean ret = es.checkEmp(empName);
       if(ret)
           return msg.success();
       return msg.fail().add("va_msg","用户名不可用");
    }


    //查询员工
    @RequestMapping(value = "/emp/{id}",method = RequestMethod.GET)
    @ResponseBody
    public msg getEmp(@PathVariable("id") Integer id)
    {
        employee e=es.getEmp(id);
        return msg.success().add("emp",e);
    }

    //员工更新方法
    @RequestMapping(value = "/emp/{empId}",method = RequestMethod.PUT)
    @ResponseBody
    public msg updateEmp(employee e)
    {
            es.updateEmp(e);
        return msg.success();
    }

    //员工删除方法实现
    @RequestMapping(value = "/emp/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public msg deleteEmpById(@PathVariable("id")String ids)
    {
        System.out.println("======================================");
        if(ids.contains("-"))//批量删除
        {
            System.out.println("批量删除中");
            String[] str_ids = ids.split("-");
               //调用批量删除的方法
            //组装id集合
            List<Integer> del_ids=new ArrayList<Integer>();
            for(String s:str_ids)
            {
                int i = Integer.parseInt(s);
                del_ids.add(i);
            }
            es.deleteBatch(del_ids);
        }
        else//单个删除
        {
            Integer id=Integer.parseInt(ids);
            es.deleteEmp(id);
        }
         return msg.success();
    }
}

总结

在这里插入图片描述
在这里插入图片描述

ajax和js使用注意事项

  1. 实现某个功能时,尽量抽取成一个方法,提高重用性,例如本项目中跳转到某一页的方法,和抽取出来的显示校验结果的方法
  2. 如果某个值需要在多处使用,那么可以定义一个全局变量保存该值,方便调用
  3. 使用ajax向标签中追加内容后,标签体中不会显示出现追加的内容,但是实际已经存在,那么下一次再次调用ajax时,又会重复上一次的追加行为,那么页面效果就是内容重复追加,解决办法就是在每次调用ajax之前,先将之前重复追加的内容清除掉
  4. 同理如果ajax是追加或者修改了标签的属性,那么对应的被更改的属性就会一直存在,因此下一次调用ajax之前,需要先清除之前追加给标签的属性
  5. 我们可以通过给按钮或者其他控件添加自定义属性的方式,来保存一些我们需要用到的数据,例如给删除按钮增添一个自定义属性保存当前员工的id,方便一会通过在按钮点击事件中获取到id值,从而通过ajax返回给服务器端,进行删除逻辑操作
  6. 使用ajax时,在获取到服务器端发送来的数据后,可以在成功的回调函数中,获取数据,然后通过append等方式,动态向需要的标签或位置中添加内容
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SSM整合案例
  • 关于jdbcurl后面跟的参数问题
  • SpringBoot中lombok提供的注解如下:
  • 功能
  • 技术
  • 需要的依赖
  • 通过cdn引入bootstrap及注意事项
  • 使用MBG逆向工程
  • 数据库环境搭建—含外键关联
  • maven静态资源导出问题—在web.xml中进行配置
  • 在spring核心配置容器中配置可以执行批量sqlsession
  • Spring核心配置文件
  • SpringMVC的核心配置文件
  • Mybaits核心配置文件
    • web.xml配置文件
    • 使用分页插件
    • controller层
      • 查询所有员工并分页显示的方法
        • 如何通过spring单元测试,完成对上面controller层代码的测试呢? 看下面的步骤
      • 查询员工的思路—ajax
        • 新增员工的思路
          • ajax使用时需要注意的问题:当我们使用ajax向某个标签中追加数据的时候。例如点击一个按钮,向一个div追加5条记录,那么下一次点击按钮,又会调用一次ajax请求,向里面追击五条与先前重复的记录,因此每一次在追加之前,需要先将之前追加的记录或者追加的标签属性清除
        • jquery中的正则表达式以及其他常用函数
          • js清除表单内容的reset方法
            • java中string类里面的matches校验正则表达式函数
              • 使用springmvc的JSR303数据校验需要引入一下的依赖
                • @Pattern注解中常用的校验正则表达式笔记
                  • jQuery之$(document)和on(events,[selector],[data],fn)方法
                    • jquery中的val可以获取或者设置对应的value值,设置单、多选框中被选中的状态
                      • springmvc两篇好文
                        • 占位符参数也会尝试去绑定函数中同名参数或者对象中同名属性
                          • ajax可以直接发送put和delete请求
                          • ajax发送put请求引发的血案
                            • 问题: 使用ajax直接发送put请求,封装的数据值为null
                              • 原因,这里也揭示了参数绑定的原理
                                • 血案:
                                  • 注意如果不是直接使用ajax发送put请求,而是下面这种:
                                • 直接通过ajax发送put请求的解决方案:
                                  • 删除员工
                                    • jquery中获取所有祖先并可以加以筛选的函数
                                    • 弹出框confirm()的使用
                                    • ctrl+f快捷查找某个标签,变量在当前页面的具体位值
                                  • length函数,返回查找到的元素个数
                                    • 查找被选中的元素—checked
                                      • prop函数,设置单选框是否被选中,使用true或者false
                                        • jquery中的each方法来遍历数组和对象
                                          • 在后代元素中进行筛选—find函数
                                          • js中的substring和substr的区别
                                          • 项目完整逻辑链代码
                                            • 主页:这里是采用的模板,具体链接如下
                                              • 员工展示页面,即增删查改页面
                                                • POJO层除了逆向工程自动生成的四个类外,还额外增添了一个消息类msg,将其作为json字符串返回给前端,并且使用链式编程和静态函数,方便直接调用
                                                  • Dao层就是逆向工程自动生成的三个接口
                                                    • 注意:Dao层对应的三个逆向工程自动生成的.xml文件中,我们还需要增添两个查出员工的同时查出部门信息的方法,一个是单个员工,一个是多个员工,这里使用的是联合查询里面的左连接
                                                  • service层—两个类,一个处理部门的数据库操作,一个处理员工的数据库操作
                                                    • controller层对应也有两个类,一个处理部门请求,一个处理员工请求
                                                    • 总结
                                                    • ajax和js使用注意事项
                                                    相关产品与服务
                                                    容器服务
                                                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                    领券
                                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档