Spring+SprinMVC+MyBatis注解方式简易模板

Spring+SprinMVC+MyBatis注解方式简易模板代码Demo GitHub访问 ssm-tpl-anno

一、数据准备

创建数据库test,执行下方SQL创建表ssm-tpl-cfg

/*Navicat Premium Data TransferSource Server         : 127.0.0.1Source Server Type    : MySQLSource Server Version : 80030Source Host           : 127.0.0.1:3306Source Schema         : testTarget Server Type    : MySQLTarget Server Version : 80030File Encoding         : 65001Date: 17/10/2022 00:52:07
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for ssm-tpl-cfg
-- ----------------------------
DROP TABLE IF EXISTS `ssm-tpl-cfg`;
CREATE TABLE `ssm-tpl-cfg` (`id` bigint NOT NULL COMMENT '主键编号',`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '测试名称',PRIMARY KEY (`id`)
) COMMENT '初始SSM表结构数据' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;-- ----------------------------
-- Records of ssm-tpl-cfg
-- ----------------------------
BEGIN;
INSERT INTO `ssm-tpl-cfg` (`id`, `name`) VALUES (2210162246100000, '左翰林');
INSERT INTO `ssm-tpl-cfg` (`id`, `name`) VALUES (2210162257100000, '刘卓神');
COMMIT;SET FOREIGN_KEY_CHECKS = 1;

二、代码实现

2.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tpl.ssm.anno</groupId><artifactId>ssm-tpl-anno</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><properties><spring_version>5.1.18.RELEASE</spring_version><jackson_version>2.9.7</jackson_version></properties><dependencies><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><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</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-beans</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring_version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring_version}</version></dependency><dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version><scope>compile</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-annotation</artifactId><version>3.4.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.16</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.15.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.15.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.7</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.36</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.7.0</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.2</version></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><dependency><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId><version>1.6</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.7</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency><dependency><groupId>com.google.code.findbugs</groupId><artifactId>annotations</artifactId><version>2.0.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.25</version></dependency></dependencies>
</project>

2.2 Spring和Mybatis配置

package com.tpl.ssm.anno.config;import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/** Spring配置类** <!-- 扫描service -->* <context:component-scan base-package="com.tpl.ssm.cfg.service"/>*/
@ComponentScan(basePackages = {"com.tpl.ssm.anno.service"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = org.springframework.stereotype.Controller.class)
})
@EnableTransactionManagement
@Configuration
public class SpringConfig {private static final Logger logger = LoggerFactory.getLogger(SpringConfig.class);/** <!-- 配置数据库连接池 -->* <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">*     <!-- 四大连接参数 -->*     <property name="driverClassName" value="${jdbc.driverClassName}"/>*     <property name="url" value="${jdbc.url}"/>*     <property name="username" value="${jdbc.username}"/>*     <property name="password" value="${jdbc.password}"/>*     <!-- 连接池配置信息 -->*     <property name="initialSize" value="${jdbc.initialSize}"/>*     <property name="minIdle" value="${jdbc.minIdle}"/>*     <property name="maxActive" value="${jdbc.maxActive}"/>*     <property name="maxWait" value="${jdbc.maxWait}"/>*     <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->*     <property name="timeBetweenEvictionRunsMillis" value="60000"/>*     <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->*     <property name="minEvictableIdleTimeMillis" value="300000" />*     <!-- Druid用来测试连接是否可用的SQL语句,默认值每种数据库都不相同-->*     <property name="validationQuery" value="SELECT 'x'" />*     <!-- 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除. -->*     <property name="testWhileIdle" value="true" />*     <!-- 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->*     <property name="testOnBorrow" value="false" />*     <!-- 指明是否在归还到池中前进行检验 -->*     <property name="testOnReturn" value="false" />*     <!-- 配置监控统计拦截的filters -->*     <property name="filters" value="wall,stat" />* </bean>*/@Bean(name = "dataSource")public DruidDataSource druidDataSource() {// 基本属性 url、user、passwordDruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setUrl("jdbc:mysql://localhost:3306/test");druidDataSource.setUsername("root");druidDataSource.setPassword("root");// 配置初始化大小、最小、最大druidDataSource.setInitialSize(10);druidDataSource.setMinIdle(10);druidDataSource.setMaxActive(50);// 配置获取连接等待超时的时间druidDataSource.setMaxWait(60000);// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒druidDataSource.setTimeBetweenEvictionRunsMillis(60000);// 配置一个连接在池中最小生存的时间,单位是毫秒druidDataSource.setMinEvictableIdleTimeMillis(300000);druidDataSource.setValidationQuery("SELECT 1");druidDataSource.setTestWhileIdle(true);druidDataSource.setTestOnBorrow(false);druidDataSource.setTestOnReturn(false);// 打开PSCache,并且指定每个连接上PSCache的大小// 如果用Oracle,则把poolPreparedStatements配置为true,// mysql可以配置为false。druidDataSource.setPoolPreparedStatements(true);druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);// 配置监控统计拦截的filterstry {druidDataSource.setFilters("wall,stat");} catch (SQLException e) {logger.error("配置监控统计拦截的filters error: ", e);}return druidDataSource;}/** <!-- 配置sessionFactory -->* <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">*     <!-- 注入数据源 -->*     <property name="dataSource" ref="dataSource"/>*     <!-- mapper文件位置 -->*     <property name="mapperLocations" value="classpath:mapper/*DAO.xml"/>*     <!-- mybatis核心配置文件位置 -->*     <property name="configLocation" value="classpath:config/mybatis-config.xml"/>* </bean>*/@Bean(name = "sqlSessionFactory")public SqlSessionFactoryBean sqlSessionFactoryBean() {SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();sqlSessionFactory.setMapperLocations(resolveMapperLocations());sqlSessionFactory.setDataSource(druidDataSource());/** <?xml version="1.0" encoding="UTF-8" ?>* <!DOCTYPE configuration*         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"*         "http://mybatis.org/dtd/mybatis-3-config.dtd">* <configuration>**     <!-- 配置信息 -->*     <settings>*         <!-- 映射下划线到驼峰命名 -->*         <setting name="mapUnderscoreToCamelCase" value="true"/>*         <!-- 配置开启二级缓存 -->*         <setting name="cacheEnabled" value="true"/>*         <!-- 开启控制台打印SQL -->*         <setting name="logImpl" value="STDOUT_LOGGING"/>*     </settings>**     <!-- 别名 -->*     <typeAliases>*         <package name="com.tpl.ssm.cfg.entity"/>*     </typeAliases>* </configuration>*/MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();mybatisConfiguration.setMapUnderscoreToCamelCase(true);mybatisConfiguration.setCacheEnabled(true);mybatisConfiguration.setLogImpl(StdOutImpl.class);mybatisConfiguration.getTypeAliasRegistry().registerAliases("com.tpl.ssm.anno.entity");sqlSessionFactory.setConfiguration(mybatisConfiguration);return sqlSessionFactory;}// https://wenku.baidu.com/view/1b9ade1640323968011ca300a6c30c225901f0c2.htmlpublic Resource[] resolveMapperLocations() {PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();List<String> mapperLocations = new ArrayList<>();mapperLocations.add("classpath:mapper/*DAO.xml");List<Resource> resources = new ArrayList<>();for (String mapperLocation : mapperLocations) {Resource[] mappers = new Resource[0];try {mappers = resolver.getResources(mapperLocation);} catch (IOException e) {e.printStackTrace();}resources.addAll(Arrays.asList(mappers));}return resources.toArray(new Resource[0]);}/** <!-- 配置扫描mapper生成代理对象 -->* <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">*     <property name="basePackage" value="com.tpl.ssm.cfg.dao"/>*     <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>* </bean>*/@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();mapperScannerConfigurer.setBasePackage("com.tpl.ssm.anno.dao");mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");return mapperScannerConfigurer;}/* 事务管理器配置* <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">*     <property name="dataSource" ref="dataSourceProxy"/>* </bean>*/@Bean(name = "transactionManager")public DataSourceTransactionManager transactionManager(DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}}

2.3 SpringMVC配置

package com.tpl.ssm.anno.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;/* 开启controller注解支持* 注意事项请参考:http://jinnianshilongnian.iteye.com/blog/1762632** <context:component-scan base-package="com.tpl.ssm.cfg.controller"/>*/
@ComponentScan(basePackages = {"com.tpl.ssm.anno.controller"
}, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = org.springframework.stereotype.Controller.class),@ComponentScan.Filter(type = FilterType.ANNOTATION, value = org.springframework.web.bind.annotation.ControllerAdvice.class)
}, useDefaultFilters = false)
@EnableWebMvc
@Configuration
// <import resource="spring-mvc-xxx.xml"/>
// @Import(value = {SpringMvcXxxConfig.class})
public class SpringMVCConfig implements WebMvcConfigurer {/* <!-- 配置SpringMVC视图解析器 -->* <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">*     <property name="prefix" value="/pages/"/>*     <property name="suffix" value=".jsp"/>* </bean>*/@Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);resolver.setPrefix("/pages/");resolver.setSuffix(".jsp");return resolver;}/* <!-- 释放静态资源文件 -->* <mvc:resources mapping="/js/" location="/js/**"/>* <mvc:resources mapping="/css/" location="/css/**"/>* <mvc:resources mapping="/images/" location="/images/**"/>*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/js/").addResourceLocations("/js/**");registry.addResourceHandler("/css/").addResourceLocations("/css/**");registry.addResourceHandler("/images/").addResourceLocations("/images/**");}// 文件解析器@Beanpublic CommonsMultipartResolver multipartResolver() {CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();// maxUploadSizePerFile:单个文件大小限制(byte)// maxUploadSize:整个请求大小限制(byte)commonsMultipartResolver.setMaxUploadSizePerFile(10 * 1024 * 1024); // 10McommonsMultipartResolver.setMaxUploadSize(100 * 1024 * 1024); // 100Mreturn commonsMultipartResolver;}}

2.4 web.xml配置

package com.tpl.ssm.anno.config;import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;/*** Web应用启动入口* <p/>* <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"* xmlns="http://xmlns.jcp.org/xml/ns/javaee"* xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee* http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">* </web-app>*/
public class WebInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {// 父容器配置AnnotationConfigWebApplicationContext springCtx = new AnnotationConfigWebApplicationContext();springCtx.setDisplayName("ssm-tpl-anno"); // 部署应用的名称 <display-name>ssm-tpl-anno</display-name>/** <!-- Spring配置文件开始  -->* <context-param>*     <param-name>contextConfigLocation</param-name>*     <param-value>*         classpath:spring-config.xml*     </param-value>* </context-param>* <listener>*     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>* </listener>* <!-- Spring配置文件结束 -->*/springCtx.register(SpringConfig.class);// 通过监听器加载配置信息servletContext.addListener(new ContextLoaderListener(springCtx));/* 可以使用RequestContextHolder.currentRequestAttributes() 获取到请求的attr* <listener>*     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>* </listener>*/servletContext.addListener(org.springframework.web.context.request.RequestContextListener.class);// 子容器配置AnnotationConfigWebApplicationContext mvcCtx = new AnnotationConfigWebApplicationContext();/** <!-- SpringMVC配置文件开始  -->* <servlet>*     <servlet-name>springMVC</servlet-name>*     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>*     <init-param>*         <param-name>contextConfigLocation</param-name>*         <param-value>classpath:spring-mvc.xml</param-value>*     </init-param>*     <load-on-startup>1</load-on-startup>*     <async-supported>true</async-supported>* </servlet>* <servlet-mapping>*     <servlet-name>springMVC</servlet-name>*     <url-pattern>/</url-pattern>* </servlet-mapping>* <!-- SpringMVC配置文件结束  -->*/mvcCtx.register(SpringMVCConfig.class);ServletRegistration.Dynamic servlet = servletContext.addServlet("DispatcherServlet",new DispatcherServlet(mvcCtx));servlet.setLoadOnStartup(1);servlet.setAsyncSupported(true);servlet.addMapping("/");/** <!-- 设置servlet编码开始 -->* <filter>*     <filter-name>CharacterEncodingFilter</filter-name>*     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>*     <async-supported>true</async-supported>*     <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>* <!-- 设置servlet编码结束 -->*/FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("CharacterEncodingFilter",new CharacterEncodingFilter("UTF-8", true));encodingFilter.setAsyncSupported(true);encodingFilter.addMappingForUrlPatterns(null, false, "/*");}
}

