Summary of Personnel Management System

Personnel Management System

1. Create a project

1.1 Create projects using reverse engineering

Automatically generate entity class bean s, mapper interfaces, and mapping files

1.2 pom.xml Writing Import Dependency

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--    Spring-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!--    section-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.6</version>
    </dependency>

    <!--    springmvc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.5</version>
    </dependency>
    <!--    fastjson-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.75</version>
    </dependency>
    <!--    jackson-databind-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.12.4</version>
    </dependency>
    <!--    mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.2</version>
    </dependency>
    <!--    mybatis-spring-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.6</version>
    </dependency>
    <!--    lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
    </dependency>
    <!--    data base-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.23</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!--    servlet api You can use native servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <!--    paging-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.2.0</version>
    </dependency>
    <!--shiro-spring-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.6.0</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!--    spring-aspects-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.7.1</version>
    </dependency>
    <dependency>
      <groupId>jspapi</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
    </dependency>

  </dependencies>

  <build>

    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>

1.2 Configuration File Writing

1.2.1 applicationContext.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:mybatis="http://mybatis.org/schema/mybatis-spring"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://mybatis.org/schema/mybatis-spring
       http://mybatis.org/schema/mybatis-spring.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1.Configure Component Scan,Main Scan service and mapper package-->
    <context:component-scan base-package="com.hrf.service,com.hrf.mapper"/>

<!--    2.Introducing an external property file-->
    <context:property-placeholder location="classpath*:jdbc.properties"/>
<!--    3.Configure Data Source-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
<!--    4.To configure sqlsessionFactory-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--        4.1 Configure Data Source-->
        <property name="dataSource" ref="dataSource"/>
        <!--        4.4 Load Settings-->
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true"/>
                <property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"/>
            </bean>
        </property>
        <!--       4.5 Plug-in Paging Plug-in-->
        <property name="plugins">
            <list>
                <bean class="com.github.pagehelper.PageInterceptor"/>
            </list>
        </property>
<!--        4.2 Define Alias-->
        <property name="typeAliasesPackage" value="com.hrf.bean"/>
        <!--        4.2 Load mybatis Core Profile configLocation-->
        <!--        <property name="configLocation" value="classpath:mybatis-config.xml"/>-->
<!--        4.3 Load mapper Configuration file inside-->
        <property name="mapperLocations" value="classpath*:com/hrf/mapper/*.xml"/>
    </bean>

    <!--    5.search mapper Mapping interface-->
    <mybatis:scan base-package="com.hrf.mapper"/>

    <!--        6.transaction management-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

<!--    7.Transaction Face Configuration-->
    <tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

<!--    8.Association of transaction facets with entry points-->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="p" expression="execution(* com.hrf.service.*.*(..))"/>
        <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="p"/>
    </aop:config>

</beans>

1.2.2 Springmvc.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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1.Component Scan,Mainly scan controller-->
    <context:component-scan base-package="com.hrf.controller"/>
<!--    2.Open Notes-->
    <mvc:annotation-driven>
<!--        If fastjson Return json Data needs to continue configuration-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="defaultCharset" value="utf-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
<!--    3.Configure View Parser-->
<!--    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
<!--        <property name="prefix" value="/"/>-->
<!--        <property name="suffix" value=".jsp"/>-->
<!--    </bean>-->
<!--    <mvc:view-resolvers>-->
<!--        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
<!--            <property name="prefix" value="/"/>-->
<!--            <property name="suffix" value=".jsp"/>-->
<!--        </bean>-->
<!--    </mvc:view-resolvers>-->
<!--    4.Processing static resources-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>


    <!-- Specify Use Cglib As AOP Dynamic Proxy Implementation -->
    <aop:config proxy-target-class="true"/>
    <!-- open Shiro Permission Annotation Support -->
<!--    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">-->
<!--        <property name="securityManager" ref="securityManager"/>-->
<!--    </bean>-->
    <!-- Handle Annotation Check Permission Page Error Exception -->
    <!-- Define exceptions that need special handling, using class or full path names as key,Exception Page Name as Value -->
<!--    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">-->
<!--        <property name="exceptionMappings"> <props>-->
<!--            <prop key="org.apache.shiro.authz.UnauthorizedException">/forbidden.jsp</prop>-->
<!--            <prop key="org.apache.shiro.authz.AuthorizationException">/forbidden.jsp</prop>-->
<!--        </props>-->
<!--        </property>-->
<!--    </bean>-->

</beans>

1.2.3 jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hrmanagement?serverTimeZone=UTC
jdbc.username=root
jdbc.password=0429

1.2.4 log4j.properties

# Global Log Configuration
log4j.rootLogger=ERROR, stdout
# MyBatis Log Configuration
log4j.logger.com.hrf.mapper=TRACE
# console output
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

