ContextLoaderListener监听器和SSM整合

news2024/7/6 20:55:29

ContextLoaderListener监听器

Spring提供了监听器ContextLoaderListener,实现ServletContextListener接口,
可监听ServletContext的状态,在web服务器的启动,读取Spring的配置文件,
创建Spring的IOC容器。web应用中必须在web.xml中配置。

作用:在服务器启动的时候,加载spring的配置文件,获取spring的ioc容器。

过程:

~通过监听器进行监听服务器的状态,在服务器启动时直接创建springioc的容器,
在springmvc获取ioc容器的时候直接完成自动装配的过程中对controller里面的service自动装配。

原因:

~监听器里面的初始化方法只执行一次,获取ioc容器的时候没必要每次都要获取,
因为创建ioc容器都是通过配置文件创建出来的,通过同一个配置文件创建的ioc没有区别。
~监听器的初始化方法是服务器启动之后第一个执行的方法,比DispatcherServlet初始化时间还早,
就可以通过监听器创建spring的ioc容器,当DispatcherServlet初始化的时候,
就可以完成controller里面的service自动装配。

web.xml

<!--  监听器 -->
  <listener>
<!--    在服务器启动时加载spring配置文件-->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!--
 Spring配置文件默认位置和名称:/WEB-INF/applicationContext.xml
  可通过上下文参数自定义Spring配置文件的位置和名称
  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:ApplicationContext.xml</param-value>
  </context-param>

ssm增删改查分页

引入依赖

    <properties>
<!--      自定义属性,spring版本,统一管理各个依赖的版本      -->
        <spring.version>5.3.1</spring.version>
    </properties>

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--springmvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--      事务管理器的类在spring-aspects依赖中  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
<!--切面-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
<!--        -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- Mybatis核心 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!--mybatis和spring的整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
<!--        分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- ServletAPI -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
<!--     json格式   -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.1</version>
        </dependency>
<!--     文件上传   -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- Spring5和Thymeleaf整合包 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.12.RELEASE</version>
        </dependency>

数据库表

配置web.xml

<!-- 配置spring的编码过滤器 -->
  <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>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

<!-- 配置处理请求方式的过滤器 -->
  <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>
  
<!-- 配置前端控制器 -->
  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--  设置springmvc配置文件自定义的位置和名称  -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
<!--  DispatcherServlet的初始化时间提前到服务器启动时  -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
<!-- 配置spring的监听器,在服务器启动时加载spring的配置文件 -->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 设置spring配置spring配置文件自定义的位置和名称 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>

springmvc配置文件

<!--扫描控制层组件-->
    <context:component-scan base-package="com.atguigu.ssm.controller"></context:component-scan>

<!--配置视图解析器 -->
    <bean id="viewResolver"
          class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean
                            class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8" />
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

<!--   配置默认的servlet处理静态资源 -->
    <mvc:default-servlet-handler/>
<!--    开启mvc的注解驱动-->
    <mvc:annotation-driven/>
<!-- 配置视图控制器   -->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
    <mvc:view-controller path="/to/add" view-name="/employee_add"></mvc:view-controller>
<!--   配置文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
<!--   配置拦截器 有需要在配置 -->
<!--   异常解析器 有需要在配置 -->

搭建Mybatis环境

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

核心配置文件mybatis-config.xml

<configuration>
    <!--  Mybatis核心配置文件中的标签必须要按照指定的顺序配置  -->

<!--    <properties resource="jdbc.properties"></properties>-->

    <!--  设置全局配置 将下划线映射为驼峰 -->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <package name=" "/>
    </typeAliases>
<!--注释的都让spring管理了-->
<!--    <environments default="development">-->
<!--        <environment id="development">-->
<!--            <transactionManager type="JDBC"/>-->
<!--            <dataSource type="POOLED">-->
<!--                <property name="driver" value="${jdbc.driver}"/>-->
<!--                <property name="url" value="${jdbc.url}"/>-->
<!--                <property name="username" value="${jdbc.username}"/>-->
<!--                <property name="password" value="${jdbc.password}"/>-->
<!--            </dataSource>-->
<!--        </environment>-->
<!--    </environments>-->

    <!--   引入mybatis的映射文件 -->
<!--    <mappers>-->
<!--        <package name=" "/>-->
<!--    </mappers>-->
    
<!--  分页插件  -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

</configuration>

Mapper接口和映射文件

public interface EmployeeMapper {

}
<mapper namespace="com.atguigu.ssm.mapper.EmployeeMapper">

</mapper>

日志文件log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}
%m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

Spring的配置文件并配置

 <!--扫描组件 除控制层-->
    <context:component-scan base-package="com.atguigu.ssm">
<!--  排除控制层扫描  -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
<!--引入jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--  数据源  -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    <!--  配置事务管理器  -->
    <!--  事务管理器在spring-jdbc这个依赖中  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--     管理事务,基于连接对象操作的,连接对象交给数据源管理的   -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--  开启事务的注解驱动 将使用的注解@transactionManager标识的方法或类中所有的方法进行事务管理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

<!--  整合mybatis  -->
<!--  配置SqlSessionFactoryBean  mybatis-spring的依赖提供的  -->
<!-- 可以直接来获取工程bean所提供的的对象   -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--   
        可以通过spring配置核心配置文件也可以在mybatis的核心配置文件配置。
        dataSource:数据源   mapperLocations:映射文件路径  
        configurationProperties:全局配置  plugins:插件  
        typeAliasesPackage:类型别名所对应的包   
          -->
        <!--   configLocation:设置mybatis核心配置文件路径, -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--     设置数据源   -->
        <property name="dataSource" ref="dataSource"></property>
<!--     设置类型别名所对应的包 (实体类别名)   -->
        <property name="typeAliasesPackage" value="com.atguigu.ssm.pojo"></property>
        
<!--设置映射文件的路径: 映射文件路径和mapper接口的路径不一致才设置 -->
<!--     <property name="mapperLocations" value="classpath:mappers/*.xml"></property>  -->
        
    </bean>
   <!-- 
     配置mapper接口的扫描,MapperScannerConfigurer可以把指定的包下面所有的mapper接口
     通过SqlSessionFactory所提供的的sqlsession对象来创建mapper接口的代理实现类对象交给ioc管理。
     所以直接在service自动装配mapper接口对象就可以
   -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.atguigu.ssm.mapper"></property>
    </bean>

组件

实体类Employee

package com.atguigu.ssm.pojo;

public class Employee {
    private Integer empId;
    private String empName;
    private Integer age;
    private String gender;
    private String email;

    public Employee() {
    }
   ....
}

控制层EmployeeController

@Controller
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
//分页查询
    @RequestMapping(value = "/employee/page/{pageNum}",method = RequestMethod.GET)
    public String getEmployeePage(@PathVariable("pageNum") Integer pageNum,Model model){
//        调用service层 查询员工数据和处理分页信息
        PageInfo<Employee> pageInfo=employeeService.getEmployeePage(pageNum);
//        将分页数据共享到请求域中
        model.addAttribute("pageInfo",pageInfo);
//        跳转employee_list.html
        return "employee_list";
    }
//    查询数据(数据没有分页)
//    @RequestMapping(value = "/employee",method = RequestMethod.GET)
//    public String getAllEmployee(Model model){
//        //    查询所有的员工信息
//        List<Employee> list= employeeService.getAllEmployee();
//        System.out.println(list);
        将员工信息在请求域中共享数据
//        model.addAttribute("list",list);
        跳转employee_list.html
//        return "employee_list";
//    }

//    添加数据
    @RequestMapping(value = "/employee",method = RequestMethod.POST)
    public String AddEmployee(Employee employee){
//        调用service层 把接收浏览器的数据传过去 处理添加数据
        employeeService.addEmployee(employee);
//        重定向
        return "redirect:/employee/page/1";
    }

//    修改查询数据
    @RequestMapping(value = "/employee/{empId}")
    public String servletupdateEmployee(@PathVariable("empId") Integer empId, Model model){
//        根据id查询所有数据
        Employee employee= employeeService.servletupdateEmployee(empId);
//  共享域数据
        model.addAttribute("employee",employee);
        return "employee_update";
    }