2.5 Entity

package com.tpl.ssm.anno.entity;import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;import java.util.LinkedHashMap;
import java.util.Map;/*** 测试实体*/
public class TestEntity {/*** 主键编号*/private Long id;/*** 测试名称*/private String name;private JSONObject flowImg;private String flowImgStr;/*** 扩展字段*/@JsonIgnore@TableField(exist = false)private Map<String, Object> ext = new LinkedHashMap<>(5);public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Map<String, Object> getExt() {return ext;}public void setExt(Map<String, Object> ext) {this.ext = ext;}public JSONObject getFlowImg() {return flowImg;}public void setFlowImg(JSONObject flowImg) {this.flowImg = flowImg;}public String getFlowImgStr() {return flowImgStr;}public void setFlowImgStr(String flowImgStr) {this.flowImgStr = flowImgStr;}
}

2.6 Controller

package com.tpl.ssm.anno.controller;import com.tpl.ssm.anno.entity.TestEntity;
import com.tpl.ssm.anno.service.TestService;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;/*** 1. Spring5.1.x -> jackson2.9.x* 2.The origin server did not find a current representation for the target resource* 原因是WEB-INF只能转发进去, 重定向是进不去的*/
@Controller
@RequestMapping("/test")
public class TestController {private final TestService testService;public TestController(TestService testService) {this.testService = testService;}@GetMapping("/")public String listTests(TestEntity test, Model model) {List<TestEntity> tests = testService.listTests(test);model.addAttribute("tests", tests);return "test";}@PostMapping("/save")public String saveTest(@RequestBody TestEntity test) {testService.saveTest(test);return "redirect:/test/";}@PostMapping("/modify")public String modifyTest(TestEntity test) {testService.modifyTest(test);return "redirect:/test/";}@RequestMapping("/remove")public String removeTest(TestEntity test) {testService.removeTest(test);return "redirect:/test/";}}