1.3 Integration with the Web (Writing of 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">
  <!--  Set Welcome Page-->
  <welcome-file-list>
    <welcome-file>/WEB-INF/jsp/loginForm.jsp</welcome-file>
  </welcome-file-list>
  <!--    Configure filters-->
  <filter>
    <filter-name>code</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>code</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!--    Configure Central Processor-->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--        binding springmvc-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!--    Spring Context Listener Configuration Listener-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  


  <!--    shiro Filter-->
<!--  <filter>-->
<!--    <filter-name>shiroFilter</filter-name>-->
<!--    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>-->
<!--  </filter>-->
<!--  <filter-mapping>-->
<!--    <filter-name>shiroFilter</filter-name>-->
<!--    <url-pattern>/*</url-pattern>-->
<!--    <dispatcher>REQUEST</dispatcher>-->
<!--    <dispatcher>FORWARD</dispatcher>-->
<!--  </filter-mapping>-->


  <!--    Set Session Configuration session-timeout 5 Minute-->
<!--  <session-config>-->
<!--    <session-timeout>5</session-timeout>-->
<!--  </session-config>-->

</web-app>

Note: Set the default welcome page, loginForm.jsp, to log in and see the code above.

1.4 Import Tool Class

1.4.1 Paging Label

package com.hrf.util;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * Paging Label
 */
public class PagerTag extends SimpleTagSupport {
	
	/** Define placeholder constants in request URL s */
	private static final String TAG = "{0}";
	
	/** CurrentPage */
	private int pageIndex;
	/** Number of displays per page */
	private int pageSize;
	/** Total number of records */
	private int recordCount;
	/** Request URL page.action?pageIndex={0}*/
	private String submitUrl;
	/** style */
	private String style = "sabrosus";
	
	/** Define total pages */
	private int totalPage = 0;
	
	/**  Referencing a custom label on a page triggers a label processing class   */
	@Override
	public void doTag() throws JspException, IOException {
		/** Define it as stitching the end result */
		StringBuilder res = new StringBuilder();
		/** Define the page number in the middle of its stitching */
		StringBuilder str = new StringBuilder();
		/** Judging the total number of records */
		if (recordCount > 0){   //1499 / 15  = 100
			/** Paging labels need to be displayed to calculate how many pages the total number of pages needs to be divided */
			totalPage = (this.recordCount - 1) / this.pageSize + 1; 
			
			/** a label is not required to determine the previous or next page */
			if (this.pageIndex == 1){ // home page
				str.append("<span class='disabled'>Previous page</span>");
				
				/** Calculate the middle page number */
				this.calcPage(str);
				
				/** Next page does not require a label */
				if (this.pageIndex == totalPage){
					/** Only one page */
					str.append("<span class='disabled'>next page</span>");
				}else{
					String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1));
					str.append("<a href='"+ tempUrl +"'>next page</a>");
				}
			}else if (this.pageIndex == totalPage){ // End Page
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1));
				str.append("<a href='"+ tempUrl +"'>Previous page</a>");
				
				/** Calculate the middle page number */
				this.calcPage(str);
				
				str.append("<span class='disabled'>next page</span>");
			}else{ // Middle
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1));
				str.append("<a href='"+ tempUrl +"'>Previous page</a>");
				
				/** Calculate the middle page number */
				this.calcPage(str);
				
				tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1));
				str.append("<a href='"+ tempUrl +"'>next page</a>");
			}
			
			/** Stitch together other information */
			res.append("<table width='100%' align='center' style='font-size:13px;' class='"+ style +"'>");
			res.append("<tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>" + str.toString());
			res.append("&nbsp;Jump To&nbsp;&nbsp;<input style='text-align: center;BORDER-RIGHT: #aaaadd 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #aaaadd 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 2px; MARGIN: 2px; BORDER-LEFT: #aaaadd 1px solid; COLOR: #000099; PADDING-TOP: 2px; BORDER-BOTTOM: #aaaadd 1px solid; TEXT-DECORATION: none' type='text' size='2' id='pager_jump_page_size'/>");
			res.append("&nbsp;<input type='button' style='text-align: center;BORDER-RIGHT: #dedfde 1px solid; PADDING-RIGHT: 6px; BACKGROUND-POSITION: 50% bottom; BORDER-TOP: #dedfde 1px solid; PADDING-LEFT: 6px; PADDING-BOTTOM: 2px; BORDER-LEFT: #dedfde 1px solid; COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; BORDER-BOTTOM: #Dedfde 1px solid; TEXT-DECORATION: none'value='ok' id='pager_ Jump_ Btn'/>';
			res.append("</td></tr>");
			res.append("<tr align='center'><td style='font-size:13px;'><tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>");
			/** Number of start bars */
			int startNum = (this.pageIndex - 1) * this.pageSize + 1;
			/** Number of end bars */
			int endNum = (this.pageIndex == this.totalPage) ? this.recordCount : this.pageIndex * this.pageSize;
			
			res.append("In total<font color='red'>"+ this.recordCount +"</font>Bar records, currently displayed"+ startNum +"-"+ endNum +"Records.");
			res.append("</td></tr>");
			res.append("</table>");
			res.append("<script type='text/javascript'>");
			res.append("   document.getElementById('pager_jump_btn').onclick = function(){");
			res.append("      var page_size = document.getElementById('pager_jump_page_size').value;");
			res.append("      if (!/^[1-9]\\d*$/.test(page_size) || page_size < 1 || page_size > "+ this.totalPage +"){");
			res.append("          alert('Please enter[1-"+ this.totalPage +"]Page number between!');");
			res.append("      }else{");
			res.append("         var submit_url = '" + this.submitUrl + "';");
			res.append("         window.location = submit_url.replace('"+ TAG +"', page_size);");
			res.append("      }");
			res.append("}");
			res.append("</script>");
			
			
		}else{
			res.append("<table align='center' style='font-size:13px;'><tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>Total <font color='red'>0</font>records, currently displaying 0-0 records. </ Td></tr></table>";
		}
		this.getJspContext().getOut().print(res.toString());
	}
	
	
	/** Method of calculating intermediate page number */
	private void calcPage(StringBuilder str) {
		/** Judging Total Pages */
		if (this.totalPage <= 11){
			/** Show all page numbers at once */
			for (int i = 1; i <= this.totalPage; i++){
				if (this.pageIndex == i){
					/** CurrentPage */
					str.append("<span class='current'>"+ i +"</span>");
				}else{
					String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
					str.append("<a href='"+ tempUrl +"'>"+ i +"</a>");
				}
			}
		}else{
			/** Near Home Page */
			if (this.pageIndex <= 8){
				for (int i = 1; i <= 10; i++){
					if (this.pageIndex == i){
						/** CurrentPage */
						str.append("<span class='current'>"+ i +"</span>");
					}else{
						String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<a href='"+ tempUrl +"'>"+ i +"</a>");
					}
				}
				str.append("...");
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage));
				str.append("<a href='"+ tempUrl +"'>"+ this.totalPage +"</a>");
			}
			/** Near End Page */
			else if (this.pageIndex + 8 >= this.totalPage){
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1));
				str.append("<a href='"+ tempUrl +"'>1</a>");
				str.append("...");
				
				for (int i = this.totalPage - 10; i <= this.totalPage; i++){
					if (this.pageIndex == i){
						/** CurrentPage */
						str.append("<span class='current'>"+ i +"</span>");
					}else{
						tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<a href='"+ tempUrl +"'>"+ i +"</a>");
					}
				}
			}
			/** In the middle */
			else{
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1));
				str.append("<a href='"+ tempUrl +"'>1</a>");
				str.append("...");
				
				for (int i = this.pageIndex - 4; i <= this.pageIndex + 4; i++){
					if (this.pageIndex == i){
						/** CurrentPage */
						str.append("<span class='current'>"+ i +"</span>");
					}else{
						tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<a href='"+ tempUrl +"'>"+ i +"</a>");
					}
				}
				
				str.append("...");
				tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage));
				str.append("<a href='"+ tempUrl +"'>"+ this.totalPage +"</a>");
			}
		}
	}

	/** setter Method */
	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount;
	}
	public void setSubmitUrl(String submitUrl) {
		this.submitUrl = submitUrl;
	}
	public void setStyle(String style) {
		this.style = style;
	}
}

1.4.2 Authentication Code Related

