Hey, Nice to meet You. 

必有过人之节.人情有所不能忍者,匹夫见辱,拔剑而起,挺身而斗,此不足为勇也,天下有大勇者,猝然临之而不惊,无故加之而不怒.此其所挟持者甚大,而其志甚远也.          ☆☆☆所谓豪杰之士,

SSM的简易整合,基于RESTful风格

1、整合前言

本文是一个简单的SSM整合案例,基于RESTful风格,主要是简单记录一下学习笔记。

开发的相关环境:

  • JDK:1.8
  • Spring:5.2.7.RELEASE
  • Mybatis:3.5.3
  • MySQL数据库
  • Druid连接池

数据库源文件:

-- ----------------------------
-- Table structure for t_emp
-- ----------------------------
DROP TABLE IF EXISTS `t_emp`;
CREATE TABLE `t_emp`  (
  `emp_id` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `emp_salary` double(10, 2) NULL DEFAULT NULL,
  `emp_address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`emp_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_emp
-- ----------------------------
INSERT INTO `t_emp` VALUES (1, '张三', 13000.00, '广东深圳南山区');
INSERT INTO `t_emp` VALUES (2, '李四', 6000.00, '山东菏泽曹县');
INSERT INTO `t_emp` VALUES (3, '赵六', 10000.00, '上海浦东区');

导入相关的依赖:

    <!--定义版本信息-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <spring.version>5.2.7.RELEASE</spring.version>
        <mybatis.version>3.5.3</mybatis.version>
        <mybatis.spring.version>2.0.6</mybatis.spring.version>
        <mybatis.generator.version>1.4.0</mybatis.generator.version>
        <log4j.version>1.2.17</log4j.version>
        <mysql.version>8.0.23</mysql.version>
        <druid.version>1.2.4</druid.version>
    </properties>

    <dependencies>
        <!--Spring相关依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</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-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-jdbc</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-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <!--Mybatis相关依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis.spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mybatis.generator.version}</version>
        </dependency>
        <!--数据库相关依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--日志相关依赖-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!--单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <!--处理json数据的依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.5</version>
        </dependency>
    </dependencies>

2、相关的配置文件

注:配置文件都放在maven项目的resources目录下。

连接数据库的文件(db.properties):

datasource.driver-class-name=com.mysql.cj.jdbc.Driver
datasource.url=jdbc:mysql://localhost:3306/ssm?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowMultiQueries=true
datasource.username=root
datasource.password=root

