Project(9)——收货地址 -查看列表
1、分析项目
当需要开发某个项目时,首先,应该分析这个项目中,需要处理哪些种类的数据!例如:用户、商品、商品类别、收藏、订单、购物车、收货地址…
然后,将以上这些种类的数据的处理排个顺序,即先处理哪种数据,后处理哪种数据!通常,应该先处理基础数据,再处理所相关的数据,例如需要先处理商品数据,才可以处理订单数据,如果多种数据之间没有明显的关联,则应该先处理简单的,再处理较难的!
则以上这些数据的处理顺序应该是:用户 > 收货地址 > 商品类别 > 商品 > 收藏 > 购物车 > 订单
当确定了数据处理顺序后,就应该分析某个用户对应的功能有哪些,以“用户”数据为例,相关功能有:注册、登录、修改密码、修改资料、上传头像…
然后,还是需要确定以上功能的开发顺序,通常,遵循 “增 > 查 > 删 > 改” 的顺序,则以上功能的开发顺序应该是:注册 > 登录 > 修改密码 > 修改资料 > 上传头像。
每个功能的开发都应该遵循 创建数据表 > 创建实体类 > 持久层 > 业务层 > 控制器层 > 前端页面
一次只解决一个问题
大问题拆成小问题
2、用户 - 注册 - 创建数据表
3、用户 - 注册 - 创建实体类
4、用户 - 注册 - 持久层
a.规划SQL语句
b.接口与抽象方法
c.配置映射
5、用户 - 注册 - 业务层
业务层的基本定位
a.规划异常
b.接口与抽象方法
c.实现类与重写方法
6、用户 - 注册 - 控制器层
a.处理异常
b.设计请求
c.处理请求
7、用户 - 注册 - 前端页面
……
收货地址 - 分析
关于收货地址的管理,涉及的功能有:增加,查看列表,修改,删除,设为默认。
以上功能的开发顺序应该是:增加 > 查看列表 > 设为默认 > 删除 > 修改。
25、收货地址 - 创建数据表
CREATE TABLE t_address(
aid INT PRIMARY KEY AUTO_INCREMENT COMMENT '收货地址aid',
uid INT COMMENT '用户uid',
name VARCHAR(50) COMMENT '收货人姓名',
province_code CHAR(6) COMMENT '省 - 代号',
province_name VARCHAR(50) COMMENT '省 - 名称',
city_code CHAR(6) COMMENT '市 - 代号',
city_name VARCHAR(50) COMMENT '市 - 名称',
area_code CHAR(6) COMMENT '区 - 代号',
area_name VARCHAR(50) COMMENT '区 - 名称',
zip CHAR(6) COMMENT '邮编',
address VARCHAR(100) COMMENT '详细地址',
phone VARCHAR(20) COMMENT '手机',
tel VARCHAR(20) COMMENT '固话',
tag VARCHAR(20) COMMENT '地址类型',
is_default INT COMMENT '是否默认 0 - 非默认;1 - 默认',
is_delete INT COMMENT '是否标记为删除 0 - 未删除;1 - 已删除',
created_user VARCHAR(20) COMMENT '创建人',
created_time DATETIME COMMENT '创建时间',
modified_user VARCHAR(20) COMMENT '修改人',
modified_time DATETIME COMMENT '修改时间'
) DEFAULT CHARSET UTF8;
26、收货地址 - 创建实体类
27、收货地址 - 增加 - 持久层
a.规划SQL语句
b.接口与抽象方法
c.配置映射
28、收货地址 - 增加 - 业务层
a.规划异常
b.接口与抽象方法
c.实现类与重写方法
29、收货地址 - 增加 - 控制器层
a.处理异常
b.设计请求
c.处理请求
30、收货地址 - 增加 - 前端页面
31、省市区数据 - 导入数据
登录 mysql 控制台,通过source 文件路径
导入
32、创建实体类
33、省市区数据 - 获取列表 - 持久层
a.规划SQL语句
b.接口与抽象方法
c.配置映射
34、省市区数据 - 获取列表 - 业务层
a.规划异常
b.接口与抽象方法
c.实现类与重写方法
35、省市区数据 - 获取列表 - 控制器层
a.处理异常
b.设计请求
c.处理请求
36、省市区数据 - 获取列表 - 前端页面
37、收货地址 - 查看列表 - 持久层
a.规划SQL语句
SELECT
tag, name, province_name AS provinceName, city_name AS cityName,
area_name AS areaName, address, phone, aid,
is_default AS isDefault
FROM
t_address
WHERE
uid=#{uid}
ORDER BY
is_default desc, modified_time desc
// 将默认的地址排到前面,将其余地址按照时间顺序排列,最新的地址数据排到前面
b.接口与抽象方法
/**
* 根据用户 uid 查询收货地址信息
* @param uid 用户 uid
* @return 收货地址的列表
*/
List<Address> findByUid(Integer uid);
c.配置映射
<!-- 根据用户 uid 查询收货地址信息 -->
<!-- List<Address> findByUid(Integer uid) -->
<select id="findByUid" resultType="cn.tedu.store.entity.Address">
SELECT
tag, name, province_name AS provinceName, city_name AS cityName,
area_name AS areaName, address, phone, aid,
is_default AS isDefault
FROM
t_address
WHERE
uid=#{uid}
ORDER BY
is_default desc, modified_time desc
</select>
在src/test/java
的AddressMapperTests
中编写并执行单元测试:
/**
* 测试根据 uid 查询用户收货地址信息
*/
@Test
public void testFindByUid() {
Integer uid = 7;
List<Address> list = addressMapper.findByUid(uid);
System.err.println("Begin:");
for(Address address : list) {
System.err.println(address);
}
System.err.println("End.");
}
38、收货地址 - 查看列表 - 业务层
a.规划异常
无
b.接口与抽象方法
将AddressMapper
持久层接口中的 List<Address> findByUid(Integer uid)
方法直接复制到IAddressService
业务层接口中,将方法名称改为getByUid
:
/**
* 根据用户 uid 查询收货地址信息
* @param uid 用户 uid
* @return 收货地址的列表
*/
List<Address> getByUid(Integer uid);
c.实现类与重写方法
同理,将AddressMapper
持久层接口中的 List<Address> findByUid(Integer uid)
方法直接复制到AddressServiceImpl
实现类,私有化实现此方法:
/**
* 根据用户 uid 查询收货地址信息
* @param uid 用户 uid
* @return 收货地址的列表
*/
private List<Address> findByUid(Integer uid){
return addressMapper.findByUid(uid);
}
然后,重写IAddressService
接口中的getByUid()
方法:
@Override
public List<Address> getByUid(Integer uid) {
return findByUid(uid);
}
在src/test/java
的AddressServiceTests
中编写并执行测试方法:
/**
* 测试根据 uid 查询用户收货地址信息
*/
@Test
public void testGetByUid() {
Integer uid = 7;
List<Address> list = service.getByUid(uid);
System.err.println("Begin:");
for(Address address : list) {
System.err.println(address);
}
System.err.println("End.");
}
39、收货地址 - 查看列表 - 控制器层
a.处理异常
无
b.设计请求
请求路径:/addresses/
请求参数:HttpSession session
请求类型:GET
响应数据:JsonResult<List<Address>>
c.处理请求
在AddressController
中添加处理方法:
/**
* 根据 uid 查询用户收获地址信息
* @param session 用于获取用户 uid
* @return
*/
@GetMapping("/")
public JsonResult<List<Address>> getByUid(HttpSession session){
// 从 session 中获取 uid
Integer uid = getUidFromSession(session);
// 调用业务层方法获取数据
List<Address> list = service.getByUid(uid);
// 响应
return new JsonResult<List<Address>>(SUCCESS, list);
}
先用Tom
登录,然后再地址栏上输入http://localhost:8080/addresses/
进行测试。
40、收货地址 - 查看列表 - 前端页面
一:
在address.html
页面中:
<script type="text/javascript">
$(document).ready(function(){
showAddressList();
});
function showAddressList(){
$.ajax({
"url" : "/addresses/",
"type" : "get",
"dataType" : "json",
"success" : function(json){
var list = json.data;
console.log("count = " + list.length);
for (var i = 0; i < list.length; i++) {
console.log(list[i].name);
}
}
});
}
</script>
完成后先登录,然后刷新http://localhost:8080/web/address.html
页面,用 F12
查看控制台数据:
二:字符串拼接,但是不推荐!
在<tbody>
部分中添加id
属性值为address-list
<script type="text/javascript">
$(document).ready(function(){
showAddressList();
});
function showAddressList(){
$.ajax({
"url" : "/addresses/",
"type" : "get",
"dataType" : "json",
"success" : function(json){
var list = json.data;
console.log("count = " + list.length);
$("#address-list").empty();
for (var i = 0; i < list.length; i++) {
console.log(list[i].name);
var html = '<tr>'
+ '<td>' + list[i].tag + '</td>'
+ '<td>' + list[i].name + '</td>'
+ '<td>' + list[i].provinceName + list[i].cityName + list[i].areaName + list[i].address + '</td>'
+ '<td>' + list[i].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>';
$("#address-list").append(html);
}
}
});
}
</script>
三:
function showAddressList(){
$.ajax({
"url" : "/addresses/",
"type" : "get",
"dataType" : "json",
"success" : function(json){
var list = json.data;
console.log("count = " + list.length);
$("#address-list").empty();
for (var i = 0; i < list.length; i++) {
console.log(list[i].name);
var html = '<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>';
html = html.replace("#{tag}", list[i].tag);
html = html.replace("#{name}", list[i].name);
html = html.replace("#{address}", list[i].provinceName + list[i].cityName + list[i].areaName + list[i].address);
html = html.replace("#{phone}", list[i].phone);
$("#address-list").append(html);
}
}
});
}
优化:
收货地址页面的第一条数据为默认地址,应该隐藏后面的 设为默认
选项: