一个电商项目的Web服务化改造
2016-04-25 17:58
295 查看
一个电商项目的Web服务化改造项目,早期是随便瞎做的,没啥架构,连基本的设计也没。有需求,实现需求,再反复修改。大致就是这么做的。
最近,项目要重新架构,和某boss协商的结果是,采用阿里开源的dubbo实现服务化。前几天,写了一篇dubbo入门案例,分布式服务框架Dubbo入门案例和项目源码/article/7549585.html。
最近,开始实现基本业务功能模块的开发。完成1个模块,原有项目就接入进来,从而完成项目的服务化改造。
在和某boss的商讨之后,我们的做法是1.只做单表操作,mysql数据库层次不写“关联查询”。2.针对单个表,实现CRUD等基本操作。3.层次划分 mapper:基本的数据库CRUD,全部是原子操作 dao:对mapper的数据进行组装,比如关联查询。 之前,是在service层进行代码组装的。 bizService:业务逻辑操作 webService:对外服务层 由于当前阶段,我们的业务逻辑比较简单,bizService和webService可以看成是1层的。 好处:严格的层次划分,上层可以调用下层,同层之间不能互相调用。比如service不能调用其它的service。4.结合Freemarker,写代码自动生成的工具。根据数据库表,自动生成标准化的代码。 书写中...
类结构 Base*:基础的公共的类 Brand: 具体的,以品牌brand表为例 brand表结构
Brand.java:数据库表对应的模型
BaseMapper.java:定义最通用的sql映射。注意,这个mapper没有对应的Mybatis xml配置。
BrandMapper.java:品牌的sql映射,Java接口定义 import java.util.List;
BrandMapper.xml:品牌的sql映射,sql语句
BaseDao.java:定义最基础、最通用的dao层接口。
BrandDao.java: 品牌的dao接口
BrandDaoImpl.java:品牌的dao接口实现类
BrandService.java: 品牌,业务层的接口定义 代码类似 BrandServiceImpl.java:品牌,业务层的接口实现 代码类似 junit单元测试:测dao和service层,mapper层忽视 BaseDaoTest.java:dao基础配置
BaseServiceTest.java:service基础配置 代码类似 BrandServiceTest.java:brand的基础测试用例 代码类似 单元测试结果图
spring数据源配置,spring-dataSource.xml 和普通项目一样 除了Base基础接口,具体的业务类,计划通过代码生成工具自动生成。 我们保证内部代码mapper层和dao层代码正确,保证service层正确,然后用dubbo把service的代码,稍微做点配置,对外提供服务。 其它项目,比如front前端商城系统、mobile移动App、backend后端运营系统,直接调用咱们的服务接口即可。
最近,项目要重新架构,和某boss协商的结果是,采用阿里开源的dubbo实现服务化。前几天,写了一篇dubbo入门案例,分布式服务框架Dubbo入门案例和项目源码/article/7549585.html。
最近,开始实现基本业务功能模块的开发。完成1个模块,原有项目就接入进来,从而完成项目的服务化改造。
在和某boss的商讨之后,我们的做法是1.只做单表操作,mysql数据库层次不写“关联查询”。2.针对单个表,实现CRUD等基本操作。3.层次划分 mapper:基本的数据库CRUD,全部是原子操作 dao:对mapper的数据进行组装,比如关联查询。 之前,是在service层进行代码组装的。 bizService:业务逻辑操作 webService:对外服务层 由于当前阶段,我们的业务逻辑比较简单,bizService和webService可以看成是1层的。 好处:严格的层次划分,上层可以调用下层,同层之间不能互相调用。比如service不能调用其它的service。4.结合Freemarker,写代码自动生成的工具。根据数据库表,自动生成标准化的代码。 书写中...
类结构 Base*:基础的公共的类 Brand: 具体的,以品牌brand表为例 brand表结构
CREATE TABLE `brand` ( `id` varchar(50) NOT NULL COMMENT 'ID', `name` varchar(30) DEFAULT NULL COMMENT '品牌名称', `logo` varchar(100) DEFAULT NULL COMMENT '品牌LOGO', `isDelete` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除', `createTime` datetime DEFAULT NULL COMMENT '创建日期', `updateTime` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='品牌表';
Brand.java:数据库表对应的模型
/** * 品牌 * */ public class Brand { private String id; private String name; private String logo; private Date createTime; private Date updateTime; private Integer isDelete; }
BaseMapper.java:定义最通用的sql映射。注意,这个mapper没有对应的Mybatis xml配置。
import java.util.List; public interface BaseMapper<ID, Entity> { Entity get(ID id); List<Entity> listByIdList(List<String> idList); List<Entity> listAll(); int add(Entity entity); int update(Entity entity); int remove(ID id); int removeByIdList(List<ID> idList); }
BrandMapper.java:品牌的sql映射,Java接口定义 import java.util.List;
@Mapper public interface BrandMapper extends BaseMapper<String, Brand> { // read List<Brand> listByShopIdList(List<String> shopIdList); List<Brand> list(BrandBean brandBean); // write }
BrandMapper.xml:品牌的sql映射,sql语句
<?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.webservice.mapper.BrandMapper"> <sql id="columns"> id,name,logo,createTime,updateTime,isDelete </sql> <select id="get" resultType="Brand"> select <include refid="columns" /> from brand where id = #{id} </select> <select id="list" resultType="Brand"> select <include refid="columns" /> from brand where isDelete=0 <if test="name != null and name !=''"> and name like '%${name}%' </if> order by createTime desc </select> ... }
BaseDao.java:定义最基础、最通用的dao层接口。
import java.util.List; public interface BaseDao<ID, Entity,Bean> { //read Entity get(ID id); List<Entity> listByIdList(List<String> idList); List<Entity> list(Bean bean); List<Entity> listAll(); //write int add(Entity entity); int update(Entity entity); int remove(ID id); int removeByIdList(List<ID> idList); }
BrandDao.java: 品牌的dao接口
import java.util.List; public interface BrandDao extends BaseDao<String, Brand,BrandBean> { // read List<Brand> listByShopIdList(List<String> shopIdList); List<String> listLogoByIdList(List<String> idList); // write }
BrandDaoImpl.java:品牌的dao接口实现类
@Component public class BrandDaoImpl implements BrandDao { @Autowired private BrandMapper brandMapper; private Logger logger = Logger.getLogger(getClass()); @Override public Brand get(String id) { if(StringUtils.isEmpty(id)){ logger.error("The id is null"); return null; } return brandMapper.get(id); } @Override public List<Brand> listByIdList(List<String> idList) { if (CollectionUtils.isEmpty(idList)) { logger.error("The idList is empty"); return null; } return brandMapper.listByIdList(idList); } }
BrandService.java: 品牌,业务层的接口定义 代码类似 BrandServiceImpl.java:品牌,业务层的接口实现 代码类似 junit单元测试:测dao和service层,mapper层忽视 BaseDaoTest.java:dao基础配置
//单元测试的mysql数据库,最好是单独的一套库,没有任何数据。如果开发和单元测试共用数据库,listAll之类的方法会有影响。 //单元测试:1.构造数据,2.执行操作,3.断言,4.回滚 //设置自动回滚 @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional @ContextConfiguration(locations={"classpath*:spring-dataSource.xml"}) @RunWith(SpringJUnit4ClassRunner.class) public class BaseDaoTest { public static final String NOT_EXIST_ID_STRING="not_exist_id_string"; public static final String NOT_EXIST_ID_INT="not_exist_id_int"; public static final String EXIST_NAME = "test"; public static final String NOT_EXIST_NAME = "not_exist_name"; } BrandDaoTest.java:brand的基础测试用例 public class BrandDaoTest extends BaseDaoTest { @Autowired private BrandDao brandDao; // //////////////////////read////////////////////////// @Test public void testGet() { Brand brand = TestDataCenter.brand(); brandDao.add(brand); Brand dbBrand = brandDao.get(brand.getId()); assertNotNull(dbBrand); } @Test public void testGetNotExist() { Brand brand = TestDataCenter.brand(); brandDao.add(brand); Brand nullBrand = brandDao.get(NOT_EXIST_ID_STRING); assertNull(nullBrand); } }
BaseServiceTest.java:service基础配置 代码类似 BrandServiceTest.java:brand的基础测试用例 代码类似 单元测试结果图
spring数据源配置,spring-dataSource.xml 和普通项目一样 除了Base基础接口,具体的业务类,计划通过代码生成工具自动生成。 我们保证内部代码mapper层和dao层代码正确,保证service层正确,然后用dubbo把service的代码,稍微做点配置,对外提供服务。 其它项目,比如front前端商城系统、mobile移动App、backend后端运营系统,直接调用咱们的服务接口即可。
相关文章推荐
- C++第四次作业
- RxJava----使用
- iOS开发:提取MP3文件中的信息
- 【BZOJ1441】Min【裴蜀定理】
- android面试题收集
- 关于如何使用eclipse创建web项目——整个流程的概述
- RunLoop浅谈
- XMLHTTPRequest笔记
- UVaLA 3026 Period MP算法
- Linux中的15个‘echo’ 命令实例
- 多进程并发编程----基于高级的预先创建进程池(accept使用线程上锁)的模型
- jQuery中的ajax
- Android---SharedPreferences使用
- android中使用线程池和临时缓存优化网络图片加载
- Activity堆栈管理
- 如何实现炫酷的ArtLine
- 欢迎使用CSDN-markdown编辑器
- 获取button所在tableView cell下标
- Android中文API- <merge/> 标签
- JS倒计时,距离某一日期还有多少时间