package com.hrf.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCodeUtils {
    //With Algerian fonts, you need to install fonts if they are not available on the system. Fonts are capitalized, with 1,0,i,o characters removed and W characters taken up too wide
    public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVXYZ";
    private static Random random = new Random();


    /**
     * Generate Authentication Code with System Default Character Source
     * @param verifySize    Authentication code length
     * @return
     */
    public static String generateVerifyCode(int verifySize){
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }
    /**
     * Generate Authentication Code with Specified Source
     * @param verifySize    Authentication code length
     * @param sources   Authentication Code Character Source
     * @return
     */
    public static String generateVerifyCode(int verifySize, String sources){
        if(sources == null || sources.length() == 0){
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));
        }
        return verifyCode.toString();
    }

    /**
     * Generate a random validation code file and return the validation code value
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }

    /**
     * Output random authenticator picture stream and return the authenticator value
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }

    /**
     * Generate the specified Authentication Code image file
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException{
        if(outputFile == null){
            return;
        }
        File dir = outputFile.getParentFile();
        if(!dir.exists()){
            dir.mkdirs();
        }
        try{
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch(IOException e){
            throw e;
        }
    }

    /**
     * Output Specified Authentication Code Picture Stream
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for(int i = 0; i < colors.length; i++){
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);

        g2.setColor(Color.GRAY);// Set border color
        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);
        g2.setColor(c);// Set Background Color
        g2.fillRect(0, 2, w, h-4);

        //Draw interference lines
        Random random = new Random();
        g2.setColor(getRandColor(160, 200));// Set the color of the line
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }

        // add noise
        float yawpRate = 0.05f;// Noise Rate
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }

        shear(g2, w, h, c);// Twist the picture

        g2.setColor(getRandColor(100, 160));
        int fontSize = h-4;
        Font font = new Font("Algerian", Font.PLAIN, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for(int i = 0; i < verifySize; i++){
            //AffineTransform affine = new AffineTransform();
            //affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);
            //g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);
        }

        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }

    private static Color getRandColor(int fc, int bc) {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }

    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }

    private static void shear(Graphics g, int w1, int h1, Color color) {
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }

    private static void shearX(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(2);

        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);

        for (int i = 0; i < h1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(0, i, w1, 1, (int) d, 0);
            if (borderGap) {
                g.setColor(color);
                g.drawLine((int) d, i, 0, i);
                g.drawLine((int) d + w1, i, w1, i);
            }
        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(40) + 10; // 50;

        boolean borderGap = true;
        int frames = 20;
        int phase = 7;
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }

        }

    }
}

1.4.3 Paged PageModel

package com.hrf.util;

import java.io.Serializable;

public class PageModel implements Serializable{
	private Integer pageIndex=1;
	private Integer pageSize=6;
	private Integer recordCount;
	public Integer getPageIndex() {
		return pageIndex;
	}
	public void setPageIndex(Integer pageIndex) {
		this.pageIndex = pageIndex;
	}
	public Integer getPageSize() {
		return pageSize;
	}
	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}
	public Integer getRecordCount() {
		return recordCount;
	}
	public void setRecordCount(Integer recordCount) {
		this.recordCount = recordCount;
	}
	
	public PageModel() {
		super();
	}
	public PageModel(Integer pageIndex, Integer pageSize, Integer recordCount) {
		super();
		this.pageIndex = pageIndex;
		this.pageSize = pageSize;
		this.recordCount = recordCount;
	}
	
}

Paging may not be used, but a paging plugin is required

2. Write project code

2.1 Create a controller layer

2.2 Create service layer

3. Implementation of user login module

3.1 UserLoginController implementation, using shiro

package com.hrf.controller;

import com.hrf.bean.User;
import com.hrf.service.UserLoginService;
import com.hrf.util.VerifyCodeUtils;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

@Controller
@Slf4j
public class UserLoginController {
    @Autowired
    private UserLoginService userLoginService;
//  1. Check the verification code
    @RequestMapping("/checkCode")
    public void checkCode(String num, HttpSession session, HttpServletResponse response) throws IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        int w = 200, h = 80;
        String code = VerifyCodeUtils.generateVerifyCode(4);
        session.setAttribute("code",code);
        VerifyCodeUtils.outputImage(w, h, outputStream, code);
        outputStream.close();
    }
//    2. Log on
    @RequestMapping("/login")
    public String login(String loginname,String password, String user_input_verifyCode,Model model,HttpSession session) throws Exception {
        //        If the username and password are not empty, call shiro to verify that the username and password are correct
        if (loginname==null||("").equals(loginname)){
            model.addAttribute("msg","Login name cannot be empty");
            throw new Exception("User name cannot be empty");
        }
        if (password==null||("").equals(password)){
            model.addAttribute("msg","Password cannot be empty");
            throw new Exception("Password cannot be empty");
        }
//        if (user_input_verifyCode==null||("").equals(user_input_verifyCode)){
//            model.addAttribute("msg", "Authentication code cannot be empty");
//            throw new Exception("Authentication code cannot be empty");
//        }
//        Encapsulate username and password as token objects
        UsernamePasswordToken token = new UsernamePasswordToken(loginname, password);
//        shiro verify login success
        try{
//            shiro login
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
//            Query user based on loginname
            User user_session = userLoginService.findUserByLoginname(loginname);
            session.setAttribute("user_session",user_session);
//            Jump to the successful login page
            return "/jsp/index.jsp";
        }catch (UnknownAccountException e){
//            Logon failed, print exception information
            log.error("user name does not exist");
        }catch (LockedAccountException e){
            log.error("Account Locked");
        }catch (IncorrectCredentialsException e){
            log.error("Password error");
        }catch (AuthenticationException e) {
            // Other authentication exceptions
            log.error("Logon Failure");
        }
        model.addAttribute("msg","User name or password error!");
//        Return to the login page
        return "/jsp/loginForm.jsp";
    }



//    3. Home page display
    @RequestMapping("/welcome")
    public String welcome(){
        return "/jsp/welcome.jsp";
    }

//    4. User registration
    @RequestMapping("/register/registCode")
    public String registCode(){
        System.out.println("User registration");
        return "/jsp/regist.jsp";
    }
//    5. Retrieve your password
    @RequestMapping("/password/repassword")
    public String repassword(){
        System.out.println("Retrieve password!");
        return "/jsp/findPwd.jsp";
    }

    @RequestMapping("/logOut")
    public String logOut(HttpSession session){
//        Remove user from session
        session.removeAttribute("user_session");
//        Invalidate session
        session.invalidate();
//        Return to the login page
        return "/jsp/loginForm.jsp";
    }


}

3.2 Customize realm classes, authenticate, authorize

package com.hrf.util;

import com.hrf.bean.User;
import com.hrf.service.UserLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/*
    Custom Authentication Class
 */
@Slf4j
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private UserLoginService userLoginService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.debug("Start Authorization---------");
        //Get the current logged on user identity
        String loginname = (String)principalCollection.getPrimaryPrincipal();
        //Associate database tables to find user-specific roles, permissions menus
        // Analog data
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole("admin");
        return info;