2.7 Service

package com.tpl.ssm.anno.service;import com.tpl.ssm.anno.entity.TestEntity;import java.util.List;public interface TestService {/*** 测试集** @param cond 查询条件* @return 测试集*/public List<TestEntity> listTests(TestEntity cond);/*** 单一测试实体** @param cond 查询条件* @return 测试实体*/public TestEntity singleTest(TestEntity cond);/*** 新增测试记录** @param cond 查询条件* @return 受影响的条数*/public boolean saveTest(TestEntity cond);/*** @param cond 查询条件* @return 受影响的条数*/public boolean modifyTest(TestEntity cond);/*** 删除一条测试记录** @param cond 查询条件* @return 受影响的条数*/public boolean removeTest(TestEntity cond);/*** 删除多条测试记录** @param testIds 测试实体主键集* @return 受影响的条数*/public boolean removeTests(List<Long> testIds);}
package com.tpl.ssm.anno.service.impl;import com.tpl.ssm.anno.dao.TestDAO;
import com.tpl.ssm.anno.entity.TestEntity;
import com.tpl.ssm.anno.service.TestService;
import com.tpl.ssm.anno.util.MajorKeyUtil;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class TestServiceImpl implements TestService {private final TestDAO testDAO;public TestServiceImpl(TestDAO testDAO) {this.testDAO = testDAO;}@Overridepublic List<TestEntity> listTests(TestEntity cond) {return testDAO.listTests(cond);}@Overridepublic TestEntity singleTest(TestEntity cond) {return testDAO.singleTest(cond);}@Overridepublic boolean saveTest(TestEntity cond) {cond.setId(MajorKeyUtil.idSeq());cond.setFlowImgStr(cond.getFlowImg().toString());return testDAO.insertTest(cond) > 0;}@Overridepublic boolean modifyTest(TestEntity cond) {return testDAO.updateTest(cond) > 0;}@Overridepublic boolean removeTest(TestEntity cond) {return testDAO.deleteTest(cond) > 0;}@Overridepublic boolean removeTests(List<Long> testIds) {return testDAO.deleteTests(testIds) > 0;}
}

