Bootstrap

Project(9)——收货地址 -查看列表

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数据(1)

全国大陆地区省市区MySQL数据(2)

登录 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/javaAddressMapperTests中编写并执行单元测试:


   /**
	 * 测试根据 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/javaAddressServiceTests中编写并执行测试方法:


    /**
	 * 测试根据 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);
				
			}
		}
	});
}

优化:

收货地址页面的第一条数据为默认地址,应该隐藏后面的 设为默认 选项:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

;