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
@NoArgsConstructor
public 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映射


<?xml version="1.0" encoding="UTF-8" ?>
<!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">
        <!--        将表的资源和类的睡醒不一样的字段进行匹配指定,名称一直的字段可以省略不写-->
        <!--
                    配合完成名称不一致的映射
                    column属性:表示表中的资源名称
                    property属性:表示类中的属性名称
        -->
        <!--        在定义映射规则时主键是不可以省略的-->
        <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;
@Service
public 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<Void>
@Api(tags = "收货地址接口")
@RequestMapping("/address")
@RestController
public 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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@黑夜中的一盏明灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值