架构框架搭建(一)《单体应用服务之SSM整合:Spring4 + SpringMvc + Mybatis》

简介: 在实际的业务开发中按照不同的场景需要,会有不同的业务架构也就同时会有不同的技术框架来支撑。那么这个专题想把一些常用的框架整理下,方便平时使用的同时也做一些技术沉淀。那么本章节会先搭建一个比较适合个人项目或者一些小公司开发项目的单体架构模型

前言介绍

在实际的业务开发中按照不同的场景需要,会有不同的业务架构也就同时会有不同的技术框架来支撑。那么这个专题想把一些常用的框架整理下,方便平时使用的同时也做一些技术沉淀。那么本章节会先搭建一个比较适合个人项目或者一些小公司开发项目的单体架构模型。服务功能展示页面如下;

27.jpg

工程环境

  1. JDK1.8
  2. Maven 3.2.3
  3. Spring 4.3.24.RELEASE + SpringMvc + Mybatis 3.3.0
  4. Mysql 5.6 + dbcp2
  5. layui 2.5.4

工程模型

整体的工程模型采用DDD四层架构,相对于MVC模式来讲。嗯!相当于家里三居换四居了!

1itstack-demo-frame-ssm
 2└── src
 3    ├── main
 4    │   ├── java
 5    │   │   └── org.itstack.demo
 6    │   │       ├── application    
 7    │   │       │    └── UserService.java    
 8    │   │       ├── domain
 9    │   │       │    ├── model
10    │   │       │    │   ├── aggregates
11    │   │       │    │   │   └── UserInfoCollect.java
12    │   │       │    │   ├── req
13    │   │       │    │   │   └── UserReq.java        
14    │   │       │    │   └── vo
15    │   │       │    │       └── UserInfo.java   
16    │   │       │    ├── repository
17    │   │       │    │   └── IUserRepository.java    
18    │   │       │    └── service 
19    │   │       │        └── UserServiceImpl.java    
20    │   │       ├── infrastructure
21    │   │       │    ├── common
22    │   │       │    │   ├── EasyResult.java
23    │   │       │    │   └── PageRequest.java
24    │   │       │    ├── dao
25    │   │       │    │   └── IUserDao.java   
26    │   │       │    ├── po
27    │   │       │    │   └── User.java       
28    │   │       │    └── repository
29    │   │       │        └── UserRepository.java 
30    │   │       └── interfaces
31    │   │            └── UserController.java
32    │   ├── resources    
33    │   │   ├── mapper
34    │   │   ├── props    
35    │   │   ├── spring
36    │   │   ├── logback.xml
37    │   │   ├── mybatis-config.xml
38    │   │   └── spring-config.xml
39    │   └── webapp
40    │       ├── page
41    │       ├── res
42    │       ├── WEB-INF
43    │       ├── index.html
44    │       └── res_layui.html
45    └── test
46         └── java
47             └── org.itstack.demo.test
48                 └── ApiTest.java

以下对工程模块进行介绍,整体源码获取,可以关注公众号:bugstack虫洞栈,回复:框架搭建

application应用层

应用层是比较薄的一层,不做具体逻辑开发。本工程里只包括服务的定义,具体逻辑有领域层实现。如果需要扩展可以做一些应用服务编排。

application/UserService.java & 定义接口

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6public interface UserService {
 7
 8    UserInfoCollect queryUserInfoList(UserReq req);
 9
10}

domain领域层

领域层是整个工程的核心服务层,这里负责处理具体的核心功能,完成领域服务。domain下可以有多个领域,每个领域里包括;聚合、请求对象、业务对象、仓储、服务。

domain/model/aggregates/UserInfoCollect.java & 定义聚合查询结果

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6public class UserInfoCollect {
 7
 8    private Long count;
 9    private List<UserInfo> userInfoList;
10
11    public UserInfoCollect() {
12    }
13
14    public UserInfoCollect(Long count, List<UserInfo> userInfoList) {
15        this.count = count;
16        this.userInfoList = userInfoList;
17    }
18
19    public Long getCount() {
20        return count;
21    }
22
23    public void setCount(Long count) {
24        this.count = count;
25    }
26
27    public List<UserInfo> getUserInfoList() {
28        return userInfoList;
29    }
30
31    public void setUserInfoList(List<UserInfo> userInfoList) {
32        this.userInfoList = userInfoList;
33    }
34}

