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

news2024/12/23 0:22:50

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接口测试结果

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

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

相关文章

拼多多无货源中转仓项目真的靠谱吗?发展前景如何?

阿阳最近一直在关注无货源电商这一块&#xff0c;尤其是拼多多无货源中转仓&#xff0c; 现如今也有了自己的运营团队和交付团队&#xff0c;整体来看这个项目还算不错&#xff01; 说实话&#xff0c;在考察这个项目的时候&#xff0c;看到市面上很多人在做&#xff0c;包括我…

JavaScript 类型判断及类型转换规则

文章目录 JavaScript 类型及其判断使用 typeof 判断类型使用 instanceof 判断类型使用 constructor 和 Object.prototype.toString 判断类型JavaScript 类型及其转换JavaScript 函数参数传递cannot read property of undefined 问题解决方案分析一道网红题目JavaScript 类型判断…

【GAMES101】Lecture 08 着色-Blinn-Phong反射模型

目录 Blinn-Phong反射模型-高光 Blinn-Phong反射模型-环境光照 Blinn-Phong反射模型 Blinn-Phong反射模型-高光 我们在lecture7的时候讲了这个Blinn-Phong反射模型的漫反射部分&#xff0c;现在我们继续讲Blinn-Phong反射模型的高光部分 这个高光是怎么产生的呢&#xff0…

} expected.Vetur(1005)

typescript TS 错误码大全&#xff01;收藏了 - 环信 } expected.Vetur(1005) 没有补齐} 虽然他给的是最后代码出错了&#xff0c;但可以看看之前的代码有没有红色的{&#xff0c;补齐即可以

Air780E开发板开发环境搭建

开发板原理图 开发软件 下载网站 https://luatos.com/luatools/download/last 使用教程 烧录教程 - LuatOS 文档 开发流程 首先下载最新版本的Luatools 然后新建一个Luatools文件夹&#xff0c;将下载的exe文件放入其中后&#xff0c;再打开exe文件&#xff08;会生成目…

MB51选择屏幕与报表增强

1、文档说明 如之前文档《MIGO新增页签增强》&#xff0c;在MIGO中增强自定义字段&#xff0c;那么在查询MB51时&#xff0c;想通过自定义字段进行筛选&#xff0c;并将数据展示到报表中&#xff0c;就需要对MB51进行增强。 此处需要说明&#xff0c;文档 《MIGO新增页签增强…

Leetcode刷题笔记题解(C++):200. 岛屿数量

思路&#xff1a;利用深度优先搜索的思路来查找1身边的1&#xff0c;并且遍历之后进行0替换防止重复dfs&#xff0c;代码如下所示 class Solution { public:int numIslands(vector<vector<char>>& grid) {int row grid.size();int col grid[0].size();int n…

【从0上手cornerstone3D】如何加载nifti格式的文件

在线演示 支持加载的文件格式 .nii .nii.gz 代码实现 npm install cornerstonejs/nifti-volume-loader// ------------- 核心代码 Start------------------- // 注册一个nifti格式的加载器 volumeLoader.registerVolumeLoader("nifti",cornerstoneNiftiImageVolu…

Ubuntu 安装Python3.8

安装Python3.8 一、安装环境 Ubuntu2004Python2.7 目标是将python版本从 2.7 更新到3.8 二、安装步骤 2.1 下载python3.8安装包 wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tar.xz2.2 安装 依次执行如下步骤&#xff1a; tar Jxf Python-3.8.0.tar.xz…

红队打靶练习:NULLBYTE: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 图片信息收集 hydra爆破 sql注入 闭合 爆库 爆表 爆列 爆字段 hashcat SSH登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan…

梳理从MVP变换到光栅化的过程

1.梳理从MVP变换到光栅化的过程 相关博客&#xff1a; 1.MVP变换 2.Rasterization&#xff08;光栅化&#xff09; 1.1 View/Camera transformation 此例中相机初始位置为&#xff08;0,0,5&#xff09;【备注&#xff1a;详见主函数中输入的值】经过 M view M_{\text{view}}…

shell编程-uname命令详解(超详细)

文章目录 前言一、介绍二、语法格式三、常见选项四、示例用法1. 输出所有信息2. 查看内核名称3. 查看主机名4. 查看内核发行号5. 查看内核版本6. 查看硬件架构名称7. 查看处理器类型8. 查看硬件平台9. 查看操作系统名称10. 查看版本信息 总结 前言 在本文中&#xff0c;我们将…

智能小程序开发项目步骤流程

快速开始 在开发小程序之前&#xff0c;请确保电脑上已经安装node运行环境。可前往Node.js官网(opens in a new tab)下载安装。智能小程序环境搭建和面板小程序一致&#xff0c;请参考面板小程序搭建环境指南。 开发小程序的流程&#xff1a; 使用涂鸦开发者 IoT 账号登录 T…

鸿蒙千帆起~ 是转? 还是留?

近期鸿蒙系统相关行业热度一度高涨&#xff0c;像今天2024年1月18日 鸿蒙OS Next开发者预览版正式发布引起了不少业内人士关注&#xff0c;再度冲上了热榜。余承东老余之前就说过2024年是鸿蒙关键的一年&#xff0c;从这句话就可以看出后一定有大的动作。 就像去年有业内人士网…

Unreal Engine(UE5)中构建离线地图服务

1. 首先需要用到3个软件&#xff0c;Unreal Engine&#xff0c;gis office 和 bigemap离线服务器 Unreal Engine下载地址:点击前往下载页面 Gis office下载地址:点击前往下载页面 Bigemap离线服务器 下载地址: 点击前往下载页面 Unreal Engine用于数字孪生项目开发&#x…

【python】—— 集合

目录 &#xff08;一&#xff09;集合的概念 &#xff08;二&#xff09;集合的使用 2.1 集合的创建 2.2 集合元素的唯一性 2.3 集合的操作 2.3.1 并集 2.3.2 交集 2.3.3 差集 2.3.4 补集 2.4 遍历集合 2.5 其他集合操作 2.5.1 添加元素 2.5.2 移除元素 2.5.3 清…

15分钟学会Pinia

Pinia 核心 Pinia 介绍 官方文档&#xff1a;pinia.web3doc.top/ What is Pinia ? Pinia 是一个状态管理工具&#xff0c;它和 Vuex 一样为 Vue 应用程序提供共享状态管理能力。语法和 Vue3 一样&#xff0c;它实现状态管理有两种语法&#xff1a;选项式API 与 组合式API&a…

11- OpenCV:自定义线性滤波(卷积,卷积边缘)

目录 一、卷积 1、卷积概念 2、卷积如何工作 3、常见算子&#xff08;卷积核 Kenel&#xff09; 4、自定义卷积模糊 二、卷积边缘 1、卷积边缘问题 2、处理边缘 一、卷积 1、卷积概念 &#xff08;1&#xff09;在OpenCV中&#xff0c;卷积是一种常用的图像处理操作&…

Python+Selenium+Unittest 之selenium13--WebDriver操作方法3-鼠标操作2

这篇说下ActionChains里常用的几种鼠标操作的方法。 ActionChains常用的鼠标操作方法 click()鼠标左键单击double_click()鼠标左键双击context_click()鼠标右键单击move_to_element()鼠标移动到某个元素上&#xff08;鼠标悬浮操作&#xff09;click_and_hold()点击鼠标左键&am…

合并K个升序链表(LeetCode 23)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;顺序合并方法二&#xff1a;分治合并方法三&#xff1a;使用优先队列合并 参考文献 1.问题描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff…