Project(10)——收货地址 - 设置默认
Project(10)——收货地址 - 设置默认
1、分析项目
当需要开发某个项目时,首先,应该分析这个项目中,需要处理哪些种类的数据!例如:用户、商品、商品类别、收藏、订单、购物车、收货地址…
然后,将以上这些种类的数据的处理排个顺序,即先处理哪种数据,后处理哪种数据!通常,应该先处理基础数据,再处理所相关的数据,例如需要先处理商品数据,才可以处理订单数据,如果多种数据之间没有明显的关联,则应该先处理简单的,再处理较难的!
则以上这些数据的处理顺序应该是:用户 > 收货地址 > 商品类别 > 商品 > 收藏 > 购物车 > 订单
当确定了数据处理顺序后,就应该分析某个用户对应的功能有哪些,以“用户”数据为例,相关功能有:注册、登录、修改密码、修改资料、上传头像…
然后,还是需要确定以上功能的开发顺序,通常,遵循 “增 > 查 > 删 > 改” 的顺序,则以上功能的开发顺序应该是:注册 > 登录 > 修改密码 > 修改资料 > 上传头像。
每个功能的开发都应该遵循 创建数据表 > 创建实体类 > 持久层 > 业务层 > 控制器层 > 前端页面
一次只解决一个问题
大问题拆成小问题
2、用户 - 注册 - 创建数据表
3、用户 - 注册 - 创建实体类
4、用户 - 注册 - 持久层
a.规划SQL语句
b.接口与抽象方法
c.配置映射
5、用户 - 注册 - 业务层
业务层的基本定位
a.规划异常
b.接口与抽象方法
c.实现类与重写方法
6、用户 - 注册 - 控制器层
a.处理异常
b.设计请求
c.处理请求
7、用户 - 注册 - 前端页面
……
收货地址 - 分析
关于收货地址的管理,涉及的功能有:增加,查看列表,修改,删除,设为默认。
以上功能的开发顺序应该是:增加 > 查看列表 > 设为默认 > 删除 > 修改。
…
…
37、收货地址 - 查看列表 - 持久层
a.规划SQL语句
b.接口与抽象方法
c.配置映射
38、收货地址 - 查看列表 - 业务层
a.规划异常
b.接口与抽象方法
c.实现类与重写方法
39、收货地址 - 查看列表 - 控制器层
a.处理异常
b.设计请求
c.处理请求
40、收货地址 - 查看列表 - 前端页面
41、收货地址 - 设置默认 - 持久层
a.规划SQL语句
如果要将某收货地址设置为默认,SQL语句大致是:
UPDATE t_address
SET is_default = 1, modified_user = ?, modified_time = ?
WHERE aid = ?
在把某收货地址设为默认之前,应该把原来的默认地址设为非默认,可以选择把所有的收货地址设置为非默认:
UPDATEt_address
SETis_default = 0
WHEREuid = ?
另外,在设置默认之前,还应该检查该收货地址数据是否存在,可通过简单的查询来实现:
SELECT*
FROMt_address
WHEREaid = ?
并且,除了检查数据是否存在以外,还应该检查数据的归属是否正确,即该 aid
对应的数据是不是当前登录的用户的数据,则查询时,应该查询 uid
字段,与用户登录后 session
中的 uid
进行对比,以判断数据归属,则查询需要调整为:
SELECTuid
FROMt_address
WHEREaid = ?
总结:
// 共三条 sql 语句
// 1、将所有地址设为非默认
UPDATE t_address SET is_default=0 WHERE uid=?
// 2、将指定地址设为默认
UPDATE t_address SET is_default=1, modified_user=?, modified_time=? WHERE aid=?
// 3、查询收货地址是否存在
SELECT uid FROM t_address WHERE aid=?
b.接口与抽象方法
/*** 将所有地址设为非默认* @param uid 用户 uid* @return 受影响的行数*/Integer updateNonDefault(Integer uid);/*** 将指定地址设为默认* @param aid 指定的地址 id* @return 受影响的行数*/Integer updateDefault(@Param("aid") Integer aid, @Param("modifiedUser") String modifiedUser, @Param("modifiedTime") Date modifiedTime);/*** 根据 aid 查询地址信息* @param aid 要查询的地址的id* @return 查询到的地址信息*/Address findByAid(Integer aid);
c.配置映射
<!-- 将所有地址设置为非默认 --><!-- Integer updateNonDefault(Integer uid) --><update id="updateNonDefault">UPDATEt_addressSETis_default=0WHEREuid=#{uid}</update><!-- 将指定地址设置为默认 --><!-- Integer updateDefault(Integer aid) --><update id="updateDefault">UPDATEt_addressSETis_default=1, modified_user=#{modifiedUser}, modified_time=#{modifiedTime}WHEREaid=#{aid}</update><!-- 根据收货地址 aid 查询收货地址信息 --><!-- Address findByAid(Integer aid) --><select id="findByAid" resultType="cn.tedu.store.entity.Address">SELECTuidFROMt_addressWHEREaid=#{aid}</select>
编写并执行单元测试:
/*** 测试将所有地址设为非默认*/@Testpublic void testUpdateNonDefault() {Integer uid = 7;Integer rows = addressMapper.updateNonDefault(uid);System.err.println("rows = " + rows);}/*** 测试将指定地址设为默认*/@Testpublic void testUpdateDefault() {Integer aid = 1;String modifiedUser = "酒厂管理员";Date modifiedTime = new Date();Integer rows = addressMapper.updateDefault(aid, modifiedUser, modifiedTime);System.err.println("rows = " + rows);}/*** 测试根据 aid 查询 地址信息*/@Testpublic void testFindByAid() {Integer aid = 1;Address address = addressMapper.findByAid(aid);System.err.println("address.uid = " + address.getUid());}
42、收货地址 - 设置默认 - 业务层
a.规划异常
此次操作的流程大致是:先检查收货地址数据是否存在,再检查数据归属是否正确,然后再执行修改操作。
检查数据是否存在时,可能抛出:AddressNotFoundException
;
检查数据归属是否正确时,可能抛出:AccessDeniedException
;
执行修改操作时,可能抛出:UpdateException
。
所以,需要事先创建原本不存在的异常类AddressNotFoundException
和AccessDeniedException
。
b.接口与抽象方法
在IAddressService
接口中添加抽象方法:
/*** 设置默认收货地址* @param aid 地址 aid* @param uid 用户 uid* @param username 用户名* @throws AddressNotFoundException 地址不存在异常* @throws AccessDeniedException 访问被拒绝异常* @throws UpdateException 更新失败异常*/void setDefault(Integer aid, Integer uid, String username) throws AddressNotFoundException, AccessDeniedException, UpdateException;
c.实现类与重写方法
首先,将持久层的 3个新增方法复制到AddressServiceImpl
业务层实现类中:
Integer updateNonDefault(Integer uid);Integer updateDefault(Integer aid, String modifiedUser, Date modifiedTime);Address findByAid(Integer aid);
未实现的方法是报错的,先私有化实现:
/*** 设置所有地址为非默认* @param uid 用户 uid*/private void updateNonDefault(Integer uid) {Integer rows = addressMapper.updateNonDefault(uid);if(rows == 0) {throw new UpdateException("修改默认地址失败!出现未知错误,请联系系统管理员!");}}/*** 设置指定地址为默认* @param aid 指定地址 aid* @param modifiedUser 修改人* @param modifiedTime 修改时间*/private void updateDefault(Integer aid, String modifiedUser, Date modifiedTime) {Integer rows = addressMapper.updateDefault(aid, modifiedUser, modifiedTime);if(rows != 1) {throw new UpdateException("修改默认地址失败!出现未知错误,请联系系统管理员!");}}/*** 根据地址 aid 查询地址信息* @param aid 地址 aid* @return 查询到的地址信息*/private Address findByAid(Integer aid) {return addressMapper.findByAid(aid);}
然后,重写接口中定义的抽象方法:
在方法前添加@Transactional
注解:
/*** 设置默认地址*/@Override@Transactionalpublic void setDefault(Integer aid, Integer uid, String username)throws AddressNotFoundException, AccessDeniedException, UpdateException {// 根据 aid 查询地址数据是否存在// 不存在 -- 抛出地址不存在异常// 判断查询结果的 uid 与 参数 uid 是否一致// 不一致 -- 抛出访问被拒绝异常// 将用户所有地址设为非默认// 将指定地址设为默认}
具体实现:
/*** 设置默认地址*/@Override@Transactionalpublic void setDefault(Integer aid, Integer uid, String username)throws AddressNotFoundException, AccessDeniedException, UpdateException {// 根据 aid 查询地址数据是否存在// 不存在 -- 抛出地址不存在异常// 判断查询结果的 uid 与 参数 uid 是否一致// 不一致 -- 抛出访问被拒绝异常Address result = findByAid(aid);if(result == null) {throw new AddressNotFoundException("修改默认地址失败!该地址数据不存在!");}if(result.getUid() != uid) {throw new AccessDeniedException("修改默认地址失败!访问被拒绝!不允许访问他人数据!");}// 将用户所有地址设为非默认updateNonDefault(uid);// 将指定地址设为默认Date now = new Date();updateDefault(aid, username, now);}
编写并执行单元测试:
/*** 测试设置地址为默认*/@Testpublic void testSetDefault() {try {Integer aid = 2;Integer uid = 7;String username = "Gin";service.setDefault(aid, uid, username);System.err.println("OK");}catch(ServiceException e) {System.err.println(e.getClass().getName());System.err.println(e.getMessage());}}
43、收货地址 - 设置默认 - 控制器层
a.处理异常
需要处理AddressNotFoundException
和AccessDeniedException
b.设计请求
请求路径:/addresses/{aid}/set_default
请求参数:@PathVariable("aid") Integer aid, HttpSession session
请求类型:POST
响应数据:JsonResult<Void>RESTful:一种 url 的设计风格
建议风格:/resources/id/command
c.处理请求
/*** 设置默认地址* @param aid 地址 aid* @param session 用于获取 uid、username* @return*/@RequestMapping("/{aid}/set_default")public JsonResult<Void> setDefault(@PathVariable("aid") Integer aid,HttpSession session){// 从 session 中获取 uid,usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 调用业务层方法执行设置默认地址service.setDefault(aid, uid, username);// 响应return new JsonResult<Void>(SUCCESS);}
44、收货地址 - 设置默认 - 前端页面
在address.html
中,在 设为默认
的选项框中添加 onclick
属性:
然后再添加新的 function setDefault(aid){}
:
先写入 alert(aid)
,登陆后进行测试:
function setDefault(aid){alert(aid);
}
测试成功后,在function setDefault(aid){}
中添加执行逻辑:
<script type="text/javascript">
$(document).ready(function(){showAddressList();
});function showAddressList(){$.ajax({..................});
}function setDefault(aid){$.ajax({"url" : "/addresses/" + aid + "/set_default","type" : "post","dataType" : "json","success" : function(json){if(json.state == 2000){showAddressList();}else{alert("json.message");}},"error" : function(){alert("您的登录信息已过期!请重新登录!");}});
}</script>
---------------------------------------------------------------------------
附1:基于Spring-JDBC的事务(Transaction)
首先,事务是用于保障数据安全的,可以使得一系列的增删改操作,要么全部成功,要么全部失败!
什么情况下需要使用事务: 当某个业务涉及 2 次或更多次的增、删、改操作时,必须使用事务!例如执行 2 条Update语句,或1条 Insert 语句和 1 条 Update 语句等。
如何使用事务: 基于Spring-JDBC的编程中,只需要在业务方法之前添加@Transactional
注解即可。
框架在处理事务时,大致的处理过程是:
开启事务:begintry{执行各任务提交:commit} catch(RuntimeException) {回滚:rollback}
所以,为了保证@Transactional
注解能够正常保障事务,在每次的增、删、改操作执行完成后,都必须判断受影响的行数是否是预期值,如果不是预期值,必须抛出RuntimeException
或其某个子孙类的异常!
另外,@Transactional
注解还可以添加在业务类之前,表示该类中所有的方法在执行时,都是有事务保障的!通常并不推荐这样处理!
@Override@Transactionalpublic void setDefault(Integer aid, Integer uid, String username)throws AddressNotFoundException, AccessDeniedException, UpdateException {// 根据 aid 查询地址数据是否存在// 不存在 -- 抛出地址不存在异常// 判断查询结果的 uid 与 参数 uid 是否一致// 不一致 -- 抛出访问被拒绝异常// Address result = addressMapper.findByAid(aid);// if(result == null) {// throw new AddressNotFoundException("修改默认地址失败!该地址数据不存在!");// }// if(result.getUid() != uid) {// throw new AccessDeniedException("修改默认地址失败!访问被拒绝!不允许访问他人的数据!");// }// 将用户所有地址设为非默认updateNonDefault(uid);// 将指定地址设为默认Date now = new Date();updateDefault(aid, username, now);}
Project(10)——收货地址 - 设置默认相关推荐
- 收货地址 - 设置默认收货地址
/*** 修改默认地址* @param userId* @param addressId*/ public void updateUserAddressToBeDefault(String userI ...
- ionic4.x仿京东 - 10.3.4.收货地址-修改默认收货地址、显示默认收货地址
一.修改默认收货地址 1.接口信息 请求方式:post 地址:域名/api/changeDefaultAddress 传参说明: 参数 说明 备注 uid 用户 id 必传 sign 签名 验证地址是 ...
- 收货地址 (默认收货地址)
个人笔记 class DefaultAddress(APIView):"""设置默认地址"""def post(self,request): ...
- 设置默认收货地址【项目 商城】
设置默认收货地址[项目 商城] 设置默认收货地址 1. 持久层 1.1 规划SQL语句 1.2 设计抽象方法 1.3 配置SQL映射 测试 2.业务层 2.1 异常规划 2.2 抽象方法 2.3 实现 ...
- SpringBoot电脑商城-收货地址
收货地址 1. 新增收获地址 1.1 数据库表创建 1.2 创建实体类 1.3 持久层 1.4 业务层 1.5 控制层 1.6 前端页面 2. 获取省市区列表 2.1 数据库表 2.2 实体类 2.3 ...
- 完整电商项目--(五)用户基本信息(2):收货地址
业务分析(纯业务逻辑分析,增删改查我们就不讲代码实现,主要是学习电商设计) 这一部分可以参考一般的电商网站做 class Address(BaseModel):"""用户 ...
- UNIAPP实战项目笔记43 购物车页面修改收货地址和修改默认地址
UNIAPP实战项目笔记43 购物车页面修改收货地址和修改默认地址 实际案例图片 修改收货地址和修改默认地址页面布局和功能 具体内容图片自己替换哈,随便找了个图片的做示例 用到了vuex的状态机,具体 ...
- html收货地址填写怎么做才合理_拼多多发货地不在同一个地方有影响吗?怎么设置发货地址?...
卖家在拼多多开店之后,需要对商品进行基本设置.其中就涉及到了发货地址,卖家需要把发货的地址设置好,但是有的卖家有不同的发货地址,那么拼多多发货地不在同一个地方有影响吗? 拼多多发货地不在同一个地方是有 ...
- html收货地址填写怎么做才合理_匀思电商:拼多多卖家设置发货地址有哪些注意事项?...
拼多多卖家在开店之后,需要对店铺的商品进行各种基本设置,比如设置发货地址,卖家会遇到自己有好几个不同的发货地址需要怎么设置呢?不同的发货地址对拼多多店铺有影响那?今天匀思电商拼多多网店培训小编就来给大 ...
- 移动商城第五篇(用户模块)【用户登陆、回显用户、拦截器、收货地址】
移动商城[用户登陆.回显用户] 我们来实现用户登陆的功能: 当点击的时候,出来的是一个弹出框,我们想要切换成一个页面. 找到对应的事件.切换成我们的页面就行了. $("#loginAlert ...
最新文章
- 如何手动卸载 SQL Server 2005 实例(官方)
- 求最小生成树-Prim(普里姆算法)
- python图书管理系统增删改查_python基础-字典的增删改查
- python界面编程和网口通信_Python—网络通信编程之tcp通信编程
- RK3399Pro Android Rock-X 人工智能开发系列(2)
- 华为牛人在华为工作十年的感悟!--总结[华为的10年工作]
- VMware Workstation 常见问题解决
- UVA12657 Boxes in a Line【模拟】
- 高性能MySQL系统思维导图
- 无线路由器网络测试软件,如何简单快速测试家里无线路由器的网速和性能?
- 新宝美股三大指数集体高开
- 发生异常: ModuleNotFoundError No module named ‘XXXX‘可优先尝试的解决方式
- oracle8ora-00059,ORA-00059错误分析以及MAXDATAFILES、DB_FILES参数修改
- python打印列表元素_Python打印输出数组中全部元素
- English--元音
- 欧文计算机科学排名,加州大学欧文分校计算机科学世界排名2019年最新排名第55(THE世界排名)...
- [强化学习-3] Devil 课程第二章解析+ 学生马尔可夫决策过程代码
- 计算机视觉小白入门第一问——什么是计算机视觉
- C++-生日-星座-性格查询
- 目标检测常用评价指标笔记