//        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.debug("Start Authentication....");
        //Authentication Method
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //Get User Identity
        String loginname = (String)token.getPrincipal();
//       Get password credentials
        //4. Get the credential password
        char[] cs = (char[]) token.getCredentials();
        String password = String.valueOf(cs);

        //First parameter source code Second parameter salt salt Third parameter iteration number
        Md5Hash password1 = new Md5Hash(password,loginname,5);
        System.out.println(password1);
        //Analog data, only username equals admin, assuming the user exists
        User user = userLoginService.findUserByLoginname(loginname);
        if (user!=null) {
             return new SimpleAuthenticationInfo(loginname,
                    user.getPassword(),
                    ByteSource.Util.bytes(loginname),
                    getName());
        }
        return null;
    }
}

Note: how shiro works

1. Shiro Running Process

For example, a login process:
1. Call Subject.login(token) to log in first, and he will delegate it to SecurityManager
2. SecurityManager is responsible for the real authentication logic; It delegates authentication to Authenticator;
3. Authenticator passes the corresponding token into Realm, obtains authentication information from Realm, returns authentication failure if not, and continues if not.

2. Describe the Shiro certification process

1. The application code calls the Subject.login method to pass the created AutohenticationToken instance that contains the Principals (identity) and Reduentials (credentials) of the end user;
2. The Subject instance delegates the application's SecurityManager to begin real validation by calling securityManager.login(token); Subject instance (usually DelegatingSubject or its subclasses)
3. SubjectManager receives token and calls the internal Authenticator instance to call authenticator.authenticate(token).Authenticator is usually a ModularRealmAuthenticator instance that supports reconciling one or more Realm instances in authentication;
4. If more than one Realm is configured in the application, the ModularRealmAuthenticator instance will use the configured AuthenticationStrategy to initiate the Multi-Realm authentication attempt. Before, during, and after Realms are invoked by authentication, AuthenticationStrategy is invoked to enable it to respond to the results of each Realm. (AuthenticationStrategy is called to react to the results of each Realm);
5. The Realm of each configuration is used to help see if it supports the submitted Authentication Token. If so, the getAuthentication Info method that supports Realm will be called with the submitted token. The getAuthentication Info method effectively represents a single authentication attempt for a specific Realm.

3. How to configure using Shiro in Spring

1, configure Shiro's Filter in web.xml;
2. Configure Shiro in Spring's configuration file;
3. Configure custom Realm: implement custom authentication and authorization;
4. Configure the caching strategy used by Shiro entity classes;
5. Configure SecurityManager;
6. Configure a Lifecycle Bean postprocessor that guarantees that the Shiro internal Bean declaration cycle is executed;

4. For fuzzy queries on search, paging, query lists are best written in a controller

4.1 Front End Writes Path

4.1.1 index.jsp front-end interface

<li>
                <a href="javascript:;">
                    <i class="iconfont">&#xe6b4;</i>
                    <cite>Download Center</cite>
                    <i class="iconfont nav_right">&#xe697;</i>
                </a>
                <ul class="sub-menu">
                    <li>
                        <a _href="${pageContext.request.contextPath}/document/list">
                            <i class="iconfont">&#xe6a7;</i>
                            <cite>Document Query</cite>
                        </a>
                    </li>
                    <li id="document">
                        <a _href="${pageContext.request.contextPath}/document/toadd">
                            <i class="iconfont">&#xe6a7;</i>
                            <cite>Upload Document</cite>
                        </a>
                    </li>
                </ul>
            </li>

4.1.2 list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fkjava" uri="/pager-tags" %> 
<!DOCTYPE html>
<html>
  
  <head>
    <meta charset="UTF-8">
    <title>document information</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
    <link rel="shortcut icon" href="${pageContext.request.contextPath}/public/logo.ico" type="image/x-icon" />
    <link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/font.css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/xadmin.css">
    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/public/lib/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/public/js/xadmin.js"></script>
    <script type="text/javascript">
    $(function(){
    	/** Download Document Function */
    	$("a[id^='down_']").click(function(){
    		/** Get the id of the document you want to download */
    		var id = this.id.replace("down_","");
    		/** Download the document */
    		window.location = "${pageContext.request.contextPath}/document/downLoad?id="+id;
    	})
    })
    </script>
    
    <script type="text/javascript">
    $(function(){
    	if(${count}!=0){
    		$("#count1").hide();
    		$("#count2").show();
    	}
    	var username = "${sessionScope.user_session.loginname}";
    	if(username=="admin"||username=="manager"){
    		$("#aaa").show(); 
    		$("#bbb").show(); 
    		$("#do").css("display", "block"); 
    		$("#ID").css("display", "block"); 
    		$('tr').find('td:eq(0)').show();
    		$('tr').find('td:eq(8)').show();
    	}else{
    		$("#aaa").hide();
    		$("#bbb").hide(); 
    		$("#do").css("display", "none"); 
    		$("#ID").css("display", "none");
    		$('tr').find('td:eq(8)').hide();
    	};
    }) 
  </script>
  </head>
  
  <body>
    <div class="x-nav">
      <span class="layui-breadcrumb">
        <a href="">home page</a>
        <a>
          <cite>document information</cite></a>
      </span>
            <button id="aaa" type="button" οnclick="location.href='${pageContext.request.contextPath}/document/toadd'" class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:innert;margin-left:75%;;"  lay-submit="" lay-filter="sreach"><i class="layui-icon"></i>increase</button>
      
      <a id="bbb" class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" href="${pageContext.request.contextPath}/document/list" title="Refresh">
        <i class="layui-icon" style="line-height:30px">ဂ</i></a>
    </div>
    <div class="x-body">
      <div class="layui-row" style="" align="center">
        <form class="layui-form layui-col-md12 x-so" method="get" action="${pageContext.request.contextPath}/document/list">
          <input type="text" name="content" style="width:50%;"  placeholder="Please enter your search" autocomplete="off" class="layui-input">
          <button class="layui-btn"  lay-submit="" lay-filter="sreach"><i class="layui-icon">&#xe615;</i></button>
        </form>
      </div>
      
     
      
      <table class="layui-table">
        <thead>
          <tr>
            <th>
              <div class="layui-unselect header layui-form-checkbox" lay-skin="primary"><i class="layui-icon">&#xe605;</i></div>
            </th>
            <th>ID</th>
            <th>Title</th>
            <th>describe</th>
            <th>file name</th>
            <th>Release date</th>
            <th>Publishing Users</th>
            <th>download</th>
            <th id="do">operation</th>
        </thead>
        <tbody>
        <c:forEach items="${requestScope.list}" var="document" varStatus="stat">
     <tr>
            <td>
              <div class="layui-unselect layui-form-checkbox"  lay-skin="primary" data-id='2'><i class="layui-icon">&#xe605;</i></div>
            </td>
            
            <td>${document.id}</td>
            <td>${document.title }</td>
            <td>${document.remark }</td>
            <td>${document.filename }</td>
            <td>${document.createdate}</td>
            <td>${document.user.username }</td>
            <td align="center"  width="40px;"><a href="#" id="down_${document.id }">
				<img width="20" height="20" title="download" src="${pageContext.request.contextPath}/public/images/downLoad.png"/></a>
			</td>
            <td class="td-manage">
              
              <a title="edit"  href='${pageContext.request.contextPath}/document/toedit?id=${document.id}'>
                <i class="layui-icon">&#xe642;</i>
              </a>
              <a title="delete" οnclick="member_del(this,'${document.id }')" href="javascript:;">
                <i class="layui-icon">&#xe640;</i>
              </a>
            </td>
          </tr>
			</c:forEach>
        </tbody>
      </table>
         <!-- Paging Label -->
     <div style="margin-left: 400px;" id="count1">
         <fkjava:pager
	  	        pageIndex="${requestScope.pageModel.pageIndex}" 
	  	        pageSize="${requestScope.pageModel.pageSize}" 
	  	        recordCount="${requestScope.pageModel.recordCount}" 
	  	        style="digg"
	  	        submitUrl="${pageContext.request.contextPath}/document/list?pageIndex={0}"/>
     </div>
      <div style="margin-left: 500px; display: none;" id="count2">
                <p style="color: rgb(0,97,222)">Total queries to<font color="red">${count}</font>Bar data</p>
       </div>
    </div>
   
   
    <script>
      /*User-Delete*/
      function member_del(obj,id){
          layer.confirm('Are you sure you want to delete it?',function(index){
              //Send Asynchronous Delete Data
              //Wait until you use asynchronous, use it here first
              $.get("${pageContext.request.contextPath}/document/delete?id="+id);
              $(obj).parents("tr").remove();
              layer.msg('Deleted!',{icon:1,time:1000});
              location.reload();
          });
      }

      function delAll (argument) {
        var data = tableCheck.getData();
        layer.confirm('Are you sure you want to delete it?'+data,function(index){
            //Catch all selected and delete asynchronously
            layer.msg('Delete succeeded', {icon: 1});
            $(".layui-form-checked").not('.header').parents('tr').remove();
        });
      }
    </script>
  </body>