domain/repository/IUserRepository.java & 定义仓储服务

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6public interface IUserRepository {
 7
 8    UserInfoCollect queryUserInfoList(UserReq req);
 9
10}

domain/service/UserServiceImpl.java & 对业务层功能进行实现

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@Service("userService")
 7public class UserServiceImpl implements UserService {
 8
 9    @Resource(name = "userRepository")
10    private IUserRepository userRepository;
11
12    @Override
13    public UserInfoCollect queryUserInfoList(UserReq req) {
14        return userRepository.queryUserInfoList(req);
15    }
16
17}

infrastructure基础层

  1. 实现领域层仓储定义
  2. 数据库操作为非业务属性的功能操作
  3. 在仓储实现层进行组合装配DAO&Redis&Cache等

infrastructure/dao/IUserDao.java & 数据库操作

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6public interface IUserDao {
 7
 8    List<User> queryUserInfoList(UserReq req);
 9
10    Long queryUserInfoCount(UserReq req);
11
12}

infrastructure/repository/UserRepository.java & 仓储功能实现如果有redis可以进行包装使用

1/**
 2 * 微信公众号:bugstack虫洞栈 | 欢迎关注学习专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@Repository("userRepository")
 7public class UserRepository implements IUserRepository {
 8
 9    @Resource
10    private IUserDao userDao;
11
12    @Override
13    public UserInfoCollect queryUserInfoList(UserReq req) {
14        Long count = userDao.queryUserInfoCount(req);
15        List<User> userList = userDao.queryUserInfoList(req);
16        List<UserInfo> userInfoList = new ArrayList<>();
17        userList.forEach(user -> {
18            UserInfo userInfo = new UserInfo();
19            userInfo.setUserId(user.getId());
20            userInfo.setName(user.getName());
21            userInfo.setAge(user.getAge());
22            userInfo.setAddress(user.getAddress());
23            userInfo.setEntryTime(user.getEntryTime());
24            userInfo.setStatus(user.getStatus());
25            userInfoList.add(userInfo);
26        });
27        return new UserInfoCollect(count, userInfoList);
28    }
29
30}

interfaces接口层

  1. 包装应用接口对外提供api,目前这一层比较简单只需要进行接口使用即可
  2. 如果是对外部提供服务接口,那么可以使用DTO方式进行转换,避免污染到业务类

interfaces/UserController.java & 提供接口服务

1@Controller
 2@RequestMapping("/api/user/")
 3public class UserController {
 4
 5    private Logger logger = LoggerFactory.getLogger(UserController.class);
 6
 7    @Resource
 8    private UserService userService;
 9
10    @RequestMapping(path = "queryUserInfoList", method = RequestMethod.GET)
11    @ResponseBody
12    public EasyResult queryUserInfoList(String json, String page, String limit) {
13        try {
14            logger.info("查询用户信息列表开始。json:{}", json);
15            UserReq req = JSON.parseObject(json, UserReq.class);
16            if (null == req) req = new UserReq();
17            req.setPage(page, limit);
18            UserInfoCollect userInfoCollect = userService.queryUserInfoList(req);
19            logger.info("查询用户信息列表完成。userInfoCollect:{}", JSON.toJSONString(userInfoCollect));
20            return EasyResult.buildEasyResultSuccess(userInfoCollect.getCount(), userInfoCollect.getUserInfoList());
21        } catch (Exception e) {
22            logger.error("查询用户信息列表失败。json:{}", json, e);
23            return EasyResult.buildEasyResultError(e);
24        }
25    }
26
27}

resource配置

这里包括了Spring、SpringMvc、mybatis、以及日志信息的配置;

mapper/User_Mapper.xml

1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE mapper
 3        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5
 6<mapper namespace="org.itstack.demo.infrastructure.dao.IUserDao">
 7
 8    <select id="queryUserInfoCount" resultType="java.lang.Long">
 9        select count(id)
10        from user
11        <where>
12            <if test="name != null">
13                and name = #{name}
14            </if>
15            <if test="status != null">
16                and status = #{status}
17            </if>
18        </where>
19    </select>
20
21    <select id="queryUserInfoList" resultType="org.itstack.demo.infrastructure.po.User">
22      SELECT id, name, age, address, entryTime, status, remark, createTime, updateTime
23      FROM user
24      <where>
25          <if test="name != null">
26              and name = #{name}
27          </if>
28          <if test="status != null">
29              and status = #{status}
30          </if>
31      </where>
32      limit #{pageStart},#{pageEnd}
33    </select>
34
35</mapper>

props/jdbc.properties & 数据库链接信息

1db.jdbc.driverClassName=com.mysql.jdbc.Driver
2db.jdbc.url=jdbc:mysql://127.0.0.1:3306/itstack?createDatabaseIfNotExist=true&amp;characterEncoding=utf-8&amp;useUnicode=true
3db.jdbc.username=root
4db.jdbc.password=123456

spring/spring-config-datasource.xml & dbcp2数据源配置以及扫描Mapper等

1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="http://www.springframework.org/schema/beans"
 3       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4       xsi:schemaLocation="http://www.springframework.org/schema/beans
 5    http://www.springframework.org/schema/beans/spring-beans.xsd">
 6
 7    <!-- 1.数据库连接池 -->
 8    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
 9        <property name="driverClassName" value="${db.jdbc.driverClassName}" />
10        <property name="url" value="${db.jdbc.url}" />
11        <property name="username" value="${db.jdbc.username}" />
12        <property name="password" value="${db.jdbc.password}" />
13        <property name="maxTotal" value="20" />
14        <property name="maxIdle" value="3" />
15        <property name="maxWaitMillis" value="15000" />
16        <property name="timeBetweenEvictionRunsMillis" value="60000" />
17        <property name="minEvictableIdleTimeMillis" value="180000" />
18    </bean>
19
20    <!-- 2.配置SqlSessionFactory对象 -->
21    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
22        <!-- 注入数据库连接池 -->
23        <property name="dataSource" ref="dataSource" />
24        <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
25        <property name="configLocation" value="classpath:mybatis-config.xml" />
26        <!-- 扫描entity包 使用别名 -->
27        <property name="typeAliasesPackage" value="com.soecode.lyf.entity" />
28        <!-- 扫描sql配置文件:mapper需要的xml文件 -->
29        <property name="mapperLocations" value="classpath:mapper/*.xml" />
30    </bean>
31
32    <!-- 3.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
33    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
34        <!-- 注入sqlSessionFactory -->
35        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
36        <!-- 给出需要扫描Dao接口包 -->
37        <property name="basePackage" value="org.itstack.demo.infrastructure.dao" />
38    </bean>
39
40</beans>

resources/mybatis-config.xml

1<?xml version="1.0" encoding="UTF-8" ?>
 2<!DOCTYPE configuration
 3  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4  "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5<configuration>
 6    <!-- 配置全局属性 -->
 7    <settings>
 8        <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
 9        <setting name="useGeneratedKeys" value="true" />
10        <!-- 使用列别名替换列名 默认:true -->
11        <setting name="useColumnLabel" value="true" />
12        <!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
13        <setting name="mapUnderscoreToCamelCase" value="true" />
14    </settings>
15</configuration>

resources/spring-config.xml

1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="http://www.springframework.org/schema/beans"
 3       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4       xmlns:context="http://www.springframework.org/schema/context"
 5       xmlns:aop="http://www.springframework.org/schema/aop"
 6       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
 7       default-autowire="byName">
 8
 9    <context:component-scan base-package="org.itstack"/>
10    <aop:aspectj-autoproxy/>
11
12    <!-- 属性文件读入 -->
13    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
14        <property name="locations">
15            <list>
16                <value>classpath:props/*.properties</value>
17            </list>
18        </property>
19    </bean>
20
21    <import resource="classpath:spring/spring-*.xml"/>
22
23</beans>
24

itstack.sql

1DROP TABLE user;
2CREATE TABLE user ( id bigint(11) NOT NULL AUTO_INCREMENT, name varchar(32), age int(4), address varchar(128), entryTime datetime, remark varchar(64), createTime datetime, updateTime datetime, status int(4) DEFAULT '0', PRIMARY KEY (id), INDEX idx_name (name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3insert into user (id, name, age, address, entryTime, remark, createTime, updateTime, status) values (1, '水水', 18, '吉林省榆树市黑林镇尹家村5组', '2019-12-22 00:00:00', '无', '2019-12-22 00:00:00', '2019-12-22 00:00:00', 0);
4insert into user (id, name, age, address, entryTime, remark, createTime, updateTime, status) values (2, '豆豆', 18, '辽宁省大连市清河湾司马道407路', '2019-12-22 00:00:00', '无', '2019-12-22 00:00:00', '2019-12-22 00:00:00', 1);
5insert into user (id, name, age, address, entryTime, remark, createTime, updateTime, status) values (3, '花花', 19, '辽宁省大连市清河湾司马道407路', '2019-12-22 00:00:00', '无', '2019-12-22 00:00:00', '2019-12-22 00:00:00', 0);

综上总结

  • 此工程模型基于SSM比较适合开发ERP服务,ERP使用layui页面清新,功能完善
  • 工程框架采用了DDD架构模式,在此架构模式下可以更容易的开发系统,适应后比MVC更加方便
  • 后续将继续拓展架构服务搭建,包括一些Dubbo、Redis、mq等使用,方便自己也方便他人
目录
相关文章
|
6天前
|
Java 数据库连接 Maven
后端框架学习-----mybatis(使用mybatis框架遇到的问题)
这篇文章总结了在使用MyBatis框架时可能遇到的几个常见问题及其解决方法,包括配置文件注册、接口绑定、方法名匹配、返回类型匹配、Maven资源导出、时区设置和字符编码问题。
|
6天前
|
Java 数据库连接 Maven
SSM框架整合图书管理项目
这篇文章是关于SSM框架整合到图书管理项目的详细教程,涵盖了从Maven项目构建、依赖导入、数据库连接、配置文件编写、实体类和接口实现到SpringMVC整合的完整步骤。
SSM框架整合图书管理项目
|
6天前
|
Java 数据库连接 mybatis
mybatis框架图
文章介绍了MyBatis框架的起源、发展和其作为持久层框架的功能,提供了MyBatis的框架图以帮助理解其结构和组件。
mybatis框架图
|
6天前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
3天前
|
监控 负载均衡 API
从单体到微服务:架构转型之道
【8月更文挑战第17天】从单体架构到微服务架构的转型是一项复杂而系统的工程,需要综合考虑技术、团队、文化等多个方面的因素。通过合理的规划和实施策略,可以克服转型过程中的挑战,实现系统架构的升级和优化。微服务架构以其高度的模块化、可扩展性和灵活性,为业务的持续发展和创新提供了坚实的技术保障。
|
6天前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(5、分页)
这篇文章介绍了如何在MyBatis框架中实现分页功能,包括使用SQL的`limit`语句进行分页和利用MyBatis的`RowBounds`对象进行分页的方法。
|
6天前
|
Java 数据库连接 mybatis
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
|
6天前
|
Java 数据库连接 测试技术
后端框架的学习----mybatis框架(8、lombok)
这篇文章介绍了如何在MyBatis框架中使用lombok库来简化Java实体类的编写,包括在IDEA中安装Lombok插件、在项目中导入lombok依赖以及在实体类上使用Lombok提供的注解。
|
6天前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(7、使用注解开发)
这篇文章讲述了如何使用MyBatis框架的注解方式进行开发,包括在接口上使用注解定义SQL语句,并通过动态代理实现对数据库的增删改查操作,同时强调了接口需要在核心配置文件中注册绑定。
|
6天前
|
Java 数据库连接 数据库
后端框架的学习----mybatis框架(6、日志)
这篇文章介绍了如何在MyBatis框架中使用日志功能,包括配置MyBatis的日志实现、使用log4j作为日志工具,以及如何通过配置文件控制日志级别和输出格式。