//    修改数据
    @RequestMapping(value = "/employee",method = RequestMethod.PUT)
    public String updateEmployee( Employee employee){
        System.out.println("employee="+employee);
        employeeService.updateEmployee(employee);
        return "redirect:/employee/page/1";
    }

//    删除数据
    @RequestMapping(value = "/employee/{empId}",method = RequestMethod.DELETE)
    public String deleteEmployee(@PathVariable("empId") Integer empId){
        employeeService.deleteEmployee(empId);
        return "redirect:/employee/page/1";
    }
}

service层

public interface EmployeeService {
    
//    查询所有的员工信息
    List<Employee> getAllEmployee();
//获取员工分页的信息
    PageInfo<Employee> getEmployeePage(Integer pageNum);
    
//添加数据
    void addEmployee(Employee employee);

    //修改之前查询数据
    Employee servletupdateEmployee(Integer empId);
  //修改数据
    void updateEmployee(Employee employee);
    
//根据id删除数据
    void deleteEmployee(Integer empId);
}
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public List<Employee> getAllEmployee() {
//        调用mapper接口 查询所有数据(没有分页)
        return employeeMapper.getAllEmployee();
    }

    @Override
    public PageInfo<Employee> getEmployeePage(Integer pageNum) {
//        开启分页功能   当前页的页码(从浏览器传过来的),每页显示的条数
//        本身是拦截器的功能,会对当前查询进行拦截,sql预语句中直接加入limit实现分页功能
        PageHelper.startPage(pageNum,4);
//    调用mapper接口    查询所有的员工信息并且分页
        List<Employee> list = employeeMapper.getAllEmployee();
//  获取分页相关数据   当前查询的员工集合 , 导航分页 23456,以当前也为原点,显示前面页码和后面页码 (导航分页的页码数)
        PageInfo<Employee> page=new PageInfo<>(list,5);
        return page;
    }

    @Override
    public void addEmployee(Employee employee) {
//     调用mapper接口   添加数据
        employeeMapper.addEmployee(employee);
    }

    @Override
    public Employee servletupdateEmployee(Integer empId) {
//      调用mapper接口  根据id查询数据进行修改
       Employee employee= employeeMapper.servletupdateEmployee(empId);
       return employee;
    }
    @Override
    public void updateEmployee(Employee employee) {
//     调用mapper接口   修改数据
        employeeMapper.updateEmployee(employee);
    }

    @Override
    public void deleteEmployee(Integer empId) {
//        调用mapper接口 删除数据
        employeeMapper.deleteEmployee(empId);
    }
}

mapper接口和mapper核心配置文件

package com.atguigu.ssm.mapper;

import com.atguigu.ssm.pojo.Employee;

import java.util.List;

public interface EmployeeMapper {
//查询所有员工信息
    List<Employee> getAllEmployee();

//添加数据
    void addEmployee(Employee employee);

//    修改查询数据
    Employee servletupdateEmployee(Integer empId);
//修改数据
    void updateEmployee(Employee employee);

//删除数据
    void deleteEmployee(Integer empId);
}
<!--    List<Employee> getAllEmployee();-->
    <select id="getAllEmployee" resultType="Employee">
        select * from t_emp
    </select>

