【SpringBoot】电脑商城-09-默认收获地址和删除收货地址

默认收货地址

1 默认收货地址-持久层

1.1 规划需要执行的SQL语句

1.将某用户的所有收货地址设置为非默认地址(是否默认:0-不默认,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.检查该收货地址是否存在,并检查数据归属是否正确。可根据收货地址aid值,查询收货地址详情数据。

select * from t_address where aid=?
1.2 接口与抽象方法

在AddressMapper接口中声明三个抽象方法。

/**
 * 将某用户的所有收货地址设置为非默认地址
 * @param uid 收货地址归属的用户id
 * @return 受影响的行数
 */
Integer updateNonDefaultByUid(Integer uid);

/**
 * 将指定的收货地址设置为默认地址
 * @param aid 收货地址id
 * @param modifiedUser 修改执行人
 * @param modifiedTime 修改时间
 * @return 受影响的行数
 */
Integer updateDefaultByAid(
        @Param("aid") Integer aid,
        @Param("modifiedUser") String modifiedUser,
        @Param("modifiedTime") Date modifiedTime);

/**
 * 根据收货地址aid值,查询收货地址详情
 * @param aid 收货地址id
 * @return 匹配的收货地址详情,如果没有匹配的数据,则返回null
 */
Address findByAid(Integer aid);
1.3 配置SQL映射

1.在AddressMapper.xml映射文件,配置以上三个抽象方法的映射。

<!-- 将某用户的所有收货地址设置为非默认地址:Integer updateNonDefaultByUid(Integer uid) -->
<update id="updateNonDefaultByUid">
    UPDATE
    	t_address
    SET
    	is_default=0
    WHERE
    	uid=#{uid}
</update>

<!-- 将指定的收货地址设置为默认地址:
         Integer updateDefaultByAid(
            @Param("aid") Integer aid,
            @Param("modifiedUser") String modifiedUser,
            @Param("modifiedTime") Date modifiedTime) -->
<update id="updateDefaultByAid">
    UPDATE
    	t_address
    SET
        is_default=1,
        modified_user=#{modifiedUser},
        modified_time=#{modifiedTime}
    WHERE
    	aid=#{aid}
</update>

<!-- 根据收货地址aid值,查询收货地址详情:Address findByAid(Integer aid) -->
<select id="findByAid" resultMap="AddressEntityMap">
    SELECT
    	*
    FROM
    	t_address
    WHERE
    	aid=#{aid}
</select>

2.在AddressMapperTests类中编写并执行以上三个抽象方法的测试。

@Test
public void updateNonDefaultByUid() {
    Integer uid = 26;
    Integer rows = addressMapper.updateNonDefaultByUid(uid);
    System.out.println("rows=" + rows);
}

@Test
public void updateDefaultByAid() {
    Integer aid = 11;
    String modifiedUser = "管理员";
    Date modifiedTime = new Date();
    Integer rows = addressMapper.updateDefaultByAid(aid, modifiedUser, modifiedTime);
    System.out.println("rows=" + rows);
}

@Test
public void findByAid() {
    Integer aid = 11;
    Address result = addressMapper.findByAid(aid);
    System.out.println(result);
}

2 默认收货地址-业务层

2.1 规划异常

1.在执行设置默认收货地址之前,需要先检查该收货地址数据是否存在,如果不存在则抛出AddressNotFoundException异常。

2.然后还需要检查数据归属是否正确,也就是不可以操作他人的数据,如果该数据中记录的uid与当前登录的用户的uid不一致,则抛出AccessDeniedException异常。

3.检查通过后先全部设置为非默认,然后将指定的收货地址设置为默认;这两种操作都是更新数据的操作,则可能抛出UpdateException异常。

4.在com.cy.store.service.ex包下创建AddressNotFoundException和AccessDeniedException异常类。

package com.cy.store.service.ex;

/** 收货地址数据不存在的异常 */
public class AddressNotFoundException extends ServiceException {
    // Override Methods...
}
package com.cy.store.service.ex;

/** 非法访问的异常 */
public class AccessDeniedException extends ServiceException {
    // Override Methods...
}
2.2 接口与抽象方法

在IAddressService接口中添加setDefault(Integer aid, Integer uid, String username)抽象方法。

/**
 * 设置默认收货地址
 * @param aid 收货地址id
 * @param uid 归属的用户id
 * @param username 当前登录的用户名
 */
void setDefault(Integer aid, Integer uid, String username);
2.3 实现抽象方法

1.在AddressServiceImpl类中重写setDefault(Integer aid, Integer uid, String username)方法。该方法需要添加@Transactional注解。

事务:基于Spring JDBC的事务(Transaction)处理,使用事务可以保证一系列的增删改操作,要么全部执行成功,要么全部执行失败。@Transactional注解可以用来修饰类也可以用来修饰方法。如果添加在业务类之前,则该业务类中的方法均以事务的机制运行,但是一般并不推荐这样处理。

@Transactional
@Override
public void setDefault(Integer aid, Integer uid, String username) {
	// 根据参数aid,调用addressMapper中的findByAid()查询收货地址数据
	// 判断查询结果是否为null
	// 是:抛出AddressNotFoundException

	// 判断查询结果中的uid与参数uid是否不一致(使用equals()判断)
	// 是:抛出AccessDeniedException:非法访问

	// 调用addressMapepr的updateNonDefaultByUid()将该用户的所有收货地址全部设置为非默认,并获取返回的受影响的行数
	// 判断受影响的行数是否小于1(不大于0)
	// 是:抛出UpdateException

	// 调用addressMapepr的updateDefaultByAid()将指定aid的收货地址设置为默认,并获取返回的受影响的行数
	// 判断受影响的行数是否不为1
	// 是:抛出UpdateException
}

2.setDefault(Integer aid, Integer uid, String username)方法的具体代码实现。

@Transactional
@Override
public void setDefault(Integer aid, Integer uid, String username) {
    // 根据参数aid,调用addressMapper中的findByAid()查询收货地址数据
    Address result = addressMapper.findByAid(aid);
    // 判断查询结果是否为null
    if (result == null) {
        // 是:抛出AddressNotFoundException
        throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
    }

    // 判断查询结果中的uid与参数uid是否不一致(使用equals()判断)
    if (!result.getUid().equals(uid)) {
        // 是:抛出AccessDeniedException
        throw new AccessDeniedException("非法访问的异常");
    }

    // 调用addressMapper的updateNonDefaultByUid()将该用户的所有收货地址全部设置为非默认,并获取返回受影响的行数
    Integer rows = addressMapper.updateNonDefaultByUid(uid);
    // 判断受影响的行数是否小于1(不大于0)
    if (rows < 1) {
        // 是:抛出UpdateException
        throw new UpdateException("设置默认收货地址时出现未知错误[1]");
    }

    // 调用addressMapper的updateDefaultByAid()将指定aid的收货地址设置为默认,并获取返回的受影响的行数
    rows = addressMapper.updateDefaultByAid(aid, username, new Date());
    // 判断受影响的行数是否不为1
    if (rows != 1) {
        // 是:抛出UpdateException
        throw new UpdateException("设置默认收货地址时出现未知错误[2]");
    }
}

3.在AddressServiceTests测试类,编写并执行单元测试。

@Test
public void setDefault() {
    try {
        Integer aid = 13;
        Integer uid = 27;
        String username = "系统管理员";
        addressService.setDefault(aid, uid, username);
        System.out.println("OK.");
    } catch (ServiceException e) {
        System.out.println(e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}

3 默认收货地址-控制器

3.1 处理异常

在BaseController类中添加处理AddressNotFoundException和AccessDeniedException的异常。

// ...
else if (e instanceof AddressNotFoundException) {
    result.setState(4004);
} else if (e instanceof AccessDeniedException) {
    result.setState(4005);
}
// ...
3.2 设计请求

设计用户提交的请求,并设计响应的方式。

请求路径:/addresses/{aid}/set_default
请求参数:@PathVaraible("aid") Integer aid, HttpSession sesion
请求类型:POST
响应结果:JsonResult<Void>

REST即表述性状态传递(Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

3.3 处理请求

1.在AddressController类中添加处理请求的setDefault(@PathVariable(“aid”) Integer aid, HttpSession session)方法。

@RequestMapping("{aid}/set_default")
public JsonResult<Void> setDefault(@PathVariable("aid") Integer aid, HttpSession session) {
    Integer uid = getUidFromSession(session);
    String username = getUsernameFromSession(session);
    addressService.setDefault(aid, uid, username);
    return new JsonResult<Void>(OK);
}

2.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/addresses/13/set_default进行测试。
在这里插入图片描述

4 默认收货地址-前端页面

1.在address.html页面中body标签内部的script标签内,添加设置用户默认收货地址的代码。

function setDefault(aid) {
    $.ajax({
        url: "/addresses/" + aid + "/set_default",
        type: "POST",
        dataType: "JSON",
        success: function(json) {
            if (json.state == 200) {
                showAddressList();
            } else {
                alert("设置默认收货地址失败!" + json.message);
            }
        },
        error: function(xhr) {
            alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
            location.href = "login.html";
        }
    });
}

2.给showAddressList()方法中的“设为默认”超链接按钮添加设置默认收货地址的点击事件。

<td><a onclick="setDefault(#{aid})" class="btn btn-xs add-def btn-default">设为默认</a></td>

3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/web/address.html页面,点击“设为默认”超链接按钮进行功能测试。

删除收货地址

1 删除收货地址-持久层

1.1 规划需要执行的SQL语句

1.在删除之前,需检查数据是否存在,数据归属是否正确。此功能已完成,无需再次开发。

2.删除指定的收货地址的SQL语句大致是。

delete from t_address where aid=?

3.如果删除的这条数据是默认收货地址,则应该将剩余的收货地址中的某一条设置为默认收货地址,可以设定规则“将最近修改的设置为默认收货地址”,要实现此功能就必须要知道“最近修改的收货地址的id是多少”。则通过以下查询语句完成。

select * from t_address where uid=? order by modified_time desc limit 0,1

4.在执行以上操作之前,还需检查该用户的收货地址数据的数量,如果删除的收货地址是最后一条收货地址,则删除成功后无需再执行其他操作。统计收货地址数量的功能此前已经完成,无需再次开发。

1.2 接口与抽象方法

在AddressMapper接口中添加抽象方法。

/**
 * 根据收货地址id删除数据
 * @param aid 收货地址id
 * @return 受影响的行数
 */
Integer deleteByAid(Integer aid);

/**
 * 查询某用户最后修改的收货地址
 * @param uid 归属的用户id
 * @return 该用户最后修改的收货地址,如果该用户没有收货地址数据则返回null
 */
Address findLastModified(Integer uid);
1.3 配置SQL映射

1.在AddressMapper.xml文件中添加以上两个抽象方法的映射。

<!-- 根据收货地址id删除数据:Integer deleteByAid(Integer aid) -->
<delete id="deleteByAid">
    DELETE FROM
        t_address
    WHERE
        aid=#{aid}
</delete>

<!-- 查询某用户最后修改的收货地址:Address findLastModified(Integer uid) -->
<select id="findLastModified" resultMap="AddressEntityMap">
    SELECT
        *
    FROM
        t_address
    WHERE
        uid=#{uid}
    ORDER BY
        modified_time DESC
        LIMIT 0,1
</select>

2.在AddressMapperTests测试类中添加单元测试方法。

@Test
public void deleteByAid() {
    Integer aid = 4;
    Integer rows = addressMapper.deleteByAid(aid);
    System.out.println("rows=" + rows);
}

@Test
public void findLastModified() {
    Integer uid = 30;
    Address result = addressMapper.findLastModified(uid);
    System.out.println(result);
}

2 删除收货地址-业务层

2.1 规划异常

在执行删除操作时,可能会删除数据失败,此时抛出DeleteException异常。在创建com.cy.store.service.ex.DeleteException异常类,并继承自ServiceException类。

package com.cy.store.service.ex;

/** 删除数据失败的异常 */
public class DeleteException extends ServiceException {
    // Override Methods...
}
2.2 接口与抽象方法

在IAddressService接口中添加删除收货地址的抽象方法。

/**
 * 删除收货地址
 * @param aid 收货地址id
 * @param uid 归属的用户id
 * @param username 当前登录的用户名
 */
void delete(Integer aid, Integer uid, String username);
2.3 实现抽象方法

1.在AddressServiceImpl实现类中实现以上两个抽象方法。

@Transactional
@Override
public void delete(Integer aid, Integer uid, String username) {
    // 根据参数aid,调用findByAid()查询收货地址数据
    Address result = addressMapper.findByAid(aid);
    // 判断查询结果是否为null
    if (result == null) {
        // 是:抛出AddressNotFoundException
        throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
    }

    // 判断查询结果中的uid与参数uid是否不一致(使用equals()判断)
    if (!result.getUid().equals(uid)) {
        // 是:抛出AccessDeniedException:非法访问
        throw new AccessDeniedException("非常访问");
    }

    // 根据参数aid,调用deleteByAid()执行删除
    Integer rows1 = addressMapper.deleteByAid(aid);
    if (rows1 != 1) {
        throw new DeleteException("删除收货地址数据时出现未知错误,请联系系统管理员");
    }

    // 判断查询结果中的isDefault是否为0
    if (result.getIsDefault() == 0) {
        return;
    }

    // 调用持久层的countByUid()统计目前还有多少收货地址
    Integer count = addressMapper.countByUid(uid);
    // 判断目前的收货地址的数量是否为0
    if (count == 0) {
        return;
    }

    // 调用findLastModified()找出用户最近修改的收货地址数据
    Address lastModified = addressMapper.findLastModified(uid);
    // 从以上查询结果中找出aid属性值
    Integer lastModifiedAid = lastModified.getAid();
    // 调用持久层的updateDefaultByAid()方法执行设置默认收货地址,并获取返回的受影响的行数
    Integer rows2 = addressMapper.updateDefaultByAid(lastModifiedAid, username, new Date());
    // 判断受影响的行数是否不为1
    if (rows2 != 1) {
        // 是:抛出UpdateException
        throw new UpdateException("更新收货地址数据时出现未知错误,请联系系统管理员");
    }
}

2.在AddressServiceTests测试类中添加单元测试方法。

@Test
public void delete() {
    try {
        Integer aid = 18;
        Integer uid = 30;
        String username = "明明";
        addressService.delete(aid, uid, username);
        System.out.println("OK.");
    } catch (ServiceException e) {
        System.out.println(e.getClass().getSimpleName());
        System.out.println(e.getMessage());
    }
}

3 删除收货地址-控制器

3.1 处理异常

在BaseController类中添加DeleteException异常的处理。

// ...
else if (e instanceof DeleteException) {
    result.setState(5002);
}
// ...
3.2 设计请求

设计用户提交的请求,并设计响应的方式。

请求路径:/addresses/{aid}/delete
请求参数:@PathVariable("aid") Integer aid, HttpSession session
请求类型:POST
响应结果:JsonResult<Void>
3.3 处理请求

1.在AddressController类中添加处理请求的delete()方法。

@RequestMapping("{aid}/delete")
public JsonResult<Void> delete(@PathVariable("aid") Integer aid, HttpSession session) {
    Integer uid = getUidFromSession(session);
    String username = getUsernameFromSession(session);
    addressService.delete(aid, uid, username);
    return new JsonResult<Void>(OK);
}

2.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/addresses/26/delete进行测试。

4 删除收货地址-前端页面

1.在address.html页面中body标签内部的script标签内,添加设置用户删除收货地址的代码。

function deleteByAid(aid) {
    $.ajax({
        url: "/addresses/" + aid + "/delete",
        type: "POST",
        dataType: "JSON",
        success: function(json) {
            if (json.state == 200) {
                showAddressList();
            } else {
                alert("删除收货地址失败!" + json.message);
            }
        },
        error: function(json) {
            alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + json.status);
            location.href = "login.html";
        }
    });
}

2.给showAddressList()方法中的“设为默认”超链接按钮添加设置默认收货地址的点击事件。

<td>
	<a onclick="deleteByAid(#{aid})" class="btn btn-xs add-del btn-info">
		<span class="fa fa-trash-o"></span> 删除
	</a>
</td>

3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/web/address.html页面,点击“删除”超链接按钮进行功能测试。
在这里插入图片描述

本期到这就结束了,点一下关注再走吧!!关注一波不迷路!!

分享不易,耗时耗力,麻烦给个不要钱的关注和赞吧
承接毕设指导,技术答疑,学习路上缺少导师的同学可以私信我
更多学习资料,公众号:墨轩学习网,B站:墨轩大楼
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听潮阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>