Spring的核心xml配置文件(applicationContext.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- ================一、连接数据库================ -->
    <!--1、引入外部资源文件-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--2、配置数据源-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="${datasource.driver-class-name}"/>
        <property name="url" value="${datasource.url}"/>
        <property name="username" value="${datasource.username}"/>
        <property name="password" value="${datasource.password}"/>
    </bean>

    <!-- ===================二、整合Mybatis==================== -->
    <!-- 1.配置SqlSessionFactory -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">

        <!-- 装配数据源 -->
        <property name="dataSource" ref="dataSource"/>

        <!-- 配置Mybatis全局配置的两个方案只能二选一 -->
        <!-- (1)、配置Mybatis全局配置方案一:还是在Mybatis自己的配置文件中配,在Spring中指定配置文件位置 -->
        <!-- Mybatis全局配置文件的位置使用configLocation指定 <property name="configLocation" value=""/> -->
        <!-- (2)、配置Mybatis全局配置方案二(推荐):在Spring配置文件配置 -->
        <!-- 在Spring中执行Mybatis全局配置 -->
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true"/><!--驼峰原则-->
                <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/><!--打印SQL-->
            </bean>
        </property>
        <!-- 配置别名,使用包扫描-->
        <property name="typeAliasesPackage" value="com.thr.entity"/>
        <!-- 指定Mapper配置文件的位置XxxMapper.xml -->
        <property name="mapperLocations" value="classpath:com/thr/mapper/*Mapper.xml"/>
    </bean>

    <!-- 2.对Mapper接口所在的包进行扫描 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" id="mapperScannerConfigurer">
        <!-- 指定Mybatis中存放Mapper接口的包 -->
        <property name="basePackage" value="com.thr.mapper"/>
        <!-- 可选,如果不写,Spring启动时候。容器中自动会按照类型去把SqlSessionFactory对象注入进来 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- ===================三、配置声明式事务==================== -->
    <!-- 1.配置事务管理器的bean -->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 2.开启基于注解的声明式事务 -->
    <tx:annotation-driven/>
    <!-- 3.配置自动扫描的包 -->
    <context:component-scan base-package="com.thr.service"/>
</beans>

SpringMVC相关的xml配置文件(spring-mvc.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.thr.controller"/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置default-servlet-handler将没有映射的请求放行 -->
    <mvc:default-servlet-handler/>
    <!-- 开启SpringMVC的注解驱动功能(标配) -->
    <mvc:annotation-driven/>
</beans>

日志的配置(log4j.properties):

# 全局日志配置 INFO DEBUG ERROR
log4j.rootLogger=INFO, stdout
# MyBatis 日志配置
log4j.logger.cn.kgc.kb09=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%ns

3、Mybatis逆向工程生成代码

逆向工程的配置文件(generatorConfig.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!--targetRuntime="MyBatis3Simple"表示生成简易版本,这里创建原始版本,参数为MyBatis3-->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释,true:是;false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf8&amp;
                        useSSL=false&amp;serverTimezone=GMT%2B8"
                        userId="root"
                        password="root">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL和NUMERIC类型解析为Integer,为true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- javaBean的生成策略,targetProject:POJO类生成的位置,注意要加上项目名称,在这里搞了好久 -->
        <javaModelGenerator targetPackage="com.thr.entity" targetProject="./ssm/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略,targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.thr.mapper" targetProject="./ssm/src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略,targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.thr.mapper" targetProject="./ssm/src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 配置表信息 -->
        <!-- schema即为数据库名 tableName为对应的数据库表 domainObjectName是要生成的实体类 enableByExample是否生成example类   -->
        <table schema="ssm" tableName="t_emp" domainObjectName="Employee"/>
    </context>
</generatorConfiguration>

逆向工程生成相关代码的启动类:

/**
 * 逆向工程核心生成代码
 */
public class GeneratorSql {
    public static void main(String[] args) throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        // 指定逆向工程配置文件
        String file = GeneratorSql.class.getResource("/generatorConfig.xml").getFile();
        File configFile = new File(file);
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}

执行后会生成如下相关的代码。

image


4、业务层(Service)和控制层(Controller)

编写Service接口(EmployeeService):

public interface EmployeeService {

    List<Employee> findAll();

    Employee findById(Integer id);

    void add(Employee employee);

    void update(Employee employee);

    void delete(Integer id);
}

编写Service接口的实现类(EmployeeServiceImpl):

@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public List<Employee> findAll() {
        return employeeMapper.selectByExample(new EmployeeExample());
    }

    @Override
    public Employee findById(Integer id) {
        return employeeMapper.selectByPrimaryKey(id);
    }

    @Override
    public void add(Employee employee) {
        employeeMapper.insert(employee);
    }

    @Override
    public void update(Employee employee) {
        employeeMapper.updateByPrimaryKey(employee);
    }

    @Override
    public void delete(Integer id) {
        employeeMapper.deleteByPrimaryKey(id);
    }
}

编写控制层Controller代码(EmployeeController):

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    /**
     * 查询所有员工信息
     * @return
     */
    @GetMapping("/emp")
    public List<Employee> findAll(){
        List<Employee> list = employeeService.findAll();
        System.out.println(list);
        return list;
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     */
    @GetMapping("/emp/{id}")
    public Employee findById(@PathVariable("id") Integer id){
        return employeeService.findById(id);
    }

    /**
     * 添加
     * @param employee
     */
    @PostMapping("/emp")
    public void add(Employee employee){
        employeeService.add(employee);
    }

    /**
     * 修改,这里接收前端发来的JSON格式的数据
     * @param employee
     */
    @PutMapping("/emp")
    public void update(@RequestBody Employee employee){
        employeeService.update(employee);
    }

    /**
     * 删除数据
     * @param id
     */
    @DeleteMapping("/emp/{id}")
    public void delete(@PathVariable("id") Integer id){
        employeeService.delete(id);
    }
}

5、测试整合结果

[1]、查询所有数据(GET请求):http://localhost:8080/ssm/emp/

image


[2]、根据ID查询数据(GET请求):http://localhost:8080/ssm/emp/1

image


[3]、添加员工信息(POST请求):http://localhost:8080/ssm/emp

image

对PostMan的Body中的四个选项进行简单说明:

  • form-data:等价于http请求中的multipart/form-data,可以上传文件或者键值对,最后都会转化为一条消息,一般用来做文件的上传。
  • x-www-form-urlencoded:相当于http请求中的application/x-www-from-urlencoded,只能上传键值对,相当于将表单内的数据转换为Key-Value。
  • raw:表示的参数可以是任意格式的,可以上传text、json、xml、html等。
  • binary:相当于Content-Type:application/octet-stream,只可以上传二进制数据,通常用来上传文件,但是一次只能上传一个文件。

添加后的数据库变化:

image


[4]、修改数据(PUT请求):http://localhost:8080/ssm/emp ,这里发送的json格式的数据,因为PUT请求用key--value不好测试。

image

修改后的数据库变化:

image


[1]、删除数据(DELETE请求):http://localhost:8080/ssm/emp/4

image

image

posted @ 2021-06-21 16:14  唐浩荣  阅读(1255)  评论(1编辑  收藏  举报