SpringBoot+MyBatis+MYSQL项目实战六(新增收货地址)
SpringBoot+MyBatis+MYSQL项目实战六(新增收货地址)
项目源码地址:
电脑商城实战
点击新增收货地址
一:新增收货地址——数据表的创建
CREATE TABLE t_address (aid INT AUTO_INCREMENT COMMENT '收货地址id',uid INT COMMENT '归属的用户id',name VARCHAR(20) COMMENT '收货人姓名',province_name VARCHAR(15) COMMENT '省-名称',province_code CHAR(6) COMMENT '省-行政代号',city_name VARCHAR(15) COMMENT '市-名称',city_code CHAR(6) COMMENT '市-行政代号',area_name VARCHAR(15) COMMENT '区-名称',area_code CHAR(6) COMMENT '区-行政代号',zip CHAR(6) COMMENT '邮政编码',address VARCHAR(50) COMMENT '详细地址',phone VARCHAR(20) COMMENT '手机',tel VARCHAR(20) COMMENT '固话',tag VARCHAR(6) COMMENT '标签',is_default INT COMMENT '是否默认:0-不默认,1-默认',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (aid)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二:新增收货地址——创建实体类
@ApiModel("收获地址的实体类")@Data@AllArgsConstructor@NoArgsConstructorpublic class Address extends BaseEntity implements Serializable { private Integer aid; private Integer uid; private String name; private String provinceName; private String provinceCode; private String cityName; private String cityCode; private String areaName; private String areaCode; private String zip; private String address; private String phone; private String tel; private String tag; private Integer isDefault; }
三:新增收货地址——持久层
3.1 各功能的开发顺序
关于收货地址数据的管理,涉及的功能有:增加,删除,修改,设为默认,显示列表。这些功能的开发顺序为:增加-显示列表-设为默认-删除-修改。
3.2 规划需要执行的SQL语句
增加收货地址的本质是插入新的收货地址数据,需要执行的SQL语句大致是:
INSERT INTO t_address (除了aid以外的字段列表) VALUES (匹配的值列表)
后续在处理业务时,还需要确定“即将增加的收货地址是不是默认收货地址”;可以设定规则“用户的第1条收货地址是默认的,以后添加的每一条都不是默认的”;要应用该规则,就必须知道“即将增加的收货地址是不是第1条”,可以“根据用户id统计收货地址的数量”,如果统计结果为0,则即将增加的就是该用户的第1条收货地址,如果统计结果不是0,则该用户已经有若干条收货地址了,即将增加的就一定不是第1条。关于统计的SQL语句大致是:
SELECT count(*) FROM t_address WHERE uid=?
一般电商平台都会限制每个用户可以创建的收货地址的数量,如“每个用户最多只允许创建20个收货地址”,也可以通过以上查询来实现。
3.3 接口与抽象方法
新建一个AddressMapper接口
/** * 插入用户的收货地址数据 * @param address 收货地址数据 * @return 受影响的行数 */ Integer insert(Address address); /** * 根据用户的id统计收获地址数量 * @param uid 用户的id * @return 返回当前收货地址总数 */ Integer countByUid(Integer uid);
3.4 配置SQL映射
新建一个AddressMapper.xml文件,配置SQL映射
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.store.mapper.AddressMapper"> <resultMap id="AddressEntityMap" type="com.example.store.entity.Address"> <result column="aid" property="aid"/> <result column="province_code" property="provinceCode"/> <result column="province_name" property="provinceName"/> <result column="city_code" property="cityCode"/> <result column="city_name" property="cityName"/> <result column="area_name" property="areaName"/> <result column="area_code" property="areaCode"/> <result column="is_default" property="isDefault"/> <result column="created_user" property="createdUser"/> <result column="created_time" property="createdTime"/> <result column="modified_user" property="modifiedUser"/> <result column="modified_time" property="modifiedTime"/> </resultMap> <insert id="insert" useGeneratedKeys="true" keyProperty="aid"> INSERT INTO t_address ( uid, name, province_name, province_code, city_name, city_code, area_name, area_code, zip, address, phone, tel,tag, is_default, created_user, created_time, modified_user, modified_time ) VALUES (#{uid}, #{name}, #{provinceName}, #{provinceCode}, #{cityName}, #{cityCode}, #{areaName},#{areaCode}, #{zip}, #{address}, #{phone}, #{tel}, #{tag}, #{isDefault}, #{createdUser},#{createdTime}, #{modifiedUser}, #{modifiedTime} ) </insert> <select id="countByUid" resultType="java.lang.Integer"> SELECT count(*) FROM t_address WHERE uid = #{uid} </select></mapper>
3.5 编写测试类
@Test public void insert(){ Address address = new Address(); address.setUid(10); address.setPhone("15166970720"); address.setName("女朋友"); addressMapper.insert(address); } @Test public void countByUid(){ Integer count = addressMapper.countByUid(10); System.out.println(count); }
三:新增收货地址——业务层
4.1 规划异常
1.无论用户将要增加的收货地址是不是默认收货地址,都需正常增加。即通过countByUid()方法统计的结果不管是不是0,都不能代表是错误的操作。
2.在执行插入收货地址数据之前,需判断countByUid()方法返回值是否超出上限值,如果超出上限值则抛AddressCountLimitException异常。
3.在执行插入数据时,还可能抛出InsertException异常,此异常无需再次创建。
4.如果查询的统计总数是0,将当前地址的is_default设置为1,查询统计的结果为0不代表异常。
4.2 接口与抽象方法
1.创建一个IAddressService接口,在其中定义业务的抽象方法
/** * 收获地址 的接口 */public interface IAddressService { void addNewAddress(Integer uid,String username,Address address);}
2.创建一个IAddressServiceImpl实现类,去实现接口中的抽象方法
在配置文件中定义数据
@Value("${user.address.max-count}") private Integer maxCount;
@Servicepublic class IAddressServiceImpl implements IAddressService { @Autowired private AddressMapper addressMapper; @Value("${user.address.max-count}") private Integer maxCount; @Override public void addNewAddress(Integer uid, String username, Address address) { Integer count = addressMapper.countByUid(uid); if(count >= maxCount){ throw new AddressCountLimitException("用户收货地址超出上限"); } // uid IsDefault address.setUid(uid); Integer isDefault = (count == 0) ? 1 : 0; // 1表示默认,0表示不是默认 address.setIsDefault(isDefault); // 补全四项日志 address.setCreatedUser(username); address.setCreatedTime(new Date()); address.setModifiedUser(username); address.setModifiedTime(new Date()); Integer rows = addressMapper.insert(address); if (rows != 1){ throw new InsertException("插入用户数据产生未知的异常"); } }}
3.测试业务层功能是否正常
@Test public void addNewAddress(){ Address address = new Address(); address.setUid(8); address.setPhone("15166970720"); address.setName("女朋友"); iAddressService.addNewAddress(8,"root",address); }
四:新增收货地址———控制器
4.1 处理异常
在控制器层新增收货地址时,如果收货地址已经达到上限值,则抛出AddressCountLimitException异常,并在BaseController类中添加处理AddressCountLimitException的异常。
// ...else if (e instanceof AddressCountLimitException) {result.setState(4003);}// ...
5.2 设计请求
设计用户提交的请求,并设计响应的方式。
请求路径:/addresses/add_new_address请求参数:Address address, HttpSession session请求类型:POST响应结果:JsonResult
@Api(tags = "收货地址接口")@RequestMapping("/address")@RestControllerpublic class AddressController extends BaseController{ @Autowired private IAddressService addressService; @ApiOperation("添加地址接口") @RequestMapping(value = "/add_new_address",method = RequestMethod.POST) public JsonResult<Void> addNewAddress(Address address,HttpSession session){ Integer uid = getuidFromSession(session); String username = getUsernameFromSession(session); addressService.addNewAddress(uid,username,address); return new JsonResult<>(OK); }}
五:新增收货地址———前端页面
<script>$("#btn-add-new-address").click(function () {$.ajax({url: "/address/add_new_address",type: "POST",data : $("#form-add-new-address").serialize(),dataType: "JSON",success: function (json) {if(json.state == 200){alert("添加收货地址成功")}else{alert("添加收货地址修改失败")}},error: function (xhr) {alert("添加收货地址时产生位置的异常"+xhr.status);}})})</script>