原生SSM整合(Spring+SpringMVC+MyBatis)案例

SSM框架是Spring、Spring MVC和MyBatis三个开源框架的整合,常用于构建数据源较简单的web项目。该框架是Java EE企业级开发的主流技术,也是每一个java开发者必备的技能。下面通过查询书籍列表的案例演示SSM整合的过程.

新建项目

创建文件目录

完整文件结构

引入依赖 

  <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!--spring和springMVC环境依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.18.RELEASE</version>
        </dependency>
        <!--servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--spring事务管理依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.18.RELEASE</version>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!--spring整合mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!--spring整合数据源依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <!--mysql数据库连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!--spring整合Junit依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.18.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <!--日志支持-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>

创建数据库表

jdbc属性文件

在resources目录下的props包中创建jdbc.properties文件

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=mysqlpass

创建配置类

jdbcConfig

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
@Configuration
//加载资源路径
@PropertySource("classpath:props/jdbc.properties")
public class JdbcConfig {
    @Value("${jdbc.driverClass}")
    private String driverClass;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${jdbc.url}")
    private String url;
    
    /**配置Druid数据源*/
    /**@Bean将返回的dataSource标识为被Spring管理的bean对象*/
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        return dataSource;
    }
}

MyBatisConfig

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
@Import(JdbcConfig.class)
public class MyBatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        //加载全局配置文件
       Resource configResource = new ClassPathResource("mybatis/mybatis-config.xml");
       sessionFactoryBean.setConfigLocation(configResource);
       //映射文件加载
        ResourcePatternResolver resourceResolver= new PathMatchingResourcePatternResolver();
        sessionFactoryBean.setMapperLocations(resourceResolver.getResources("classpath*:mybatis/mapper/*Mapper.xml"));
        return sessionFactoryBean;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
        //扫描mapper接口所在的包
        scannerConfigurer.setBasePackage("com.yaorange.ssm.mapper");
        return scannerConfigurer;
    }
}

SpringConfig



import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
//扫描业务类实现类所在的包
@ComponentScan("com.yaorange.ssm.service.impl")
//加载MyBatisConfig和JdbcConfig配置类的字节码文件
@Import({MyBatisConfig.class, JdbcConfig.class})
//开启事务管理器
@EnableTransactionManagement
public class SpringConfig {
    @Bean
    /**配置事务管理器*/
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

SpringMvcConfig

@Configuration
//扫描controller所在的包
@ComponentScan("com.yaorange.ssm.controller")
@EnableWebMvc
public class SpringMvcConfig {
}

ServletConfig配置类(用于加载Spring和SpringMVC配置类)


import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    /**加载Spring配置,创建Spring容器*/
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SpringConfig.class};
    }

    @Override
    /**加载SpringMVC配置,创建SpringMVC容器*/
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        //所有请求都交给SpringMVC处理
        return new String[] {"/"};
    }
}

功能模块开发

数据层开发

Book实体类
@Data
public class Books implements Serializable {
    /**
     * 书籍编号
     */
    private Integer bId;

    /**
     * 书籍名称
     */
    private String bName;

    /**
     * 作者
     */
    private String authers;

    /**
     * 价格
     */
    private BigDecimal price;

    /**
     * 出版年份
     */
    private Object pubdate;

    /**
     * 备注
     */
    private String note;

    /**
     * 数量
     */
    private Integer num;

   
}
mapper层BookMapper接口
public interface BooksMapper {  
    /**查询所有书籍*/
    List<Books> selectAll();
}

BookMapper.xml

<?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.yaorange.ssm.mapper.BooksMapper">

    <resultMap id="BaseResultMap" type="com.yaorange.ssm.entity.Books">
            <id property="bId" column="b_id" jdbcType="INTEGER"/>
            <result property="bName" column="b_name" jdbcType="VARCHAR"/>
            <result property="authers" column="authers" jdbcType="VARCHAR"/>
            <result property="price" column="Price" jdbcType="DECIMAL"/>
            <result property="pubdate" column="pubdate" jdbcType="OTHER"/>
            <result property="note" column="note" jdbcType="VARCHAR"/>
            <result property="num" column="num" jdbcType="INTEGER"/>
    </resultMap>

    <sql id="Base_Column_List">
        b_id,b_name,authers,
        Price,pubdate,note,
        num
    </sql>


    <select id="selectAll" resultMap="BaseResultMap">
        SELECT
           <include refid="Base_Column_List"/>
        FROM
            books
    </select>

</mapper>

业务层开发

BookService接口
public interface BookService {
    List<Books> selectAll();
}
BookServiceImpl实现类
@Service
//开启事务管理
@Transactional(rollbackFor = Exception.class)
public class BookServiceImpl implements BookService {
    @Autowired
    private BooksMapper booksMapper;