2.8 DAO

package com.tpl.ssm.anno.dao;import com.tpl.ssm.anno.entity.TestEntity;import java.util.List;/*** 测试DAO* <p>* 1.查询测试记录列表 - listTests* 2.查询单个测试记录 - singleTest* 3.新增测试记录 - insertTest* 4.修改测试记录 - updateTest* 5.删除测试记录 - deleteTest* 6.根据主键集删除测试记录 - deleteTests*/
public interface TestDAO {/*** 测试集** @param cond 查询条件* @return 测试集*/public List<TestEntity> listTests(TestEntity cond);/*** 单一测试实体** @param cond 查询条件* @return 测试实体*/public TestEntity singleTest(TestEntity cond);/*** 新增测试记录** @param cond 查询条件* @return 受影响的条数*/public int insertTest(TestEntity cond);/*** @param cond 查询条件* @return 受影响的条数*/public int updateTest(TestEntity cond);/*** 删除一条测试记录** @param cond 查询条件* @return 受影响的条数*/public int deleteTest(TestEntity cond);/*** 删除多条测试记录** @param testIds 测试实体主键集* @return 受影响的条数*/public int deleteTests(List<Long> testIds);}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tpl.ssm.anno.dao.TestDAO"><!-- 基础查询 sql 片段 --><sql id="baseSelect">SELECT id, name</sql><!-- 基础查询 where 片段 --><sql id="baseWhere"><if test="id != null">AND id = #{id}</if><if test="name != null and name != ''">AND name like CONCAT('%', #{name})</if></sql><!-- 查询测试记录列表 --><select id="listTests" parameterType="com.tpl.ssm.anno.entity.TestEntity" resultType="com.tpl.ssm.anno.entity.TestEntity"><include refid="baseSelect"/>FROM `ssm-tpl-cfg`WHERE1 = 1<include refid="baseWhere"/></select><!-- 查询单个测试记录 --><select id="singleTest" parameterType="com.tpl.ssm.anno.entity.TestEntity" resultType="com.tpl.ssm.anno.entity.TestEntity"><include refid="baseSelect"/>FROM `ssm-tpl-cfg`WHERE1 = 1<include refid="baseWhere"/>limit 1</select><!-- 新增测试记录 --><insert id="insertTest" parameterType="com.tpl.ssm.anno.entity.TestEntity">INSERT INTO `ssm-tpl-cfg`(id, name, flow_img)VALUES (#{id}, #{name}, #{flowImgStr})</insert><!-- 修改测试记录 --><update id="updateTest" parameterType="com.tpl.ssm.anno.entity.TestEntity">UPDATE `ssm-tpl-cfg`SET<if test="name != null and name != ''">name = #{name}</if>WHERE id = #{id}</update><!-- 删除测试记录 --><delete id="deleteTest" parameterType="com.tpl.ssm.anno.entity.TestEntity">DELETEFROM `ssm-tpl-cfg`WHERE 1 = 1<include refid="baseWhere"/></delete><!-- 根据主键集删除测试记录 --><delete id="deleteTests" parameterType="long">DELETEFROM `ssm-tpl-cfg`WHERE id in<foreach collection="item" open="(" separator="," close=")">#{item}</foreach></delete>
</mapper>

