> 文档中心 > SpringBoot+MyBatis+MYSQL项目实战六(新增收货地址)

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>

香烟价格网