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.hqwc.cn/news/419022.html

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

相关文章

2008年苏州大学837复试机试C语言

2008年苏州大学复试机试C 题目 编写程序充成以下功能: 一、从键盘上输入随机变量x的 10个取样点。X0&#xff0c;X1—X9 的值; 1、计算样本平均值 2、判定x是否为等差数列 3、用以下公式计算z的值(t0.63) 注。请对程序中必要地方进行注释 补充&#xff1a;个人觉得这个题目回…

canvas绘制正三边形,正四边形,正五边形...正N边形

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

使 a === 1 a === 2 a === 3 为 true 的几种“下毒“方法

前言 这算得上是近些年的前端网红题了&#xff0c;曾经对这种网红题非常抵触&#xff0c;认为非常没有意义。 看到了不少人有做分享&#xff0c;有各种各样的方案&#xff0c;有涉及到 JS 非常基础的知识点&#xff0c;也不得不感叹解题者的脑洞之大。 但是&#xff0c;拿来…

代码随想录二刷 | 二叉树 | 修剪二叉搜索树

代码随想录二刷 | 二叉树 | 修剪二叉搜索树 题目描述解题思路代码实现 题目描述 669.修剪二叉搜索树 给定一个二叉搜索树&#xff0c;同时给定最小边界 L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&…

立体视觉几何(一)

1.什么是立体视觉几何 立体视觉对应重建&#xff1a; • 对应&#xff1a;给定一幅图像中的点pl&#xff0c;找到另一幅图像中的对应点pr。 • 重建&#xff1a;给定对应关系(pl, pr)&#xff0c;计算空间中相应点的3D 坐标P。 立体视觉&#xff1a;从图像中的投影恢复场景中点…

一台手机用4年多,国产手机从态度傲慢到跪求消费者换机

分析机构trendforce公布的数据指出&#xff0c;中国消费者的换机周期已延长到51个月&#xff0c;面对消费者对国产手机用脚投票&#xff0c;如今国产手机企业开始采取多方举措&#xff0c;祈求消费者买手机&#xff0c;市场的变化促使国产手机不得不改变态度。 2010年国产手机刚…

VM使用教程--SDK取图 视频笔记

本笔记均由海康机器人官网的V学院视频中记录所得&#xff0c;属于省流大师了[doge] 图像采集 图像采集包括1图像源&#xff0c;2多图采集&#xff0c;3输出图像&#xff0c;4缓存图像&#xff0c;5光源 1图像源 图像源包括本地图像&#xff0c;相机采图&#xff0c;SDK 本…

二维旋转公式推导+旋转椭圆的公式推导

二维旋转公式推导+旋转椭圆的公式推导 二维旋转公式推导旋转椭圆的公式推导二维旋转公式推导 x , y x,y x,y表示二维坐标系中原坐标点, x ′ , y ′ x,y x′,y′表示逆时针旋转 β \beta β之后的坐标点: x ′ = x cos ⁡ ( β ) − y sin ⁡ ( β ) y ′ = y cos ⁡ ( β )…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于混合博弈的配电网与多综合能源微网优化运行》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及到配电网和多综合能源微网的优化运行&#xff0c;而优化的方法基于混合博弈理论。让我们逐步解读这个标题的关键部分&#xff1a; 基于混合…

QT+opencv源码编译

时间记录&#xff1a;2024/1/20 一、版本介绍 QT5.12.7cmake3.22.0opencv4.5.4 二、编译步骤 &#xff08;1&#xff09;下载opencv源码&#xff0c;然后安装&#xff0c;opencv的安装即对源码的解压过程&#xff0c;解压后的文件目录如下 &#xff08;2&#xff09;openc…

【C++】vector容器接口要点的补充

接口缩容 在VS编译器的模式下&#xff0c;类似于erase和insert接口的函数通常会进行缩容&#xff0c;因此&#xff0c;insert和erase行参中的迭代器可能会失效。下图中以erase为例&#xff1a; 代码如下&#xff1a; #include <iostream> #include <vector> #inclu…

Leetcode2829. k-avoiding 数组的最小总和

Every day a Leetcode 题目来源&#xff1a;2829. k-avoiding 数组的最小总和 解法1&#xff1a;贪心 哈希 从 1 开始枚举数 x&#xff0c;如果 k - x 不在哈希表里&#xff0c;说明可以插入 k-avoiding 数组&#xff0c;sum 加上 x&#xff0c;向哈希表插入 x。 当哈希表…