2.9 webapps/pages/test.jsp

<%--Created by IntelliJ IDEA.User: wangfeihuDate: 2022/10/16Time: 18:35To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>CRUD TEST</title>
</head>
<body>
<table><c:forEach items="${tests}" var="test"><tr><td>${test.id}</td><td>${test.name}</td><td><button onclick="let modifyForms = document.getElementsByName('modifyForm'); modifyForms.forEach(item => item.style.display = 'none'); document.getElementById('form${test.id}').style.display = 'inline'">修改</button><button onclick="location.href='${pageContext.request.contextPath}/test/remove?id=${test.id}'">删除</button></td><td><form id="form${test.id}" name="modifyForm" action="${pageContext.request.contextPath}/test/modify" method="post" style="display: none"><input hidden name="id" value="${test.id}"><input name="name" value="${test.name}"><button type="submit">确认修改</button></form></td></tr></c:forEach>
</table><form action="${pageContext.request.contextPath}/test/save" method="post"><label><input name="name" id="name" placeholder="请输入测试名称~"></label><button type="submit">提交</button>
</form>
</body>
</html>

2.10 配置项目访问路径

配置项目访问路径

三、访问测试

访问测试

一个简单的基于注解的增删改查就实现了

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

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

相关文章

【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

针对Java对象压缩及序列化技术的探索之路 序列化和反序列化为何需要有序列化呢&#xff1f;Java实现序列化的方式二进制格式 指定语言层级二进制格式 跨语言层级JSON 格式化类JSON格式化&#xff1a;XML文件格式化 序列化的分类在速度的对比上一般有如下规律&#xff1a;Java…

