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
所以,需要事先创建原本不存在的异常类AddressNotFoundExceptionAccessDeniedException

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.处理异常

需要处理AddressNotFoundExceptionAccessDeniedException

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)——收货地址 - 设置默认相关推荐

  1. 收货地址 - 设置默认收货地址

    /*** 修改默认地址* @param userId* @param addressId*/ public void updateUserAddressToBeDefault(String userI ...

  2. ionic4.x仿京东 - 10.3.4.收货地址-修改默认收货地址、显示默认收货地址

    一.修改默认收货地址 1.接口信息 请求方式:post 地址:域名/api/changeDefaultAddress 传参说明: 参数 说明 备注 uid 用户 id 必传 sign 签名 验证地址是 ...

  3. 收货地址 (默认收货地址)

    个人笔记 class DefaultAddress(APIView):"""设置默认地址"""def post(self,request): ...

  4. 设置默认收货地址【项目 商城】

    设置默认收货地址[项目 商城] 设置默认收货地址 1. 持久层 1.1 规划SQL语句 1.2 设计抽象方法 1.3 配置SQL映射 测试 2.业务层 2.1 异常规划 2.2 抽象方法 2.3 实现 ...

  5. SpringBoot电脑商城-收货地址

    收货地址 1. 新增收获地址 1.1 数据库表创建 1.2 创建实体类 1.3 持久层 1.4 业务层 1.5 控制层 1.6 前端页面 2. 获取省市区列表 2.1 数据库表 2.2 实体类 2.3 ...

  6. 完整电商项目--(五)用户基本信息(2):收货地址

    业务分析(纯业务逻辑分析,增删改查我们就不讲代码实现,主要是学习电商设计) 这一部分可以参考一般的电商网站做 class Address(BaseModel):"""用户 ...

  7. UNIAPP实战项目笔记43 购物车页面修改收货地址和修改默认地址

    UNIAPP实战项目笔记43 购物车页面修改收货地址和修改默认地址 实际案例图片 修改收货地址和修改默认地址页面布局和功能 具体内容图片自己替换哈,随便找了个图片的做示例 用到了vuex的状态机,具体 ...

  8. html收货地址填写怎么做才合理_拼多多发货地不在同一个地方有影响吗?怎么设置发货地址?...

    卖家在拼多多开店之后,需要对商品进行基本设置.其中就涉及到了发货地址,卖家需要把发货的地址设置好,但是有的卖家有不同的发货地址,那么拼多多发货地不在同一个地方有影响吗? 拼多多发货地不在同一个地方是有 ...

  9. html收货地址填写怎么做才合理_匀思电商:拼多多卖家设置发货地址有哪些注意事项?...

    拼多多卖家在开店之后,需要对店铺的商品进行各种基本设置,比如设置发货地址,卖家会遇到自己有好几个不同的发货地址需要怎么设置呢?不同的发货地址对拼多多店铺有影响那?今天匀思电商拼多多网店培训小编就来给大 ...

  10. 移动商城第五篇(用户模块)【用户登陆、回显用户、拦截器、收货地址】

    移动商城[用户登陆.回显用户] 我们来实现用户登陆的功能: 当点击的时候,出来的是一个弹出框,我们想要切换成一个页面. 找到对应的事件.切换成我们的页面就行了. $("#loginAlert ...

最新文章

  1. 如何手动卸载 SQL Server 2005 实例(官方)
  2. 求最小生成树-Prim(普里姆算法)
  3. python图书管理系统增删改查_python基础-字典的增删改查
  4. python界面编程和网口通信_Python—网络通信编程之tcp通信编程
  5. RK3399Pro Android Rock-X 人工智能开发系列(2)
  6. 华为牛人在华为工作十年的感悟!--总结[华为的10年工作]
  7. VMware Workstation 常见问题解决
  8. UVA12657 Boxes in a Line【模拟】
  9. 高性能MySQL系统思维导图
  10. 无线路由器网络测试软件,如何简单快速测试家里无线路由器的网速和性能?
  11. 新宝美股三大指数集体高开
  12. 发生异常: ModuleNotFoundError No module named ‘XXXX‘可优先尝试的解决方式
  13. oracle8ora-00059,ORA-00059错误分析以及MAXDATAFILES、DB_FILES参数修改
  14. python打印列表元素_Python打印输出数组中全部元素
  15. English--元音
  16. 欧文计算机科学排名,加州大学欧文分校计算机科学世界排名2019年最新排名第55(THE世界排名)...
  17. [强化学习-3] Devil 课程第二章解析+ 学生马尔可夫决策过程代码
  18. 计算机视觉小白入门第一问——什么是计算机视觉
  19. C++-生日-星座-性格查询
  20. 目标检测常用评价指标笔记

热门文章

  1. 桌面好看的linux系统,可以当桌面的LINUX漂亮壁纸
  2. 最适合程序员的画图工具?
  3. 海量数据检索 - “ElasticSearch”
  4. aistudio下载文件避免报错
  5. 用Tornado实现web聊天室(前端采用vue+bootstrap)
  6. 龙威ol服务器维护,《龙威OL》搅屎棍职业技能攻略详解
  7. java读取文件效率优化_java 读文件 性能
  8. 量子计算机与仿生论文,有关量子力学的论文
  9. 电脑围棋中的人工智能技术
  10. Data URL 基本介绍