</html>

4.2 controller Layer Writing

package com.hrf.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hrf.bean.Document;
import com.hrf.service.DocumentService;
import com.hrf.util.PageModel;
import com.hrf.util.UTF8String;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.jws.WebParam;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("/document")
public class DocumentController {

    @Autowired
    private DocumentService documentService;

    @RequestMapping("/list")
    public String list(@RequestParam(name = "pageIndex",defaultValue = "1") Integer pageIndex,
                       @RequestParam(name = "content",defaultValue = "") String content,
                       PageModel pageModel,
                       Model model){
        PageHelper.startPage(pageIndex,5);
        List<Document> documentList = documentService.findDocumentList(content);
//        This is a paging class
        PageInfo pageInfo = new PageInfo(documentList);
        List list = pageInfo.getList();

        pageModel.setPageIndex(pageIndex);
        pageModel.setRecordCount((int) pageInfo.getTotal());

        model.addAttribute("list",list);
        model.addAttribute("pageModel",pageModel);
        return "/jsp/document/list.jsp";
    }
}

4.3 Service Layer Interfaces and Implementation Classes

4.3.1 Interface

package com.hrf.service;

import com.hrf.bean.Document;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public interface DocumentService {
    List<Document> findDocumentList(String content);
}

4.3.2 Implementation Class

package com.hrf.service;

import com.hrf.bean.Document;
import com.hrf.mapper.DocumentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DocumentServiceImpl implements DocumentService{
    @Autowired
    private DocumentMapper documentMapper;
    @Override
    public List<Document> findDocumentList(String content) {
        return documentMapper.selectAll(content);
    }

}

4.4 mapper interface and sql statement

4.4.1 mapper interface

package com.hrf.mapper;

import com.hrf.bean.Document;
import org.springframework.stereotype.Component;

import java.util.List;
@Component
public interface DocumentMapper {
    int deleteByPrimaryKey(Integer id);
}

Implementation of 4.4.2 SQL statement

<resultMap id="BaseResultMap" type="com.hrf.bean.Document">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="title" jdbcType="VARCHAR" property="title" />
    <result column="filename" jdbcType="VARCHAR" property="filename" />
    <result column="remark" jdbcType="VARCHAR" property="remark" />
    <result column="createdate" jdbcType="TIMESTAMP" property="createdate" />
    <result column="user_id" jdbcType="INTEGER" property="userId" />
    <association property="user" javaType="User" autoMapping="true"/>
</resultMap>

<select id="selectAll" resultMap="BaseResultMap">
    select d.id, title, filename, remark, d.createdate, d.user_id,u.username
    from document_inf d
    left join user_inf u on d.user_id=u.id
<where>
      <if test="content!=null">
        title like '%' #{content} '%'
      </if>
    </where>
  </select>

4.5 Implementation Class

package com.hrf.bean;

import java.util.Date;

public class Document {
    private Integer id;

    private String title;

    private String filename;

    private String remark;

    private Date createdate;

    private Integer userId;
    //Relationships One-to-One
    private User user;
    //You can also pass in attributes, but it's best to pass in attributes
    //private String username;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename == null ? null : filename.trim();
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark == null ? null : remark.trim();
    }

    public Date getCreatedate() {
        return createdate;
    }

    public void setCreatedate(Date createdate) {
        this.createdate = createdate;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}

5. Paging without custom tags

5.1 controller layer

 @RequestMapping("/list")
    public String list(@RequestParam(name = "page",defaultValue = "1") Integer page,
            @RequestParam(name = "size",defaultValue = "5") Integer size,
            @RequestParam(name = "content",defaultValue = "") String content,
            HttpServletRequest request){
        List<Employee> employeeList = employeeService.findEmployeeAll(page,size,content);
        PageInfo pageInfos = new PageInfo(employeeList);
        request.setAttribute("pageInfos",pageInfos);
        return "/jsp/employee/list.jsp";
    }

5.2 service layer implementation class

 @Override
    public List<Employee> findEmployeeAll(@Param("page") Integer page,
                                          @Param("size") Integer size,
                                          @Param("content") String content) {
        PageHelper.startPage(page,size);
        return employeeMapper.selectAll2(content);
    }