选择排序(二)——堆排序(性能)与直接选择排序

目录 一.前言 二.选择排序 2.1 堆排序 2.2选择排序 2.2.1 基本思想 2.2.2直接选择排序 三.结语 一.前言 本文给大家带来的是选择排序&#xff0c;其中选择排序中的堆排序在之前我们已经有过详解所以本次主要是对比排序性能&#xff0c;感兴趣的友友可移步观看堆排&#…

世微AP5179 60V高端电流采样降压恒流驱动器 LED车灯备用灯信号灯

产品描述 AP5179是一款连续电感电流导通模式的降压恒流源&#xff0c;用于驱动一颗或多颗串联LED输入电压范围从 5 V 到 60V&#xff0c;输出电流 可达 2.0A 。根据不同的输入电压和 外部器件&#xff0c; 可以驱动高达数十瓦的 LED。 内置功率开关&#xff0c;采用高端电流采样…

python实现带刷新的文本进度条

进度条已执行的部分使用“**”&#xff0c;未执行的部分使用“--”&#xff0c;用print&#xff08;&#xff09;来完成 使用到的函数&#xff1a; time.sleep(),作用是在程序执行过程中暂停一段时间&#xff0c;即会使程序暂停指定的秒数&#xff0c;然后再继续执行后面的代…

【Unity学习笔记】Unity TestRunner使用

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/135733479 作者&#xff1a;CSDN|Ringleader| 参考&#xff1a; Input testingGetting started with Unity Test FrameworkHowToRunUnityUnitTest如果对Unity的newInputSystem感…

HTML JavaScript 数字变化特效

效果 案例一&#xff1a;上下滚动 案例二&#xff1a;本身变化 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><met…

初识 JVM

什么是JVM JVM 全称是 J ava V irtual M achine&#xff0c;中文译名 Java虚拟机 。 JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行 Java字节码文件 。 JVM的功能 Java语言如果不做任何优化&#xff0c;性能不如C、C等语言。 Java需要实时解释&…

【主题广范|见刊快】2024年生物信息学与智能系统国际学术会议(IACBIS 2024)

【主题广范|见刊快】2024年生物信息学与智能系统国际学术会议(IACBIS 2024) 2024 International Conference Bioinformatics and Intelligent Systems(IACBIS 2024) 一、【会议简介】 在2024年&#xff0c;一场全球瞩目的学术盛会将在某个繁华的都市中心举行。这次会议的主题是…

Android学习之路(22) ARouter原理解析

1.ARouter认知 首先我们从命名来看:ARouter翻译过来就是一个路由器。 官方定义&#xff1a; 一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦 那么什么是路由呢&#xff1f; 简单理解就是&#xff1a;一个公共平台转发系统 工作方式&…

软件系统测试方案-word