    @Override
    public List<Books> selectAll() {
        return booksMapper.selectAll();
    }
}

控制层开发

@Controller
@ResponseBody
//根路径
@RequestMapping("/book")
public class BookController {
    @Autowired
    private BookService bookService;
    @RequestMapping("/list")
    public Result selectAll(){
        List<Books> books = bookService.selectAll();
        return Result.ok(books);
    }
}

common包中的响应结果类和响应码常量

修改Tomcat中的访问路径

将多余的删除后点击apply


/**定义响应结果类*/
@Data
public class Result {
    //响应码
    private int code;
    //响应信息
    private String msg;
    //响应数据
    private Object data;

    public Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Result(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Result(String msg, Object data) {
        this.msg = msg;
        this.data = data;
    }

    public Result(Object data) {
        this.data = data;
    }

    public static Result success (){
        return new Result(HttpCode.SUCCESS_CODE,HttpMsg.SYS_OK_MSG);
    }
    public static Result ok(Object data){
        return new Result(data);
    }
    public static Result ok(String msg,Object data){
        return new Result(msg, data);
    }
}
public interface HttpCode {
    //成功响应码
    int SUCCESS_CODE=200;
    //失败响应码
    int ERROR_CODE=500;
}
public class HttpMsg {
    public static final String SYS_ERROR_MSG="操作失败";
    public static final String SYS_OK_MSG="操作成功";
}

postman接口测试结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CRM系统的销售漏斗是什么?如何提升销售效率?

​ CRM管理系统有许多重要的功能&#xff0c;很多人不太了解什么叫销售漏斗。网上关于CRM销售漏斗的讲解。看完以后仿佛懂了&#xff0c;细心想了想&#xff0c;好像没说透。下面说说CRM销售漏斗如何指导销售人员行动。简单来说就是分解销售目标、规划销售时间、预测销售业绩。…

【时间复杂度】时间复杂度优化法则简讲

一、引言 时间复杂度是衡量算法运行效率的一项重要指标&#xff0c;它描述了随着输入规模的增加&#xff0c;算法的执行时间如何增长。在算法设计与分析中&#xff0c;我们经常面临着优化时间复杂度的任务&#xff0c;以便提高程序的性能。本博客将深入探讨时间复杂度的优化法…

【MYSQL】事务隔离级别

脏读、幻读、不可重复读 脏读 一个事务正在对一条记录做修改&#xff0c;在这个事务完成并提交前&#xff0c;另一个事务也来读取同一条记录&#xff0c;读取了这些未提交的“脏”数据&#xff0c;并据此做进一步的处理&#xff0c;就会产生未提交的数据依赖关系。这种现象被形…

删除edge浏览器文本框储存记录值以及关闭自动填充

当我们点击输入框时总会出现许多以前输入过的信息。 一、删除edge浏览器文本框储存记录值 1、首先按下↓键选中你想删除的信息 2、然后按ShiftfnDel鍵(MAC)/ShiftDel鍵(Win)&#xff0c;就可以成功删除。 二、关闭自动填充。 1、在地址栏输入edge://wallet/settings跳转到以…

语言大模型的分布式训练与高效微调指南

原文&#xff1a;语言大模型的分布式训练与高效微调指南 - 知乎 目录 收起 1 分布式训练 2 ZeRO驱动的数据并行 3 全分片数据并行 4 实现 5 高效微调 6 实践指南 7 关于DeepSpeed和FSDP的更多内容 OneFlow编译 翻译&#xff5c;杨婷、宛子琳 最近语言大模型&#xff…

[windows]给WSL安装一个桌面gnome版本

【安装前提】 请提前安装好WSL系统&#xff0c;最好ubuntu系统>18.04 【安装步骤】&#xff1a; WSL 不支持 systemd 而 Gnome 桌面又是基于 systemd&#xff0c;所以先解决这个问题。 sudo apt update sudo apt install git git clone https://github.com/DamionGans/u…

redis数据安全(五)事务

一、概念&#xff1a; 1、介绍&#xff1a;Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令&#xff0c;一个事务中所有命令都会被序列化。在事务执行过程&#xff0c;会按照顺序串行化执行队列中的命令&#xff0c;其他客户端提交的命令请求不会插入到事务执行命…

尚无忧【无人共享空间 saas 系统源码】无人共享棋牌室系统源码共享自习室系统源码,共享茶室系统源码

可saas多开&#xff0c;非常方便&#xff0c;大大降低了上线成本 UNIAPPthinkphpmysql 独立开源&#xff01; 1、定位功能&#xff1a;可定位附近是否有店 2、能通过关键字搜索现有的店铺 3、个性轮播图展示&#xff0c;系统公告消息提醒 4、个性化功能展示&#xff0c;智能…

【JavaEE进阶】 图书管理系统开发日记——壹

文章目录 &#x1f332;序言&#x1f334;前端代码的引入&#x1f38b;约定前后端交互接口&#x1f343;后端服务器代码实现&#x1f6a9;UserController.java&#x1f6a9;BookController.java ⭕总结 &#x1f332;序言 该图书管理系统&#xff0c;博主将一步一步进行实现。…

秒懂Precision精确率、Recall召回率-附代码和案例

经常有同学目标检测评价指标含糊不清这次带你通俗易懂了解该知识 强烈推荐的博客&#xff1a; 更多有用知识&#xff0c;请点我 //☏:qq1309399183// 深度学习视觉必做项目 计算 precision&#xff08;精确率&#xff09;**和 recall&#xff08;召回率&#xff09;是评估分类…

Linux设备驱动开发学习笔记(等待队列,锁,字符驱动程序,设备树,i2C...)

1. 内核工具和辅助函数 1.1宏container_of container_of函数可以通过结构体的成员变量检索出整个结构体 函数原型&#xff1a; /* pointer 指向结构体字段的指针 container_type 结构体类型 container_field 结构体字段名称 返回值是一个指针 */ container_of(pointer, con…

智慧水务平台有哪些应用场景?

随着城市化进程的加速&#xff0c;城市水资源管理面临着越来越多的挑战。如何实现高效、智能的水资源管理&#xff0c;成为了城市管理者亟待解决的问题。智慧水务平台作为新一代信息技术在水务领域的深度应用&#xff0c;为城市水资源管理提供了全新的解决方案。 智慧水务平台的…

Tensorflow2.0笔记 - 基础数学运算

本笔记主要记录基于元素操作的,-,*,/,//,%,**,log,exp等运算&#xff0c;矩阵乘法运算&#xff0c;多维tensor乘法相关运算 import tensorflow as tf import numpy as nptf.__version__#element-wise运算&#xff0c;对应元素的,-,*,/,**,//,% tensor1 tf.fill([3,3], 4) ten…

动手学深度学习5 矩阵计算

矩阵计算--矩阵怎么求导数 1. 导数和微分2. 偏导数3. 梯度1. 向量-标量求导2. 向量-向量求导3. 拓展到矩阵 4. 链式法则5. 小结QA练习 课程安排&#xff1a; 视频&#xff1a;https://www.bilibili.com/video/BV1eZ4y1w7PY/?spm_id_fromautoNext&vd_sourceeb04c9a33e87ce…

如何选择第三方电子合同平台?

说起第三方电子合同平台大家可能有点不了解&#xff0c;陕西CA来给大家解释解释&#xff1a;第三方电子合同平台是一种提供电子合同服务的第三方机构&#xff0c;可以提供电子合同的签署、管理、存储、公证等服务&#xff0c;保障电子合同的有效性和合法性。 第三方电子合同平台…

vue 里 props 类型为 Object 时设置 default: () => {} 返回的是 undefined 而不是 {}?

问题 今天遇到个小坑&#xff0c;就是 vue 里使用 props 传参类型为 Object 的时候设置 default: () > {} 报错&#xff0c;具体代码如下 <template><div class"pre-archive-info"><template v-if"infoData.kaimo ! null">{{ infoD…

如何使用Docker本地部署Wiki.js容器并结合内网穿透实现知识库共享

文章目录 1. 安装Docker2. 获取Wiki.js镜像3. 本地服务器打开Wiki.js并添加知识库内容4. 实现公网访问Wiki.js5. 固定Wiki.js公网地址 不管是在企业中还是在自己的个人知识整理上&#xff0c;我们都需要通过某种方式来有条理的组织相应的知识架构&#xff0c;那么一个好的知识整…

用冒泡排序谈默认参数应用

前面在调用函数提到为了将信息打印到ofil中&#xff0c;前面提到的办法是 ofstream ofil("text_out1"); void bubble_sort(vector<int> vec){ } 在file scope中定义ofil&#xff0c;这是一个不受欢迎的举动。这样比较难在其他环境重用 一般的程序编写法则是&…

组态王软件安装教程6.51/6.53/5.55/6.60/7.5SP2版本组态软件

组态王软件是一款功能强大的工业自动化软件&#xff0c;以下是各个版本的主要特点&#xff1a; 组态王6.51&#xff1a;该版本是亚控科技在组态王6.0x系列版本成功应用后&#xff0c;广泛征询数千家用户的需求和使用经验&#xff0c;采取先进软件开发模式和流程&#xff0c;由…

私有仓库工具Nexus Maven如何部署并实现远程访问管理界面

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具&#xff0c;用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关&#xff0c;可…