sql statement inside 5.3 mapper

 <select id="selectAll2" resultMap="BaseResultMap">
    select e.id, e.dept_id, e.job_id, e.name ename, e.card_id, e.address, e.phone, e.sex_id, e.education_id,
    e.createdate, e.user_id, u.id uid, u.username , u.email,j.name jname, d.name dname, ed.name edname ,s.name sexname
    from employee_inf e left join user_inf u on e.user_id=u.id
    left join job_inf j on e.job_id=j.id
    left join dept_inf d on e.dept_id=d.id
    left join education_inf ed on e.education_id=ed.id
    LEFT JOIN sex_inf s ON e.sex_id = s.id
    <where>
      <if test="content!=null">
        or e.name like '%' #{content} '%'
      </if>
      <if test="content!=null">
        or e.address like '%' #{content} '%'
      </if>
      <if test="content!=null">
        or u.username like '%' #{content} '%'
      </if>
      <if test="content!=null">
        or j.name like '%' #{content} '%'
      </if>
      <if test="content!=null">
        or d.name like '%' #{content} '%'
      </if>
      <if test="content!=null">
        or ed.name like '%' #{content} '%'
      </if>
    </where>
  </select>
  
  <resultMap id="BaseResultMap" type="com.hrf.bean.Employee">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="dept_id" jdbcType="INTEGER" property="deptId" />
    <result column="job_id" jdbcType="INTEGER" property="jobId" />
    <result column="ename" jdbcType="VARCHAR" property="name" />
    <result column="card_id" jdbcType="VARCHAR" property="cardId" />
    <result column="address" jdbcType="VARCHAR" property="address" />
    <result column="phone" jdbcType="VARCHAR" property="phone" />
    <result column="sex_id" jdbcType="INTEGER" property="sexId" />
    <result column="education_id" jdbcType="INTEGER" property="educationId" />
    <result column="createdate" jdbcType="TIMESTAMP" property="createdate" />
    <result column="user_id" jdbcType="INTEGER" property="userId" />
    <association property="user" javaType="User" autoMapping="true">
    </association>
    <association property="job" javaType="Job" autoMapping="true">
      <result property="name" column="jname"/>
    </association>
    <association property="dept" javaType="Dept" autoMapping="true">
      <result property="name" column="dname"/>
    </association>
    <association property="education" javaType="Education" autoMapping="true">
      <result property="name" column="edname"/>
    </association>
    <association property="sex" javaType="Sex" autoMapping="true">
      <result property="name" column="sname"/>
    </association>
  </resultMap>

5.4 Front End Implementation

5.4.1 JSP code

<link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/myPage.css">
  <c:forEach items="${requestScope.pageInfos.list}" var="employee" varStatus="stat">
     <tr>
            <td>
              <div class="layui-unselect layui-form-checkbox" lay-skin="primary" data-id='2'><i class="layui-icon">&#xe605;</i></div>
            </td>
            <td>${employee.name }</td>
            <td>${employee.user.username}</td> <!--Easy to know who is associated with whom  -->
            <td>
					 <c:choose>
					      <c:when test="${employee.sexId==1}">male</c:when>
					      <c:otherwise><font>female</font></c:otherwise>
					 </c:choose>
			</td>
            <td>${employee.phone }</td>
            <td>${employee.user.email }</td>
            <td>${employee.job.name }</td>
            <td>${employee.dept.name }</td>
            <td>${employee.education.name }</td>
            <td>${employee.cardId }</td>
            <td>${employee.address }</td>
            <td>${employee.createdate}</td>
            <td class="td-manage">
             <a title="edit"  href='${pageContext.request.contextPath}/employee/toedit?id=${employee.id}'>
                <i class="layui-icon">&#xe642;</i>
              </a>
              <a title="delete" οnclick="member_del(this,'${employee.id}')" href="javascript:;">
                <i class="layui-icon">&#xe640;</i>
              </a>
            </td>
          </tr>
			</c:forEach>
          
        </tbody>
      </table>
         <!-- Paging Label -->
     <div style="margin-left: 400px;" id="count1">
         <ul class="pagination modal-1">
             <li><a href="${pageContext.request.contextPath}/employee/list?page=1&size=5" class="pre">home page</a></li>
             <c:if test="${pageInfos.pageNum==1}">
                 <li><a href="${pageContext.request.contextPath}/employee/list?page=1&size=5" class="prev">Previous page</a></li>
             </c:if>
             <c:if test="${pageInfos.pageNum!=1}">
                 <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pageNum-1}&size=5" class="prev">Previous page</a></li>
             </c:if>
             <c:forEach begin="1" end="${pageInfos.pages}" var="pageNumber">
                 <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageNumber}&size=5" class="active">${pageNumber}</a></li>
             </c:forEach>
             <c:if test="${pageInfos.pageNum!=pageInfos.pages}">
                 <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pageNum+1}&size=5" class="next">next page</a></li>
             </c:if>
             <c:if test="${pageInfos.pageNum==pageInfos.pages}">
                 <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pages}&size=5" class="next">next page</a></li>
             </c:if>
             <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pages}&size=5" class="next">End Page</a></li>
         </ul>
     </div>

Style him with 5.4.2 css code

.pagination {
    list-style: none;
    display: inline-block;
    padding: 0;
    margin-top: 10px;
}
.pagination li {
    display: inline;
    text-align: center;
}
.pagination a {
    float: left;
    display: block;
    font-size: 14px;
    text-decoration: none;
    padding: 5px 12px;
    color: #fff;
    margin-left: -1px;
    border: 1px solid transparent;
    line-height: 1.5;
}
.pagination a.active {
    cursor: default;
}
.pagination a:active {
    outline: none;
}

.modal-1 li:first-child a {
    -moz-border-radius: 6px 0 0 6px;
    -webkit-border-radius: 6px;
    border-radius: 6px 0 0 6px;
}
.modal-1 li:last-child a {
    -moz-border-radius: 0 6px 6px 0;
    -webkit-border-radius: 0;
    border-radius: 0 6px 6px 0;
}
.modal-1 a {
    border-color: #ddd;
    color: #4285F4;
    background: #fff;
}
.modal-1 a:hover {
    background: #eee;
}
.modal-1 a.active, .modal-1 a:active {
    border-color: #4285F4;
    background: #4285F4;
    color: #fff;
}

5.6 Result style for last page break

6. Uploading and downloading files

6.1 File Upload

The implementation of 6.1.1 front-end pages must have three points