2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.1. 硬件环境 4.2.2. 软件环境 4.3. 进度安排 5. 功能测试 6. 性能测试 7. 安全性与访问控…

[Unity] Tilemap瓦片左右翻转(上下翻转)

Tile&#xff08;瓦片&#xff09;左右翻转感觉是很常用的一个功能啊&#xff01;看了一些教程都没有提及&#xff0c;心想难道要把每张Sprite再做一张对称的、再做成瓦片吗&#xff1f; 图片量x2 、瓦片量x2、不现实&#xff01;一定有方法&#xff01; 搜索了了半天没找到方…

架构篇04:复杂度来源 - 高性能

文章目录 单机复杂度集群的复杂度小结 从本篇开始&#xff0c;我们一起深入分析架构设计复杂度的 6 个来源&#xff0c;先来聊聊复杂度的来源之一高性能。 对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机&#xff0c;从电子管计算机到晶体管计算机再到集…

springsecurity集成kaptcha功能

前端代码 本次采用简单的html静态页面作为演示&#xff0c;也可结合vue前后端分离开发&#xff0c;复制就可运行测试 项目目录 登录界面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</…

【设计模式-9】装饰模式的代码实现及使用场景

装饰器模式类比生活中房屋装修的场景&#xff0c;可以在毛坯房的基础上加以各种装饰&#xff0c;使得房屋的居住属性增强。装饰器模式能够在运行期间&#xff0c;动态地为原始对象增加一些额外的功能&#xff0c;使其功能更为丰富。 1. 概述 装饰模式 可以动态的为某些对象增…

深入Matplotlib:画布分区与高级图形展示【第33篇—python:Matplotlib】

文章目录 Matplotlib画布分区技术详解引言方法一&#xff1a;plt.subplot()方法二&#xff1a;简略写法方法三&#xff1a;plt.subplots()实例展示添加更多元素 进一步探索Matplotlib画布分区自定义子图布局3D子图结语 Matplotlib画布分区技术详解 引言 Matplotlib是一个强大…

代码随想录27期|Python|Day35|435. 无重叠区间|763.划分字母区间|56. 合并区间

435. 无重叠区间 和昨天的射爆气球是一样的处理方式&#xff1a; 由于不需要进行不重合的时候的计算&#xff0c;只需要对重合进行处理&#xff0c;所以反而更加简单。 1、按照区间左边界从小到大排序&#xff1b; 2、从索引1开始遍历&#xff0c;对于i-1的右边界大于i的左边…

网页无法访问但是有网什么原因

目录 1.运行网络诊断&#xff0c;确认原因 原因A.远程计算机或设备将不接受连接(该设备或资源(Web 代理)未设置为接受端口“7890”上的连接 原因B.DNS服务器未响应 场景A.其他的浏览器可以打开网页&#xff0c;自带的Edge却不行 方法A&#xff1a;关闭代理 Google自带翻译…

用户头像上传

将用户上传的头像存储在腾讯云存储桶里 注册腾讯云 https://cloud.tencent.com/login 创建存储桶 配置跨域 来源 * (任何都可以访问) put get post 请求都可以 点击概览&#xff0c;查看存储桶基本信息 记录保存存储桶名称和地域 找到api密钥管理&#xff0c;新建密钥 ht…

Git学习笔记(第7章):IDEA实现Git操作(VSCode)

目录 7.1 配置忽略文件 7.2 初始化本地库 7.3 添加暂存区、提交本地库 7.4 修改文件 补充&#xff1a;工具栏简介 7.1 配置忽略文件 问题引入 在版本控制系统中&#xff0c;有些文件或目录是不需要纳入版本管理的&#xff0c;比如编译产生的临时文件、日志文件、缓存文件等…

项目篇:基于UDP通信模型的网络聊天室

思维导图 基于UDP通信模型的网络聊天室 消息分类及数据包结构 服务器端 #include <head.h> #define SER_PORT 8888 #define SER_IP "192.168.232.133" typedef struct mb {struct sockaddr_in cin;char name[20];struct mb *next; }*member; //群发消息 int …