
🧸安清h:个人主页****
🎥个人专栏:【Spring篇】** 【计算机网络】 【Mybatis篇】**
**🚦作者简介:**一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。

目录
[🚀设置默认收货地址- 持久层](#🚀设置默认收货地址- 持久层)
[🚀设置默认收货地址- 业务层](#🚀设置默认收货地址- 业务层)
[🚀设置默认收货地址- 控制层](#🚀设置默认收货地址- 控制层)
[🚀设置默认收货地址- 前端页面](#🚀设置默认收货地址- 前端页面)
🚀设置默认收货地址- 持久层
✨1.1规划SQL语句
1.检测当前用户想设置为默认收货地址的这条数据是否存在。
sql
select * from t_address where aid=?
2.在修改 用户的默认地址之前,先将所有的收货地址设置为非默认。
sql
update t_address set is_default=0 where uid=?
3.将用户当前选中的这条记录设置为默认的收货地址。
sql
update t_address set is_default=1,modified_user=?,modified_time=? where aid=?
✨1.2设计抽象方法
在AddressMapper接口中来定义声明。
java
/**
* 根据aid查询收货地址数据
* @param aid 收货地址id
* @return 收货地址数据,如果没有找到返回null
*/
Address findByAid(Integer aid);
/**
* 根据用户的uid来修改用户的收货地址设置为非默认
* @param uid 用户的id值
* @return 受影响的行数
*/
Integer updateNonDefault(Integer uid);
Integer updateDefaultByAid(@Param("aid") Integer aid,
@Param("modifiedUser") String modifiedUser,
@Param("modifiedTime") Date modifiedTime);
✨1.3配置SQL映射
在AddressMapper.xml文件中配置。
XML
<select id="findByAid" resultMap="AddressEntityMap">
select * from t_address where aid=#{aid}
</select>
<update id="updateNonDefault">
update t_address set is_default=0 where uid=#{uid}
</update>
<update id="updateDefaultByAid">
update t_address set is_default=1,modified_user=#{modifiedUser},modified_time=#{modifiedTime}
where aid=#{aid}
</update>
在单元测试方法中进行测试。
java
@Test
public void updateNonDefault(){
addressMapper.updateNonDefault(6);
}
@Test
public void updateDefaultByAid(){
addressMapper.updateDefaultByAid(1,"与水",new Date());
}
@Test
public void findByAid(){
System.out.println(addressMapper.findByAid(2));
}
🚀设置默认收货地址- 业务层
✨2.1异常规划
1.在执行更新时产生未知的UpdateException异常。已经创建无需重复创建。
2.访问的数据不是当前用户登录的收货地址的数据,非法访问:AccessDeniedException异常。
java
//非法访问的异常
public class AccessDeniedException extends ServiceException {
public AccessDeniedException() {
super();
}
public AccessDeniedException(String message) {
super(message);
}
public AccessDeniedException(String message, Throwable cause) {
super(message, cause);
}
public AccessDeniedException(Throwable cause) {
super(cause);
}
protected AccessDeniedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
3.收货地址有可能不存在的异常:AddressNotFoundException异常。
java
public class AddressNotFoundException extends ServiceException{
public AddressNotFoundException() {
super();
}
public AddressNotFoundException(String message) {
super(message);
}
public AddressNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public AddressNotFoundException(Throwable cause) {
super(cause);
}
protected AddressNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
✨2.2抽象方法
在接口中编写抽象方法。
java
/**
* 修改某个用户的某条收货地址为默认收货地址
* @param aid 收货地址的id
* @param uid 用户的id
* @param username 修改执行的人
*/
void setDefault(Integer aid,Integer uid,String username);
✨2.3实现抽象方法
在AddressServiceImpl类中进行开发设计。
java
@Override
public void setDefault(Integer aid, Integer uid, String username) {
Address result = addressMapper.findByAid(aid);
if(result == null){
throw new AddressNotFoundException("收货地址不存在");
}
//检测当前获取到的收货地址数据的归属:
// 在结果中可以拿到uid,当前登录的uid以参数传递过来了,判断两个uid是否相同
if(!result.getUid().equals(uid))
{
throw new AccessDeniedException("非法数据访问");
}
//先将所有的收货地址设置为非默认
Integer rows = addressMapper.updateNonDefault(uid);
if(rows < 1){
throw new UpdateException("更新数据产生未知的异常");
}
//将用户选中的某条地址设置为默认收货地址
rows = addressMapper.updateDefaultByAid(aid,username,new Date());
if(rows != 1){
throw new UpdateException("更新时数据产生未知异常");
}
}
在单元测试类中进行测试。
java
@Test
public void setDefault(){
addressService.setDefault(3,6,"与水");
}
🚀设置默认收货地址- 控制层
✨3.1处理异常
在BaseController中进行统一的处理。
java
else if(e instanceof AddressNotFoundException) {
result.setState(4004);
result.setMessage("用户收货地址不存在的异常");
}else if(e instanceof AccessDeniedException) {
result.setState(4005);
result.setMessage("收货地址非法访问的异常");
}
✨3.2设计请求
请求路径:/addresses/{aid}/set_default({aid}是一个占位符,占的是Restful风格的数据提交形式)
请求参数:@PathVariable("aid"),Integer aid,HttpSession session(如果上边标注的是id,但是在参数列表给到的是aid,此时它不会自动注入到aid。需要通过@PathVariable()强行注入)
请求类型:GET
响应结果:JsonResult<Void>
✨3.3处理请求
在AddressController类中编写请求处理方法。
java
//RestFul风格的请求编写
@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<>(OK);
}
先登录,再去访问请求的路径。http://localhost:8080/addresses/2/set_default
🚀设置默认收货地址- 前端页面
1.给设置默认收货地址按钮添加一个onclick属性,指向一个方法的调用,在这个方法中来完成ajax请求的方法。
javascript
var tr = '<tr>\n' +
'<td>#{tag}</td>\n' +
'<td>#{name}</td>\n' +
'<td>#{address}</td>\n' +
'<td>#{phone}</td>\n' +
'<td><a class="btn btn-xs btn-info"><span class="fa fa-edit"></span> 修改</a></td>\n' +
'<td><a class="btn btn-xs add-del btn-info"><span class="fa fa-trash-o"></span> 删除</a></td>\n' +
'<td><a onclick="setDefault(#{aid})" class="btn btn-xs add-def btn-default">设为默认</a></td>\n' +
'</tr>';
//#{tag}等只是占位符,不是像映射文件里的参数,没有任何意义
tr = tr.replace(/#{tag}/g,list[i].tag);
tr = tr.replace(/#{name}/g,list[i].name);
tr = tr.replace("#{address}",list[i].address);
tr = tr.replace("#{phone}",list[i].phone);
tr = tr.replace("#{aid}",list[i].aid);
address.html页面点击"设置默认"按钮,来发送ajax请求。
javascript
function setDefault(aid){
$.ajax({
url:"/addresses/"+aid+"/set_default",
type:"POST",
dataType:"JSON",
success:function (json){
if(json.state == 200){
//重新加载收货地址列表页面
showAddressList();
}else{
alert("设置默认收货地址失败");
}
},
error:function (xhr){
alert("设置默认收货地址时产生异常"+xhr.message);
}
})
}
🎯1.删除收货地址-持久层
✨1.1规划SQL语句
1.在删除之前判断该数据是否存在,判断该条地址数据的归属是否为当前用户。不用重复开发。
2.删除收货地址的信息。
sql
delete from t_address where aid=?
3.如果用户删除的是默认收货地址,将剩下的地址中的某一条设置为默认的收货地址。规则可以自定义:可以把最新时间添加的1地址设置为默认收货地址,根据modified_time来判断。
limit 0表示从查询结果中返回从第0条开始记录的1条数据。
limit(n*(n-1),pageSize)
sql
select * from t_address where uid=?
order by modified_time DESC limit 0,1
4.如果用户本身只有一条收货地址,删除后其他操作就可以不进行了。在设置收货地址时已经开发过,此处不用重复。
✨1.2设计接口和抽象方法
在AddressMapper接口中进行抽象方法的设计。
java
/**
* 根据收货地址id删除收货地址数据
* @param aid 收货地址id
* @return 受影响的行数
*/
Integer deleteByAid(Integer aid);
/**
* 根据用户uid查询当前用户最后一次被修改的收货地址的数据
* @param uid 用户id
* @return 收货地址
*/
Address findLastModified(Integer uid);
✨1.3完成映射
在AddressMapper.xml文件中进行映射。
XML
<delete id="deleteByAid">
delete from t_address where aid=#{aid}
</delete>
<!--resultMap="AddressEntityMap"将查询结果映射到 Address 对象中,确保查询结果能够正确地被 MyBatis 处理并返回为 Java 对象-->
<select id="findLastModified" resultMap="AddressEntityMap">
select * from t_address where uid=#{uid}
order by modified_time DESC limit 0,1;
</select>
单元测试
java
@Test
public void deleteByAid(){
addressMapper.deleteByAid(1);
}
@Test
public void findLastModified(){
System.out.println(addressMapper.findLastModified(6));
}
🎯2.删除收货地址-业务层
✨2.1规划异常
在执行删除时可能会出现未知的删除异常导致不能删除成功,则抛出DeleteException异常。需要定义。
java
//删除数据时产生的异常
public class DeleteException extends ServiceException{
public DeleteException() {
super();
}
public DeleteException(String message) {
super(message);
}
public DeleteException(String message, Throwable cause) {
super(message, cause);
}
public DeleteException(Throwable cause) {
super(cause);
}
protected DeleteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
✨2.2抽象方法的设计
在IAddressService接口中进行设计抽象方法。
需要的参数:
1.updateDefaultByAid:aid,modifiedUser(username),modifiedTime(new Date());
2.findByAid:aid;
3.countByUid:需要查询数据总数,当为1时要注意删除后不再执行其他操作。uid;
4.deleteByAid:aid;
5.findLastModified:uid.
java
/**
* 删除用户选中的收货地址数据
* @param aid 收货地址的id
* @param uid 用户id
* @param username 用户名
*/
void delete(Integer aid,Integer uid,String username);
✨2.3实现抽象方法
java
@Override
public void delete(Integer aid, Integer uid, String username) {
Address result = addressMapper.findByAid(aid);
if(result == null){
throw new AddressNotFoundException("收货地址数据不存在");
}
if(!result.getUid().equals(uid)){
throw new AccessDeniedException("非法数据访问");
}
Integer rows = addressMapper.deleteByAid(aid);
if(rows != 1){
throw new DeleteException("删除数据产生位置的异常");
}
Integer count = addressMapper.countByUid(uid);
if(count == 0){
//直接终止程序
return;
}
if(result.getIsDefault() == 0){
return;
}
if(result.getIsDefault() == 1){
//将这条数据字段中is_default的值设置为1
Address address = addressMapper.findLastModified(uid);
//这里的aid是address的,上面的是要删除的aid
rows = addressMapper.updateDefaultByAid(address.getAid(),username,new Date());
}
if(rows != 1){
throw new UpdateException("更新数据时产生未知异常");
}
}
在测试类中测试该方法的功能是否正常。
java
@Test
public void delete(){
addressService.delete(3,6,"管理者");
}
🎯3.删除收货地址-控制层
1.需要处理异常DeleteException类。
java
else if(e instanceof DeleteException){
result.setState(5002);
result.setMessage("删除数据时产生未知的异常");
}
2.设计请求处理。
请求路径:/addresses/{aid}/delete
请求参数:Integer aid,HttpSession session
请求类型:POST
响应结果:JsonResult<Void>
3.编写请求处理方法的实现
java
@RequestMapping("{aid}/delete")
public JsonResult<Void> delete(@PathVariable("aid") Integer aid,HttpSession session){
addressService.delete(aid,getuidFromSession(session),getUsernameFromSession(session));
return new JsonResult<>(OK);
}
🎯4.删除收货地址-前端页面
在address页面中来添加删除按钮的事件。
javascript
<td><a onclick="deleteByAid(#{aid})" class="btn btn-xs add-del btn-info"><span class="fa fa-trash-o"></span> 删除</a></td>
javascript
tr = tr.replaceAll("#{aid}",list[i].aid);
再去编写deleteByAid(aid)方法的具体实现。
javascript
function deleteByAid(aid){
$.ajax({
url: "/addresses/"+aid+"/delete",
type: "POST",
dataType: "JSON",
success: function (json) {
if (json.state == 200) {
//重新加载收货地址列表页面
showAddressList();
} else {
alert("删除收货地址失败")
}
},
error: function (xhr) {
alert("删除收货地址时产生未知的异常!"+xhr.message);
}
});
}
登陆系统进行测试。