(1): Uploaded files are uploaded to the server and saved to the database are file names
(2): The uploaded file is uploaded as a file converted to a binary stream
(3): enctype="multipart/form-data" needs to be set inside the form, otherwise the file cannot be submitted

  </head> 
  <body>
    <div class="x-body">
        <form class="layui-form" method="POST" id="deptForm" enctype="multipart/form-data" action="${pageContext.request.contextPath}/document/add">
        <input type="hidden" name="id" id="id" value="${document.id }" >
        <input type="hidden" name="userId" id="user_id" value="${sessionScope.user_session.id}" >
          <div class="layui-form-item">
              <label for="username" class="layui-form-label">
                  <span class="x-red">*</span>Title
              </label>
              <div class="layui-input-inline">
                  <input type="text" id="title" name="title" required="" lay-verify="required"
               placeholder="No less than 3 Chinese characters"   autocomplete="off" class="layui-input" value="${document.title }">
              </div>
             
          </div>
        <div class="layui-form-item">
              <label for="username" class="layui-form-label">
                  <span class="x-red">*</span>describe
              </label>
              <div class="layui-input-inline">
                  <input type="text" id="remark" name="remark" required="" lay-verify="required"
                placeholder="No less than 5 Chinese characters"   autocomplete="off" class="layui-input" value="${document.remark }">
              </div>
             
          </div>
         <div class="layui-form-item">
              <label for="username" class="layui-form-label">
                  <span class="x-red">*</span>Upload Files
              </label>
              <div class="layui-input-inline">
                  <input type="file" id="file" name="file"  >
                  <p class="x-red">You must choose to upload a file</p>
                  <p class="x-red">${param.message}</p>
              </div>
             
          </div>
          <div class="layui-form-item">
              <label for="L_repass" class="layui-form-label">
              </label>
              <input type="submit" value=" Submit" class="layui-btn" lay-filter="add" lay-submit=""/>
                 
          </div>
      </form>
    </div>
   
  </body>

</html>

6.1.2 controller Layer Method Implementation

  Perform new operations,File Upload
    @RequestMapping("/add")
    public String add(Document document,
                      @RequestParam("file") MultipartFile multipartFile,
                      HttpServletRequest request) throws ParseException, IOException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//Set date format
        document.setCreatedate(df.parse(df.format(new Date())));
        //        Upload Document
            // Get absolute path to file upload to specific folder
            String realpath = request.getSession().getServletContext().getRealPath("/upload/");
            // Get the uploaded file name
            String fileName = multipartFile.getOriginalFilename();
            //To ensure the rename of the uploaded file, process the file name
            fileName = UUID.randomUUID().toString() +"_"+ fileName;
            // Building file objects from paths
            // Attention must be paid to the path problem during the construction process
            File uploadFile = new File(realpath, fileName);
            // Determines whether the specified folder uploadfiles exist and creates them if they do not exist
            if (!uploadFile.exists()) {
                uploadFile.mkdirs();
            }
            // Upload Files
            multipartFile.transferTo(uploadFile);
        document.setFilename(fileName);
        documentService.addDocument(document);

        return "redirect:/document/list";
    }

6.2 File Download

//    File Download
    @RequestMapping("/downLoad")
    public String downLoad(HttpServletRequest request,
                           HttpServletResponse response,
                           Integer id) throws IOException {
//       Get File Name
        Document document = documentService.findDocumentById(id);
        String filename = document.getFilename();
        // Get the downloaded file path
        String realpath = request.getSession().getServletContext().getRealPath("/WEB-INF/files/");
        // Set the response header when downloading files
        response.setHeader("Content-Type", "application/x-msdownload");
        response.setHeader("Content-Disposition", "attachment;filename=" + UTF8String.toUTF8String(filename));
        // Get File Input Stream
        FileInputStream in = new FileInputStream(new File(realpath, filename));
        // Gets the output stream of the response object used to output binary data to the client
        ServletOutputStream out = response.getOutputStream();
        out.flush();
        int aRead = 0;
        byte[] b = new byte[1024];
        // Write to Response Output Stream
        while ((aRead = in.read(b)) != -1 && in != null) {
            out.write(b, 0, aRead);
        }
        out.flush();
        // Close IO Object
        in.close();
        out.close();
        return "redirect:/document/list";
    }
    /**
     * Character encoding conversion method for saving Chinese file names when downloading
     */
    public String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer();
        int len = str.length();
        for (int i = 0; i < len; i++) {
            // Remove each character from the string
            char c = str.charAt(i);
            // Do not process when Unicode value is 0-255
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else {
                // Convert to utf-8 encoding
                byte[] b;
                try {
                    b = Character.toString(c).getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO: handle exception
                    e.printStackTrace();
                    b = null;
                }
                // Convert to string form of%HH
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0) {
                        k &= 255;
                    }
                    sb.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return sb.toString();
    }

7. Add people in bulk (take employees for example)

7.1 Batch Tool Class

package com.hrf.util;

import com.hrf.bean.Employee;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

public class ExcelData {
    private XSSFSheet sheet;