<!--        void addEmployee(Employee employee);-->
    <insert id="addEmployee">
        insert into t_emp values(null,#{empName},#{age},#{gender},#{email})
    </insert>
<!--修改 查询数据-->
<!--    servletupdateEmployee-->
    <select id="servletupdateEmployee" resultType="Employee">
        select * from t_emp where emp_id=#{empId}
    </select>

<!--                void updateEmployee(Employee employee, Integer empId); -->
    <update id="updateEmployee">
        update t_emp set emp_name=#{empName},age=#{age},gender=#{gender},email="email" where emp_id=#{empId};
    </update>

<!--        void deleteEmployee(Integer empId);-->
    <delete id="deleteEmployee">
        delete from t_emp where emp_id=#{empId}
    </delete>

浏览器页面

index.html

<h1>index.html</h1>
<!--默认访问第一页-->
<a th:href="@{/employee/page/1}">查询当前员工分页信息</a>

employee_list.html

<head>
    <meta charset="UTF-8">
    <title>员工列表</title>
    <link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<div id="app">
<table>
    <tr>
        <th colspan="6">Employee Info</th>
    </tr>
    <tr>
        <th>emp_id</th>
        <th>emp_name</th>
        <th>age</th>
        <th>sex</th>
        <th>email</th>
        <th>options</th>
    </tr>
<!--   pageInfo.list    共享的是pageInfo对象的list属性表示当前页的数据     -->
    <tr th:each="employee: ${pageInfo.list}">
        <td th:text="${employee.empId}"></td>
        <td th:text="${employee.empName}"></td>
        <td th:text="${employee.age}"></td>
        <td th:text="${employee.gender}"></td>
        <td th:text="${employee.email}"></td>
        <td>
            <a @click="deleteEmployee" th:href="@{'/employee/'+${employee.empId}}">delete</a>
            <a th:href="@{'/employee/'+${employee.empId}}">update</a>
            <a th:href="@{/to/add}">add</a>
        </td>
    </tr>
</table>
    <form method="post">
        <input type="hidden" name="_method" value="delete">
    </form>

<!--  处理分页  -->
<div style="text-align: center;">
<!--  如果结果为true,当前这个标识就会显示页面中,false不显示  -->
<!--    hasPreviousPage:是否存在上一页,如果存在,就显示首页和上一页    prePage: 上一页的页码 -->
    <a th:if="${pageInfo.hasPreviousPage}" th:href="@{/employee/page/1}">首页</a>
    <a th:if="${pageInfo.hasPreviousPage}" th:href="@{'/employee/page/'+${pageInfo.prePage}}">上一页</a>

<!--  根据数据的条数 序列导航分页的页码  navigatepageNums:导航分页的页码(123...)  -->
    <span th:each="num : ${pageInfo.navigatepageNums}">
<!--    pageNum:当前页的页码      -->
            <a th:if="${pageInfo.pageNum == num}"style="color: red"  th:href="@{'/employee/page/'+${num}}" th:text="'['+${num}+']'"></a>
            <a th:if="${pageInfo.pageNum != num}" th:href="@{'/employee/page/'+${num}}" th:text="${num}"></a>
    </span>

<!-- nextPage:下一页  pages:末页 -->
    <a th:if="${pageInfo.hasNextPage}" th:href="@{'/employee/page/'+${pageInfo.nextPage}}">下一页</a>
    <a th:if="${pageInfo.hasNextPage}" th:href="@{'/employee/page/'+${pageInfo.pages}}">末页</a>
</div>
</div>

<!--
  处理result风格 删除请求必须为delete,但是目前浏览器支持post和get不支持delete,
  想要请求可以修改为delete,必须为post请求才能修改
  -->
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">
    let vue=new Vue({
        el:"#app",
        date:'',
        methods:{
            deleteEmployee(){
                //    获取form表单
                let form=document.querySelectorAll("form")[0];
                //   将超链接的href属性值赋值给form表单的action属性
                form.action=event.target.href;   //event.target 表示当前触发事件的标签
                //    表单提交
                form.submit();
                //阻止超链接的默认行为
                event.preventDefault();
            }
        }
    })
</script>
</body>

employee_add.html

<title>add employee</title>
<link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<form th:action="@{/employee}" method="post">
    <table>
        <tr>
            <th colspan="2">add employee</th>
        </tr>

        <td>empName</td>
        <td>
            <input type="text"name="empName">
        </td>

        <tr>
            <td>email</td>
            <td>
                <input type="text" name="email">
            </td>
        </tr>
        <tr>
            <td>age</td>
            <td>
                <input type="text" name="age">
            </td>
        </tr>
        </tr>

        <tr>
            <td>gender</td>
            <td>
                <input type="radio" name="gender" value="1">male
                <input type="radio" name="gender" value="0">female
            </td>
        </tr>

        </tr>

        <tr>
            <td></td>
            <td colspan="2">
                <input type="submit" value="add">
            </td>
        </tr>
    </table>
</form>

employee_update.html

 <title>update employee</title>
    <link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<h1>update</h1>
<form th:action="@{/employee}" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="hidden" name="empId" th:value="${employee.empId}">

    <table>
        <tr>
            <th colspan="2">update employee</th>
        </tr>
        <tr>
            <td>empName</td>
            <td>
                <input type="text" name="empName" th:value="${employee.empName}">
            </td>
        </tr>
        <tr>
            <td>email</td>
            <td>
                <input type="text" name="email" th:value="${employee.email}">
            </td>
        </tr>

        <tr>
            <td>age</td>
            <td>
                <input type="text" name="age" th:value="${employee.age}">
            </td>
        </tr>
        <tr>
            <td>gender</td>
            <td>
                <input type="radio" name="gender" value="1" th:field="${employee.gender}">male
                <input type="radio" name="gender" value="0" th:field="${employee.gender}">female
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="update">
            </td>
        </tr>
    </table>
</form>
</body>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/386003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于linux采用桥连接网络模式

关于linux&#xff08;centos&#xff09;采用桥连接网络模式 下载安装VmWare&#xff0c;并创建centos虚拟机 找到自己的虚拟机&#xff0c;点击编辑虚拟机设置-网络适配器-桥接模式 点击编辑-虚拟网络编辑器 点击更改设置-自动桥接 进入系统-修改网络配置文件 #进入到…

一个使用 react+vite3+ts+react-router-dom6v Hooks Admin搭建的轻量级后台管理模板。

react18-vite3-ts-antd4react-router-dom6v 前言 之所以搭这个模板&#xff0c;对于工作上业务需求老是变来变去&#xff0c;就觉得很烦&#xff0c;干脆搭了个admin模板&#xff0c;这样自己熟悉&#xff0c;好根据业务的需求进行一个修改。很多人会说后端管理系统模板都差不…

一文看懂REE OS、TEE OS、CA以及TA概念、架构、流程

目录 一、概念 二、使能方式 三、TEE软件框架 四、TEE软件流程 一、概念 REE&#xff08;Rich Execution Environment&#xff09;&#xff1a;比如Android系统&#xff0c;是一个开放的环境&#xff0c;容易收到恶意软件的攻击&#xff0c;比如敏感数据被窃取、数字版权被…

Mask R-cnn 代码运行报错总结

Mask R-cnn 代码运行报错总结环境版本1. 数据集下载与参数配置2. 运行报错开始报错1报错2报错3报错4报错5报错6参考文章 文章1文章2 环境版本 TensorFlow 2.1.0Python 3.7keras 2.3.1 1. 数据集下载与参数配置 下载链接 https://github.com/matterport/Mask_RCNN/releases …

MySQL存储引擎详解及对比和选择

什么是存储引擎&#xff1f; MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术&#xff0c;你能够获得额外的速度或者功能&#xff0c;从而改善…

Java关键字、标识符、变量数据类型

文章目录关键字标识符标识符的命名规则标识符的命名规范变量变量的数据类型整数类型浮点类型浮点型精度字符类型布尔类型关键字 定义&#xff1a;被 Java 语言赋予了特殊含义&#xff0c;用做专门用途的字符串&#xff08;或单词&#xff09;HelloWorld 案例 中&#xff0c;出现…

7年测试工程师,裸辞掉17K的工作,想跳槽找更好的,还是太高估自己了....

14年大学毕业后&#xff0c;在老师和朋友的推荐下&#xff0c;进了软件测试行业&#xff0c;这一干就是7年时间&#xff0c;当时大学本来就是计算机专业&#xff0c;虽然专业学的一塌糊涂&#xff0c;但是当年的软件测试属于新兴行业&#xff0c;人才缺口比较大&#xff0c;而且…

南卡Neo骨传导运动耳机正式发布,打造音质最强款骨传导耳机

最近中国专业骨传导领先品牌NANK南卡发布全新Neo系列骨传导运动耳机&#xff0c;全新来袭的南卡Neo骨传导运动耳机主打音质使用体验&#xff0c;耳机配置上做到更为强劲升级优化&#xff0c;支持一体化机身&#xff0c;首发无线充设计&#xff0c;IPX6等级防水&#xff0c;升级…

Android---进程间通信机制2

Service Manager(SM)&#xff1a;大管家。管理系统服务的 Ibinder。 1 如何启动 service_manager 服务 SM注册&#xff1a; 1 binder_open(): 打开驱动(设置大小128K)&#xff0c;内存映射 2 binder_become_context_manager(): 设置 SM 为大管家 --- sm 作用&#xff1a;为…

【Python学习笔记】第二十六节 Python PyMySQL

一、什么是 PyMySQL&#xff1f;PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库。可以用它来连接Python和MySQL。如果你追求速度&#xff0c;这是一个很好的选择&#xff0c;因为它比mysql-connector-python快。PyMySQL 遵循 Python 数据库 API v2.0 规范&#x…

【存储】存储特性

存储特性精简配置技术&#xff08;SmartThin&#xff09;SmartThin主要功能容量虚拟化存储空间写时分配&#xff1a;Capacity-on-Write读写重定向&#xff1a;Direct-on-Time应用场景及配置流程存储分层技术&#xff08;SmartTier&#xff09;存储分层工作原理关键技术容量初始…

智能电子标签——商超版价签

2.1英寸TFT黑白电子价签 ★ 快速变价&#xff0c;高效运营 ★ 市场实用&#xff0c;布局物联网未来 ★ 更好客户体验 ★ 降低系统成本&#xff0c;具备竞争力 ★ 2.1英寸黑白红电子价签 ★ 电池低能耗&#xff0c;常规使用三年 ★ 穿透力强不慣障碍 ★ 2.4G载波&#x…

position:sticky 粘性定位

1、什么是粘性定位&#xff1f; 粘性定位它基于用户的滚动位置来定位。 粘性定位的元素是依赖于用户的滚动&#xff0c;在 position:relative 与 position:fixed 定位之间切换。 它的行为就像 position:relative; 而当页面滚动超出目标区域时&#xff0c;它的表现就像 position…

图机器学习-图神经网络

图神经网络 前面讲了图机器学习的一些传统方法&#xff0c;现在正式进入到课程的核心部分&#xff1a;图神经网络。 Design of GNN 那么图神经网络和我们之前接触的一些深度神经网络有什么不同呢&#xff1f; 对于别的类型的神经网络&#xff0c;往往我们都是处理一些类似网…

win环境nginx下载安装和基本操作使用解析

win环境nginx下载安装和基本操作是我们技术人员必备的技能&#xff0c;今天我们大概梳理一下&#xff1a; 下载 地址&#xff1a;nginx: download 进入后点击&#xff1a; 选择某个版本&#xff0c;就可以下载了&#xff0c;然后解压到某个目录&#xff0c;进入配置文件&…

RAM IP Core

官方文档&#xff1a;ZYNQ 存储资源指导手册 (DS109) RAM 全称 Random Access Memory&#xff0c;随机存取存储器。 随时将数据写入任意指定地址的存储单元&#xff0c;或从任意地址读出数据。读写的速度是由时钟频率决定的。 RAM主要用于存放程序运行的中间数据、运算结果等…

MySQL实战45讲深入浅出索引下

select * from T where k between 3 and 5这个语句的执行流程是&#xff1a; 在 k 索引树上找到 k3 的记录&#xff0c;取得 ID 300&#xff1b;再到 ID 索引树查到 ID300 对应的 R3&#xff1b;在 k 索引树取下一个值 k5&#xff0c;取得 ID500.再回到 ID 索引树查到 ID500 …

深度学习-第T1周——实现mnist手写数字识别

深度学习-第T1周——实现mnist手写数字识别深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片5、调整图片格式四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预…

【Python】Jupyter .ipynb

Jupyter启动Hello JupyterMarkdown纵然 Anaconda Pycharm 非常好用&#xff0c;但是既然学到 Jupyter&#xff0c;那就多掌握一份技能&#xff0c;毕竟 Jupyter 的确有他的优势在。 我认为 Jupyter 对于 Python 初学者来说&#xff0c;非常友善&#xff0c;他将一整个代码划分…

c#学习笔记

目录1.语句块2.Write和WriteLine的区别&#xff1a;3.params4.托管代码和非托管代码5.DllImport的使用&#xff1a;6.WriteLine、ReadLine和ReadKey&#xff1a;7.C#中访问修饰符8.类型的实例化9.成员可以分为两种&#xff1a;数据成员和函数成员10.枚举enum和结构struct的区别…