springboot电脑商城项目 8.收货地址列表展示 9.设置默认收货地址 10 删除收货地址
8.收货地址列表展示
1.持久层
1.数据库的查询操作:
select * from t_address where uid = #{uid} order by is_default DESC ,created_time DESC
2.接口和抽象方法
/**
* 根据用户的id查询用户的收货地址数据
* @param uid 用户id
* @return 收货地址列表
*/
List<Address> findByUid(Integer uid);
3.在xml文件中添加对应的sql语句映射
<select id="findByUid" resultMap="AddressEntityMap">
select * from t_address where uid = #{uid} order by is_default DESC ,created_time DESC
</select>
4.单元测试方法
@Test
public void findByUid(){
List<Address> list = addressMapper.findByUid(29);
for (Address address : list) {
System.out.println(address);
}
}
2.业务层
1.不用抛出相关异常
2.设计业务层的接口和抽象方法
List<Address> getAddressByUid(Integer uid);
3.在实现类中实现此方法
@Override
public List<Address> getAddressByUid(Integer uid) {
List<Address> list = addressMapper.findByUid(uid);
for (int i = 0; i < list.size(); i++) {
Address data = new Address();
Address address = list.get(i);
String name = address.getName();
String addressAddress = address.getAddress();
String provinceName = address.getProvinceName();
String cityName = address.getCityName();
String areaName = address.getAreaName();
String tag = address.getTag();
String zip = address.getZip();
String phone = address.getPhone();
data.setName(name);
data.setAddress(addressAddress);
data.setProvinceName(provinceName);
data.setCityName(cityName);
data.setAreaName(areaName);
data.setTag(tag);
data.setZip(zip);
data.setPhone(phone);
list.set(i,data);
}
3.单元测试
3.控制层
1.请求设计
/address
HttpSession session
GET
JsonResult<List<Address>>
2.实现请求方法的编写
@RequestMapping({"/",""})
public JsonResult<List<Address>> getAddressByUid(HttpSession session){
Integer uid = getUidFromSession(session);
String username = getUsernameFormSession(session);
List<Address> data = addressService.getAddressByUid(uid);
return new JsonResult<>(OK, data);
}
3.先登录,再访问请求的地址进行数据的测试
4.前端界面
<script>
$(document).ready(function () {
showAddressList();
})
function showAddressList(){
$.ajax({
url: "/address",
type: "get",
dataType: "JSON",
success: function (json) {
if (json.state == 200){
let list = json.data;
for (let i = 0; i < list.length; i++) {
let tr = '<tr>' +
'<td>#{tag}</td>' +
'<td>#{name}</td>' +
'<td>#{address}</td>' +
'<td>#{phone}</td>' +
'<td><a class="btn btn-xs btn-info"><span class="fa fa-edit"></span> 修改</a></td>' +
'<td><a class="btn btn-xs add-del btn-info"><span class="fa fa-trash-o"></span> 删除</a></td>' +
'<td><a class="btn btn-xs add-def btn-default">设为默认</a></td>' +
'</tr>';
tr = tr.replace("#{tag}",list[i].tag);
tr = tr.replace("#{name}",list[i].name);
tr = tr.replace("#{address}",list[i].address);
tr = tr.replace("#{phone}",list[i].phone)
$("#address-list").append(tr);
}
//将某个元素隐藏使用hide()方法
$(".add-def:eq(0)").hide();
}else{
alert("用户收货地址数据加载失败")
}
}
});
}
</script>
9.设置默认收货地址
1.持久层
1.1 SQL语句规划
1.检测当前用户想设置为默认收货地址的这条数据是否存在。
select * from t_address aid = ?
2.在修改用户的收货地址之前,先将所有的收货地址设置为非默认
update t_address set is_default=0 where uid = ?
3.将用户当前选中的这条记录设置为默认收货地址
update t_address set is_default,modified_user = ?,modified_time = ? where aid = ?
1.2 接口和抽象方法
/**
* 根据aid查询收货地址数据
* @param aid 收货地址id
* @return 收货地址数据,如果没有找到,则返回null
*/
Address findByAid(Integer aid);
/**
* 根据用户的uid来修改用户的收货地址,将该用户的所有收货地址设置为非默认
* @param uid 用户的uid
* @return 受影响的行数
*/
Integer updateNonDefault(Integer uid);
/**
* 将选中地址设置为默认
* @param aid
* @param modifiedUser
* @param modifiedTime
* @return
*/
Integer updateDefaultByAid(
@Param("aid") Integer aid,
@Param("modifiedUser") String modifiedUser,
@Param("modifiedTime") Date modifiedTime);
1.3 配置SQL映射
AddressMapper.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>
在单元测试方法中进行测试
@Test
public void findByAid(){
Address address = addressMapper.findByAid(17);
System.out.println(address);
}
@Test
public void updateNonDefault(){
addressMapper.updateNonDefault(29);
}
@Test
public void updateDefaultByAid(){
addressMapper.updateDefaultByAid(17,"管理员",new Date());
}
2. 业务层
2.1 异常规划
1.在执行更新时产生位置的UpdateException异常.该异常已经创建
2.访问的数据不是当前登录用户的收货地址,非法访问:AccessDeniedException异常。
3.收货地址可能不存在异常:addressNotFoundException异常
2.2 抽象方法
在接口IAddressService中编写抽象方法
/**
* 修改某个用户的某条收货地址数据为默认收货地址
* @param aid 收货地址的id
* @param uid 用户的id
* @param username 表示修改的执行人
*/
void setAddressDefault(Integer aid,Integer uid,String username);
在AddressServiceImpl中实现方法
@Override
public void setAddressDefault(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.updateNonDefault(uid);
if (rows <1){
throw new UpdateException("更新数据时产生未知异常");
}
//将用户选中的收货地址设置为默认收货地址
rows = addressMapper.updateDefaultByAid(aid, username, new Date());
if (rows != 1){
throw new UpdateException("更新数据时产生未知异常");
}
}
进行单元测试
@Test
public void setAddressDefault(){
addressService.setAddressDefault(18,29,"维生素");
}
3.控制层
3.1 处理异常
在BaseController中进行统一的处理
else if (e instanceof AddressNotFoundException) {
result.setState(4004);
result.setMessage("用户的收货地址不存在的异常");
} else if (e instanceof AccessDeniedException) {
result.setState(4005);
result.setMessage("收货地址数据非法访问的异常");
}
3.2 设计请求
/address/{aid}/set_default
@PathVariable("aid") Integer aid,HttpSession session
GET
JsonResult<Void>
3.3 完成请求方法
在AddressController类中编写请求处理方法
//RestFul风格编写
@RequestMapping("{aid}/set_default")
public JsonResult<Void> setAddressDefault(@PathVariable("aid") Integer aid, HttpSession session){
addressService.setAddressDefault(
aid,
getUidFromSession(session),
getUsernameFormSession(session));
return new JsonResult<>(OK);
}
测试:http://localhost:8080/address/20/set_default
4.前端界面
1.给设置默认收货地址俺就添加一个onclick属性,指向一个方法的调用,在这个方法中来完成ajax请求的方法。
function showAddressList(){
$.ajax({
url: "/address",
type: "get",
dataType: "JSON",
success: function (json) {
if (json.state == 200){
let list = json.data;
for (let i = 0; i < list.length; i++) {
let 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>';
tr = tr.replace("#{tag}",list[i].tag);
tr = tr.replace("#{name}",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-list").append(tr);
}
$(".add-def:eq(0)").hide();
}else{
alert("用户收货地址数据加载失败")
}
}
});
}
address.html页面中点击“设置默认”按钮,来发送ajax请求。完成setDefault()方法的声明和定义。
function setDefault(aid) {
$.ajax({
url: "/address/" + aid + "/set_default",
type: "POST",
dataType: "JSON",
success: function (json) {
if (json.state == 200){
//重新加载收货地址界面
$("#address-list").empty();
showAddressList();
}else{
alert("设置默认收货地址失败")
}
},
error: function (xhr) {
alert("设置默认收货地址时产生未知异常" + xhr.message);
}
});
}
注:在最后一步中如果状态码为200重新加载页面时,若不添加$("#address-list").empty();
则会出现list数据一直叠加的效果。
10.删除收货地址
1 持久层
1.1 规划执行的Sql语句
1.在之前判断该数据是否存在,判断修改数据的归属是否属于当前用户。不用重复开发。
2.执行删除收货地址信息
delete from t_address where aid = ?
3.如果用户删除的是默认收货地址信息,将剩下的地址中的某一条设置为默认收货地址。可自定义规则:最新修改的收获地址设置为默认收货地址(midified_time字段值)。
#limit (n-1)*n ,pageSize
select * from t_address where uid =? order by modified_time DESC limit 0,1
4.如果用户本身就只用一条收货地址数据,删除后其他操作就可以不进行了。
1.2 设计抽象方法
/**
* 根据收货地址id删除收货地址数据
* @param aid 收货地址的id
* @return 受影响的行数
*/
Integer deleteByAid(Integer aid);
/**
* 根据用户uid查询当前用户最后一次被修改的收获地址的数据
* @param uid 用户uid
* @return 收货地址数据
*/
Address findLastModified(Integer uid);
1.3 映射sql语句
在AddressMapper.xml文件中进行映射
<delete id="deleteByAid">
DELETE from t_address where aid = #{aid}
</delete>
<select id="findByModified" resultMap="AddressEntityMap">
SELECT * from t_address
where uid = #{uid}
order by modified_time DESC limit 0,1
</select>
在单元测试中测试方法
@Test
public void deleteByAid(){
addressMapper.deleteByAid(2);
}
@Test
public void findLastModified(){
System.err.println(addressMapper.findLastModified(1));
}
2 业务层
2.1 规划异常
在执行删除的时候可能会产生未知的删除异常导致数据不能删除成功。DeleteException异常。需要定义和创建。
/**
* 删除数据时产生的异常
*/
public class DeleteException extends ServiceException {
//...
}
2.2 抽象方法设计
在IAddressService接口中进行设计抽象方法。mapper层的两个方法结合
参数:aid uid username
调用mapper层方法
- findByAid
- countByUid
- 。。。
/**
* 删除用户选中的收货地址数据
* @param aid 收货地址id
* @param uid 用户id
* @param username 用户名
*/
void delete(Integer aid,Integer uid,String username);
2.3 实现抽象方法
业务层抽象方法的设计和实现
public void delete(Integer aid, Integer uid, String username) {
//通过aid查询当前删除地址是否存在
Address result = addressMapper.findByAid(aid);
if (result == null){
throw new AddressNotFoundException("收货地址数据不存在");
}
//检测当前获取到的收货地址数据的归属
if (!result.getUid().equals(uid)) {
throw new AccessDeniedException("非法访问异常");
}
//根据aid来删除这条数据
Integer rows = addressMapper.deleteByAid(aid);
if (rows != 1){
throw new DeleteException("删除数据产生未知的异常");
}
//通过uid来查询当前用户下的所有地址信息
Integer count = addressMapper.countByUid(uid);
//如果结果为0 则终止程序
if (count == 0){
return;
}
//判断当前删除地址是否为默认地址,如果为非默认地址则直接终止
if (result.getIsDefault() == 0){
return;
}
//通过uid查询出当前用户所有地址中修改时间最晚的数据,将其设置为默认地址
Address address = addressMapper.findLastModified(uid);
rows = addressMapper.updateDefaultByAid(address.getAid(), username, new Date());
if (rows != 1){
throw new UpdateException("更新数据时产生未知异常");
}
}
测试该方法的功能是否正常
3.控制层
1.需要处理异常DeleteException类。
else if (e instanceof DeleteException) {
result.setState(5002);
result.setMessage("删除数据时产生未知异常");
}
2.设计请求处理
/address/{aid}/delete
POST
Integer aid,HttpSession session
JsonResult<Void>
3.编写请求处理方法实现。
@RequestMapping("{aid}/delete")
public JsonResult<Void> deleteAddressByAid(@PathVariable("aid") Integer aid,HttpSession httpsession){
addressService.delete(aid,getUidFromSession(httpsession),getUsernameFormSession(httpsession));
return new JsonResult<>(OK);
}
4 前端页面
4.1在address.html页面中添加按钮的点击事件
<a onclick="deleteByAid(#{aid1})" class="btn btn-xs add-del btn-info"><span class="fa fa-trash-o"></span> 删除</a>
tr = tr.replace("#{aid1}",list[i].aid)
完整js
/**
* 展示用户收货地址数据列表
*/
function showAddressList(){
$.ajax({
url: "/address",
type: "POST",
dataType: "JSON",
success: function (json) {
if (json.state == 200){
let list = json.data;
for (let i = 0; i < list.length; i++) {
let 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 onclick="deleteByAid(#{aid1})" 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>';
tr = tr.replace("#{tag}",list[i].tag);
tr = tr.replace("#{name}",list[i].name);
tr = tr.replace("#{address}",list[i].address);
tr = tr.replace("#{phone}",list[i].phone);
tr = tr.replace("#{aid}",list[i].aid)
tr = tr.replace("#{aid1}",list[i].aid)
$("#address-list").append(tr);
}
$(".add-def:eq(0)").hide();
}else{
alert("用户收货地址数据加载失败")
}
}
});
}
4.2 编写deleteByAid(aid)方法的具体实现
function deleteByAid(aid){
$.ajax({
url: "/address/" + aid + "/delete",
type: "POST",
dataType: "JSON",
success: function (json) {
if (json.state == 200){
//重新加载收货地址界面
$("#address-list").empty();
showAddressList();
}else{
alert("删除收货地址失败")
}
},
error: function (xhr) {
alert("删除收货地址时产生未知异常" + xhr.message);
}
});
}