    /**
     * Constructor to initialize excel data
     * @param filePath  excel Route
     * @param sheetName sheet Table Name
     */
    public ExcelData(String filePath, String sheetName){
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(filePath);
            XSSFWorkbook sheets = new XSSFWorkbook(fileInputStream);
            //Get sheet
            sheet = sheets.getSheet(sheetName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Getting cell data based on row and column indexes
     * @param row
     * @param column
     * @return
     */
    public String getExcelDateByIndex(int row,int column){
        XSSFRow row1 = sheet.getRow(row);
        String cell = row1.getCell(column).toString();
        return cell;
    }

    /**
     * Gets the value of column x of a row based on the row whose column value is'****'
     * @param caseName
     * @param currentColumn Index of the current cell column
     * @param targetColumn Index of target cell column
     * @return
     */
    public String getCellByCaseName(String caseName,int currentColumn,int targetColumn){
        String operateSteps="";
        //Get Number of Rows
        int rows = sheet.getPhysicalNumberOfRows();
        for(int i=0;i<rows;i++){
            XSSFRow row = sheet.getRow(i);
            String cell = row.getCell(currentColumn).toString();
            if(cell.equals(caseName)){
                operateSteps = row.getCell(targetColumn).toString();
                break;
            }
        }
        return operateSteps;
    }

    //Print excel data
    public void readExcelData(){
        //Get Number of Rows
        int rows = sheet.getPhysicalNumberOfRows();
        for(int i=0;i<rows;i++){
            //Get the number of columns
            XSSFRow row = sheet.getRow(i);
            int columns = row.getPhysicalNumberOfCells();
            for(int j=0;j<columns;j++){
                String cell = row.getCell(j).toString();
                System.out.println(cell);
            }
        }
    }
    //Get Length
    public int len(String file){
        ExcelData sheet1 = new ExcelData(file, "Sheet1");

        int i=0;
        while (true){
            try {
                String c=sheet1.getExcelDateByIndex(i,0);
                i++;
            }catch (NullPointerException e){
                break;
            }
        }
        return i;
    }
    //test method
    public static void main(String[] args){

    }
    //read object
    public List<Employee> employeeList(String file){
        ExcelData excelData=new ExcelData(file,"Sheet1");
        int i=excelData.len(file);
        //System.out.println(i);
        List<Employee> list=new ArrayList<>();
        for(int j=1;j<i;j++){
            String id=excelData.getExcelDateByIndex(j,0);
            String dept_id=excelData.getExcelDateByIndex(j,1);
            String job_id=excelData.getExcelDateByIndex(j,2);
            String name=excelData.getExcelDateByIndex(j,3);
            String card_id=excelData.getExcelDateByIndex(j,4);
            String address=excelData.getExcelDateByIndex(j,5);
            String phone=excelData.getExcelDateByIndex(j,6);
            String sex_id=excelData.getExcelDateByIndex(j,7);
            String education_id=excelData.getExcelDateByIndex(j,8);
            Employee employee=new Employee();
            employee.setId(Integer.parseInt(id));
            employee.setDeptId(Integer.parseInt(dept_id));
            employee.setJobId(Integer.parseInt(job_id));
            employee.setName(name);
            employee.setCardId(card_id);
            employee.setAddress(address);
            employee.setPhone(phone);
            employee.setSexId(Integer.parseInt(sex_id));
            employee.setEducationId(Integer.parseInt(education_id));
            list.add(employee);
        }
        return list;
    }
}

7.2 controller Layer Method

//    Join in in batch
    @RequestMapping("/piliang")
    public String piliang(@RequestParam("file") MultipartFile file,
                          HttpServletRequest req,
                          Model model) throws IOException {
//        Designed to upload and download files
        String fileName= file.getName();
        String uploadPath= WebUtils.getRealPath(req.getSession().getServletContext(),"/upload/");
        String path= uploadPath+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + fileName;
        file.transferTo(new File(path));
        ExcelData excelData=new ExcelData(path,"sheet1");
        List<Employee> list=excelData.employeeList(path);
        int i=employeeService.pladd(list);
        if (i!=0){
            model.addAttribute("message","ok");
        }else {
            model.addAttribute("message","error");
        }
        return "redirect:/employee/list";
    }

8 Data visualization

8.1 Data Visualization Tool Class

package com.hrf.util;

public class ChartsVo {

    private String name;
    private Integer value;
    private Integer mailmarketing;
    private Integer allianceadvertising;
    private Integer videoadvertising;
    private Integer directaccess;
    private Integer searchengine;

    public Integer getMailmarketing() {
        return mailmarketing;
    }

    public void setMailmarketing(Integer mailmarketing) {
        this.mailmarketing = mailmarketing;
    }

    public Integer getAllianceadvertising() {
        return allianceadvertising;
    }

    public void setAllianceadvertising(Integer allianceadvertising) {
        this.allianceadvertising = allianceadvertising;
    }

    public Integer getVideoadvertising() {
        return videoadvertising;
    }

    public void setVideoadvertising(Integer videoadvertising) {
        this.videoadvertising = videoadvertising;
    }

    public Integer getDirectaccess() {
        return directaccess;
    }

    public void setDirectaccess(Integer directaccess) {
        this.directaccess = directaccess;
    }

    public Integer getSearchengine() {
        return searchengine;
    }

    public void setSearchengine(Integer searchengine) {
        this.searchengine = searchengine;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public ChartsVo() {
    }

    public ChartsVo(String name, Integer value) {
        this.name = name;
        this.value = value;
    }
}

Methods in the 8.2 controller layer

package com.hrf.controller;

import com.hrf.service.EmployeeService;
import com.hrf.util.ChartsVo;
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 StatisticsController {
    @Autowired
    private EmployeeService employeeService;

//    Visualize data
    @RequestMapping("/statistics")
    public String statistics(){

        return "/jsp/statistics/statistics.jsp";
    }
    //Get the percentage of men to women
    @RequestMapping("/echartsData")
    @ResponseBody
    public List<ChartsVo> echartsData() {
        List<ChartsVo> list= employeeService.getSexCount();
        return list;
    }

    //Get the number of employees for each position
    @RequestMapping("/echartsData1")
    @ResponseBody
    public List<ChartsVo> echartsData1() {
        List<ChartsVo> list= employeeService.getJobCount();
        return list;
    }
    //Get the number of business types processed in a week
    @RequestMapping("/echartsData2")
    @ResponseBody
    public List<ChartsVo> echartsData2() {
        List<ChartsVo> list= employeeService.getBusinessCount();
        return list;
    }
    //Get the number of residence addresses for each employee
    @RequestMapping("/echartsData3")
    @ResponseBody
    public List<ChartsVo> echartsData3() {
        List<ChartsVo> list= employeeService.getAddressCount();
        return list;
    }
}

8.3 service layer implements methods in classes

//Get the percentage of men to women
    @Override
    public List<ChartsVo> getSexCount() {
        List<ChartsVo> list = new ArrayList<>();
        int male = employeeMapper.selectByMale();
        ChartsVo maleChartsVo = new ChartsVo("Male",male);
        list.add(maleChartsVo);
        int female = employeeMapper.selectByFemale();
        ChartsVo femaleChartsVo = new ChartsVo("Female sex",female);
        list.add(femaleChartsVo);
        return list;
    }
    //Get the number of employees for each position
    @Override
    public List<ChartsVo> getJobCount() {
        return employeeMapper.getJobCount();
    }
    //Get the number of business types processed in a week
    @Override
    public List<ChartsVo> getBusinessCount() {
        return employeeMapper.getBusinessCount();
    }
    //Get the number of residence addresses for each employee
    @Override
    public List<ChartsVo> getAddressCount() {
        return employeeMapper.getAddressCount();
    }

sql statement inside 8.4 mapper

 <!--  Query the number of employees with male gender-->
  <select id="selectByMale" resultType="int">
    select count(*) from employee_inf e ,sex_inf s where e.sex_id=s.id and s.name= 'male'
  </select>
  <!--  Query the number of employees whose gender is female-->
  <select id="selectByFemale" resultType="int">
    select count(*) from employee_inf e ,sex_inf s where e.sex_id=s.id and s.name= 'female'
  </select>
  <!--  Query the number of employees in each position-->
  <select id="getJobCount" resultType="com.hrf.util.ChartsVo">
    select count(e.job_id) value,j.name from employee_inf e join job_inf j on e.job_id=j.id group by e.job_id
  </select>
  <!--  Get the number of business types processed in a week-->
  <select id="getBusinessCount" resultType="com.hrf.util.ChartsVo">
    select *  from business_inf
  </select>
  <!--  Get the number of residence addresses for each employee-->
  <select id="getAddressCount" resultType="com.hrf.util.ChartsVo">
    select count(*) value ,address name from employee_inf group by address
  </select>

Keywords: Java Javascript JQuery Maven html

Added by chimp1950 on Thu, 02 Dec 2021 17:58:17 +0200