使用 mybatis + flying + 双向相关建模 的电商后端
mybatis.flying
众所周知,mybatis 虽然易于上手,但放到互联网环境下使用时,不可避免的要面对诸如‘’一级缓存存在脏数据‘’、‘’需要写大量明文 SQL 语句‘’等问题。对于这些问题 mybatis 的开发团队选择了一种谦逊的方式,他们开放 mybatis 接口,允许用户开发插件,按自己的方式来解决这些问题。于是,一切 ORM 领域相关的问题在 mybatis 上通过插件都有了解决方案。
flying 主要特点:
以前我们在 mapper.xml 中要写很复杂的 sql 语句,但现在在 mapper.xml 中只需这样:
<select id="select" resultMap="result">
flying#{?}:select
</select>
<select id="selectOne" resultMap="result">
flying:selectOne
</select>
<insert id="insert">
flying:insert
</insert>
<update id="update">
flying:update
</update>
<delete id="delete">
flying:delete
</delete>
再在您的实体类上加上这样一些标注:
package myPackage;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "account")
public class Account {
@Id
@Column
private Integer id;
@Column
private java.lang.String name;
@Column
private Integer age;
/* 省略 getter 和 setter */
}
flying 就完全明白您的数据结构和您想做的事情了。 接下来您增删改查这个实体就会变得非常简单:
/* 新增 */
Account newAccount = new Account();
newAccount.setName("ann");
newAccount.setAge(18);
accountService.insert(newAccount);
/* 按主键查询 */
Account account = accountService.select(newAccount.getId());
/* 按姓名查询,这里忽略了年龄 */
Account accountC1 = new Account();
accountC1.setName("ann");
Account account1 = accountService.selectOne(accountC1);
/* account1 和 account 代表相同的业务数据 */
/* 按年龄查询,这里忽略了姓名 */
Account accountC2 = new Account();
accountC2.setAge(18);
Account account2 = accountService.selectOne(accountC2);
/* account2 和 account 代表相同的业务数据 */
/* 按姓名和年龄查询 */
Account accountC3 = new Account();
accountC3.setName("ann");
accountC3.setAge(18);
Account account3 = accountService.selectOne(accountC3);
/* account3 和 account 代表相同的业务数据 */
/* 修改 */
account.setName("bob");
accountService.update(newAccount);
/* 按主键删除 */
accountService.delete(newAccount);
由于 flying 掌握了您全部的数据结构和实体关系,所以操作数据变得非常简单,您再也不需要定义 “getAccountById、getAccountByName、getAccountByAge” 这样重复性强的方法了,由此带来更大的好处是您的 service 层只需要关注事务方面的逻辑即可,它从低级代码中完全解放了出来。以上只是 flying 功能的冰山一角,其它的功能如多表联查、分页、乐观锁、跨数据源查询、二级缓存等 flying 都有简单的解决方案,您可以在 flying-doc.limeng32.com 中进行查看。
flying 特点总结如下:
数据操作入参和返回类型都是自定义的实体类,完全 no sql 杜绝各种‘’手滑‘’,项目可随意重构。
支持跨表操作和跨数据源操作。
非侵占工作机制,可以和您已有的 mybatis 方法协同工作。
加入了优化过的缓存插件,可以对多数据源环境下 flying 方法和传统 mybatis 方法同时进行缓存管理。
可以自定义主键生成器,全面支持或逻辑查询。(初雪版新增特性)
flying 获取方式:
flying 的 maven 坐标为:
<groupId>com.github.limeng32</groupId>
<artifactId>mybatis.flying</artifactId>
<version>0.9.3</version>
mybatis 版本与 flying 最新版本初雪的对应关系见下:
mybatis 版本 | flying-初雪 |
---|---|
3.3.0、3.3.1 | 0.8.3 |
3.4.0、3.4.1、3.4.2、3.4.3、3.4.4、3.4.5 | 0.9.3 |
之所以采用分版本发布的方式是因为我们对 mybatis 每个版本的用户都认真负责,力求使您得到 flying 最大的好处。
我们还为您提供了一个快速上手的示例,请按以下方式使用:
1、将代码搭建成 maven 项目。
2、以 maven 命令执行 tomcat7:run
以下是初始化时的添加的数据源 dataSource 和 dataSource2,将商品业务数据和用户数据分开存放是一种常见做法。dataSource 描述了两个购物车和 12 种商品和商品装入购物车的情况:
<dataset>
<CART ID="1" DEAL="0" DEAL_TIME=null PERSON_ID="1"/>
<CART ID="2" DEAL="0" DEAL_TIME=null PERSON_ID="2" />
<COMMODITY ID="1" NAME="牙刷A" PRICE="1200" />
<COMMODITY ID="2" NAME="牙刷B" PRICE="1850" />
<COMMODITY ID="3" NAME="牙刷C" PRICE="2100" />
<COMMODITY ID="4" NAME="佳洁士牙膏" PRICE="1499" />
<COMMODITY ID="5" NAME="六必治牙膏" PRICE="1999" />
<COMMODITY ID="6" NAME="云南白药牙膏" PRICE="2499" />
<COMMODITY ID="7" NAME="潘婷洗发露" PRICE="3500" />
<COMMODITY ID="8" NAME="多芬洗发露" PRICE="3900" />
<COMMODITY ID="9" NAME="海飞丝洗发露" PRICE="5100" />
<COMMODITY ID="10" NAME="浴液-1500ML" PRICE="2800" />
<COMMODITY ID="11" NAME="浴液-2000ML" PRICE="3200" />
<COMMODITY ID="12" NAME="浴液-4000ML" PRICE="4900" />
<CART_COMMODITY ID="1" CART_ID="1" COMM_ID="1" AMOUNT="3" />
<CART_COMMODITY ID="2" CART_ID="1" COMM_ID="5" AMOUNT="4" />
<CART_COMMODITY ID="3" CART_ID="1" COMM_ID="8" AMOUNT="1" />
<CART_COMMODITY ID="4" CART_ID="1" COMM_ID="12" AMOUNT="1" />
<CART_COMMODITY ID="5" CART_ID="2" COMM_ID="2" AMOUNT="2" />
<CART_COMMODITY ID="6" CART_ID="2" COMM_ID="4" AMOUNT="1" />
<CART_COMMODITY ID="7" CART_ID="2" COMM_ID="9" AMOUNT="2" />
<CART_COMMODITY ID="8" CART_ID="2" COMM_ID="11" AMOUNT="1" />
</dataset>
dataSource2 描述了 3 种会员级别和 3 位用户的情况:
<dataset>
<ROLE ID="1" NAME="普通会员" VALUE="normal" />
<ROLE ID="2" NAME="银牌会员" VALUE="silver" />
<ROLE ID="3" NAME="金牌会员" VALUE="gold" />
<PERSON ID="1" NAME="张三" ROLE_ID="1" />
<PERSON ID="2" NAME="李四" ROLE_ID="2" />
<PERSON ID="3" NAME="王五" ROLE_ID="3" />
</dataset>
项目结构截图
运行效果
运行起来后,具体的功能访问页面可以用如下方式访问到,在浏览器中输入以下 url 可以看到效果:
查看购物车: http://localhost:8080/flying-demo2/getCart?id=${购物车cart的id}
查看商品: http://localhost:8080/flying-demo2/getCommodity?id=${商品commodity的id}
翻页查看商品(所有条件均为可选): http://localhost:8080/flying-demo2/getCommodityInPage?pageNum=${页码}&priceOrder=${按价格升序或降序输入asc或desc}&priceFrom=${价格最小值}&priceTo=${价格最大值}
增加新商品: http://localhost:8080/flying-demo2/addCommodity?name=${新商品名称}&price=${新商品价格}
编辑商品: http://localhost:8080/flying-demo2/updateCommodity?id=${商品的id}&name=${商品的名称}&price=${商品的价格}
查看购物车中的商品: http://localhost:8080/flying-demo2/getCommodityByCart?id=${购物车的id}
对购物车进行结账: http://localhost:8080/flying-demo2/dealCart?id=${购物车的id}
取消购物车的结账: http://localhost:8080/flying-demo2/undealCart?id=${购物车的id}
查看用户: http://localhost:8080/flying-demo2/getPerson?id=${用户的id}
查看会员级别: http://localhost:8080/flying-demo2/getRole?id=${会员级别的id}
编辑会员级别: http://localhost:8080/flying-demo2/updateRoleDirectly?id=${会员级别的id}&name=${会员级别的名称}
查询匹配两个级别值(如gold、silver、normal)的会员级别(使用或逻辑特性):
http://localhost:8080/flying-demo2/getRoleValue1OrValue2?value1=${级别值1}&value2=${级别值2}
查询会员级别值(如gold、silver、normal)或用户名称匹配给定值的用户(使用外键或逻辑特性)
http://localhost:8080/flying-demo2/getRoleValueOrPersonName?value=${级别值}&name=${用户名称}
向当前购物车加入/删除商品(amount为负数时为删除),并自动处理最终结果(用来展示双向相关算法下处理业务模型的优雅)
http://localhost:8080/flying-demo2/addCommodityToCart?cartId=${购物车的id}&commId=${商品的id}&amount=${购买数量}
按两个用户id查询购买的商品详情(使用跨库或逻辑特性)
http://localhost:8080/flying-demo2/getCartCommodityByPersonId1OrId2?id1=${用户id1}&id2=${用户id2}
不刷新缓存的编辑会员级别:http://localhost:8080/flying-demo2/updateRoleDirectlyWithoutCache?id=${会员级别的id}&name=${会员级别的名称}
从 use-flying-0.9.3
分支开始我们采用双向相关的方式构建 pojo,以求打造一个真实可用的电商前台,关于双向相关的详细信息请见: https://my.oschina.net/u/2280950/blog/1580056
以上API方法除最后一个外,其余均支持了二级缓存。您可以调用 updateRoleDirectlyWithoutCache
修改会员级别名称,之后调用 getRole
能看到新的名称,但调用 getCart
和 getCommodityByCart
则只能看到修改前的名称,这是因为 updateRoleDirectlyWithoutCache
设计为不支持二级缓存,从这里可以看出缓存确实发挥了作用;如果您调用 updateRoleDirectly
修改会员级别名称,在调用 getRole
、getCart
和 getCommodityByCart
都会显示出新的名称,因为 updateRoleDirectly
设计为支持二级缓存。如果再使用 redis 托管 mybatis 的二级缓存,就成为了可扩展的缓存解决方案,不过这已超过本例的讨论范围。
updateRoleDirectly
和 updateRoleDirectlyWithoutCache
都是普通 mybatis 方法而非 flying 自动映射方法,这个例子也说明改造 mybatis 二级缓存的插件可供 flying 自动映射方法和非 flying 自动映射方法同时工作。
最后,flying 项目介绍请见 flying-doc.limeng32.com ,我们为开发最好的 mybatis 插件而努力。
使用 mybatis + flying + 双向相关建模 的电商后端
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
使用 mybatis + flying + 双向相关建模 的电商后端的更多相关文章
- 使用 mybatis + flying-0.9.4 的电商后端
代码地址如下:http://www.demodashi.com/demo/12779.html mybatis.flying - 阳春 (Sunny-Spring) 项目介绍请见 flying-doc ...
- 基于SpringBoot+MyBatis实现一套电商系统
项目介绍 mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中心 ...
- SpringBoot+Security+MyBatis+ES+MQ+Redis+Docker+Vue的电商系统
今天鹏哥给大家推荐的项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现. 前台商城系统包含首页门户.商品推荐.商品搜索.商品展示.购物车.订单流程.会员中 ...
- 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01
猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念
一.前言 DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...
- 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文
阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...
- 如何一步一步用DDD设计一个电商网站(三)—— 初涉核心域
一.前言 结合我们本次系列的第一篇博文中提到的上下文映射图(传送门:如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念),得知我们这个电商网站的核心域就是销售子域.因为电子商务是以信息网络 ...
- 基于Hadoop技术实现的离线电商分析平台(Flume、Hadoop、Hbase、SpringMVC、highcharts)
离线数据分析平台是一种利用hadoop集群开发工具的一种方式,主要作用是帮助公司对网站的应用有一个比较好的了解.尤其是在电商.旅游.银行.证券.游戏等领域有非常广泛,因为这些领域对数据和用户的特性把握 ...
随机推荐
- hdu 4096 判断路径
思路:将每个关系当成一条有向边,查询时就判断之间存在路径. #include<iostream> #include<cstdio> #include<cstring> ...
- HDU 5253 最小生成树 kruscal
Description 老 Jack 有一片农田,以往几年都是靠天吃饭的.但是今年老天格外的不开眼,大旱.所以老 Jack 决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行 ...
- 洛谷P3045 [USACO12FEB]牛券Cow Coupons
P3045 [USACO12FEB]牛券Cow Coupons 71通过 248提交 题目提供者洛谷OnlineJudge 标签USACO2012云端 难度提高+/省选- 时空限制1s / 128MB ...
- favicon还是这个网站生成的比较正确
原文发布时间为:2011-11-16 -- 来源于本人的百度文章 [由搬家工具导入] http://tools.dynamicdrive.com/favicon/ http://www.rw-desi ...
- .net3.5下使用LINQ递归算法实现简洁代码
原文发布时间为:2011-04-24 -- 来源于本人的百度文章 [由搬家工具导入] http://www.cnblogs.com/wintersun/archive/2009/03/29/14243 ...
- EasySlider-最简洁的JQuery滚动插件 可控制滚动
原文发布时间为:2010-05-05 -- 来源于本人的百度文章 [由搬家工具导入] Easy Silder是由Alen Grakalic开发的基于JQuery的滚动插件,它支持以下功能: 1.自动滚 ...
- 用c#语言通过修改注册表改IE网页首页
原文发布时间为:2009-04-19 -- 来源于本人的百度文章 [由搬家工具导入] string key = @"HKEY_CURRENT_USER\Software\Microsoft\ ...
- The type or namespace name 'Html' does not exist in the namespace 'System.Web.Mvc' (are you missing an assembly reference?)
The type or namespace name 'Html' does not exist in the namespace 'System.Web.Mvc' (are you missing ...
- syslog/rsyslog的使用
syslogd是Linux下的一个记录日志文件服务.从结构来说,可以理解为这个服务下面有一系列的子服务,例如mail.auth.cron.kern等等,这些子服务对外提供日志记录的功能,而当其它的程序 ...
- springBoot 环境
环境约束 jdk1.8:Spring Boot 推荐jdk1.7及以上:maven3.x:maven 3.3以上版本:Apache Maven 3.3.9.IntelliJIDEA2017:Intel ...