SpringBoot项目--电脑商城【新增收货地址】

这篇具有很好参考价值的文章主要介绍了SpringBoot项目--电脑商城【新增收货地址】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.新增收货地址

t_address

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;

注意name是关键字,所以需要用``

2.创建收货地址的实体类

在entity包下创建实体类Address继承BaseEntity类

/**
 * 收货地址的实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address extends BaseEntity {
    private Integer aid;//收货地址id
    private Integer uid;//归属用户id
    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;//是否默认  0-不默认,1-默认
}

3.持久层[Mapper]

1 各功能的开发顺序

当前收货地址功能模块:

  • 第一个页面:列表的展示,修改,删除,设置默认
  • 第二个页面:新增收货地址

开发顺序:新增收货地址->列表的展示->设置默认收货地址->删除收货地址->修改收货地址

2 需要规划要执行的sql语句

1.新增收货地址对应的是插入语句:

insert into t_address (aid以外的所有字段) values (字段值)

2. 大部分平台都会规定一个用户的收货地址数量,这里规定最多20个.那么在插入用户新的地址之前就要先做查询操作.如果查询到的是刚好20,这并不是一个java语法的异常,可以认为是业务控制的异常,这个异常随后在service抛,在controller捕获

select count(*) from t_address where uid=?

2.设置接口和抽象方法

创建接口AddressMapper,在这个接口中定义上面两个SQL语句抽象方法定义

//收货地址持久层接口
public interface AddressMapper {
    /**
     * 插入用户的收货地址数据
     *
     * @param address 收货地址
     * @return 受影响的行数
     */
    Integer insertAddress(Address address);

    /**
     * 获取收货地址的数量(不能超过20),根据用户的uid
     *
     * @param uid 用户uid
     * @return 收货地址数量
     */
    Integer countAddress(Integer uid);
}

3.编写映射

1.在mapper标签中配置Address类属性与数据库中表的字段映射

    <resultMap id="AddressEntityMap" type="com.example.mycomputerstore.entity.Address">
        <id     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_code"      property="areaCode"/>
        <result column="area_name"      property="areaName"/>
        <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>

判断该映射是否配置成功:按着ctrl并点击type="com.cy.store.entity.Address"中的Address,如果能跳转到Address类说明映射成功

2.在AddressMapper.xml中配置以上两个抽象方法的映射

    <insert id = "insertAddress" 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="countAddress" resultType="java.lang.Integer">
        SELECT count(*) FROM t_address WHERE uid = #{uid}
    </select>

4.单元测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class AddressMapperTests {

    @Autowired
    private AddressMapper addressMapper;

    @Test
    public void insert() {
        Address address = new Address();
        address.setUid(11);
        address.setPhone("133336");
        address.setName("女朋友");
        addressMapper.insert(address);
    }

    @Test
    public void countByUid() {
        Integer count = addressMapper.countByUid(11);
        System.out.println(count);
    }
}

4.业务层[service]

1. 规划异常

  • 插入数据时用户不存在(被管理员误删等等),抛UsernameNotFoundException异常(已经有了,不需要重复创建)
  • 当用户插入的地址是第一条时,需要将当前地址作为默认收货地址
  • 实现办法:如果查询到统计总数为0则将当前地址的is_default值设置为1
  • 如果查询的结果>=20,这时需要抛出业务控制的异常AddressCountLimitException
/**收货地址总数超出限制的异常(20条)*/
public class AddressCountLimitException extends ServiceException {
    /**重写ServiceException的所有构造方法*/
}
  • 插入数据时产生未知的异常InsertException(已经有了,不需要重复创建)

2 设计接口和抽象方法及实现

1.创建一个IAddressService接口,在接口中定义业务的抽象方法

因为mapper层接口该功能模块定义了两个抽象方法,所以就要在service层接口该功能模块也定义两个抽象方法?不是这样的,要看mapper层的这两个方法是依赖关系还是独立关系,如果某一个抽象方法依赖于另一个抽象方法,那就需要在业务层将这两个方法整合到一个方法中.一句话来说就是:一个功能模块可能需要多条sql语句

//收货地址业务层接口
public interface IAddressService {
    /**
     *这三个参数的由来:
     * 1.首先肯定要有address
     * 2.业务层需要根据uid查询该用户收货地址总数及新建地址时给字段uid赋值
     * 但新建收货地址的表单中并没有哪个控件让输入用户uid,所以需要控制层将uid传给业务层
     * 3.业务层在创建/修改收货地址时需要同时修改数据库中创建人/修改人的字段
     * 但新建收货地址的表单中并没有哪个控件让输入用户username,所以需要控制层将username传给业务层
     * 注意:> 可以用HttpSession session代替Integer uid, String username,但
     * 这样写的话就需要把BaseController类下获取uid,username的方法重新封装到一个
     * 类中并让IAddressServiceImp实现类继承该类,这样就需要微调一下代码逻辑,太麻
     * 烦,并且,最好每一层只处理该层需要做的事情,session对象是控制层传递的,所以就
     * 把session对象定义封装在控制层中,不需要在业务层中额外处理以降低耦合
     */
    void addAddress(Integer uid, String username, Address address);
}

方法addNewAddress中三个参数的由来:

  • 首先肯定要有address
  • 业务层需要根据uid查询该用户收货地址总数及新建地址时给字段uid赋值
  • 但新建收货地址的表单中并没有哪个控件让输入用户uid,所以需要控制层将uid传给业务层并在业务层封装到address对象中
  • 业务层在创建/修改收货地址时需要同时修改数据库中创建人/修改人的字段
  • 但新建收货地址的表单中并没有哪个控件让输入用户username,所以需要控制层将username传给业务层并在业务层封装到address对象中

可以用HttpSession session代替Integer uid, String username,但这样写的话就需要把BaseController类下获取uid,username的方法重新封装到一个类中并让AddressServiceImpl实现类继承该类,这样就需要微调一下代码逻辑,太麻烦,并且,最好每一层只处理该层需要做的事情,session对象是控制层传递的,所以就把session对象定义封装在控制层中,不需要在业务层中额外处理,这样可以降低耦合

2.创建一个AddressServiceImpl类实现接口中抽象方法

@Service
public class IAddressServiceImpl implements IAddressService {

    @Autowired
    private AddressMapper addressMapper;


    //在添加用户的收货地址的业务层依赖于DistrictService的业务层接口
    @Autowired
    private IDistrictService districtService;

    /**
     * 为了方便日后修改最大收货地址数量,可以在配置文件
     * application.properties中定义user.address.max-count=20
     */
    @Value("${user.address.max-count}")
    private Integer MaxAddress ;


    @Override
    public void addAddress(Integer uid, String username, Address address) {
        //查询收货地址信息是否大于20
        Integer count = addressMapper.countAddress(uid);
        if(count >= MaxAddress) {
            throw new AddressCountLimitException("收货地址不能超过20条");
        }

        //设置信息
        address.setUid(uid);
        Integer isDelete = count == 0 ? 1 : 0;//1表示默认收货地址,0反之
        address.setIsDefault(isDelete);
        address.setCreatedTime(new Date());
        address.setCreatedUser(username);
        address.setModifiedTime(new Date());
        address.setModifiedUser(username);

        //对address对象中的数据进行补全:省市区
        String provinceName = districtService.getNameByCode(address.getProvinceCode());
        String cityName = districtService.getNameByCode(address.getCityCode());
        String areaName = districtService.getNameByCode(address.getAreaCode());
        address.setProvinceName(provinceName);
        address.setCityName(cityName);
        address.setAreaName(areaName);


        //插入收货地址
        Integer row = addressMapper.insertAddress(address);
        if(row != 1) {
            throw new InsertException("未知错误 在 新建收货地址");
        }
    }
}

别忘了在配置文件application.properties中定义user.address.max-count=20

3 单元测试

在test下的service文件夹下创建AddressServiceTests测试类

@SpringBootTest
@RunWith(SpringRunner.class)
public class AddressServiceTests {
    @Autowired
    private IAddressService addressService;

    @Test
    public void addNewAddress() {
        Address address = new Address();
        address.setPhone("175726");
        address.setName("男朋友");
        addressService.addNewAddress(11,"mxy",address);
    }
}

5.控制层[Controller]

1 处理异常

义务层抛出了收货地址总数超出上限的异常,在BaseController中进行捕获处理

else if (e instanceof AddressCountLimitException) {
    result.setState(4003);
    result.setMessage("用户的收货地址超出上限的异常");
}

2 设计请求

  • /addresses/add_new_address
  • post
  • Address address,HttpSession session
  • JsonResult<Void>

3. 处理请求

在controller包下创建AddressController并继承BaseController,该类用来处理用户收货地址的请求和响应文章来源地址https://www.toymoban.com/news/detail-698405.html

/**
 * 用户收货地址
 */
@RestController
@RequestMapping("/address")
public class AddressController extends BaseController {

    @Autowired
    private IAddressService addressService;


    /**
     * 新增用户收货地址
     *
     * @param address
     * @param session:这里使用session 是为了获取用户的uid和username
     * @return
     */
    @PostMapping("/add_new_address")
    public JsonResult<Void> addAddress(Address address, HttpSession session) {
        //先获取用户uid和username
        Integer uid = getuidFromSession(session);
        String username = getUsernameFromSession(session);
        addressService.addAddress(uid, username, address);
        return new JsonResult<>(OK);
    }
}

6.前端页面

		$("#btn-add-new-address").click(function (){
			$.ajax({
				url:"/address/add_new_address",
				type:"POST",
				data:$("#form-add-new-address").serialize(),
				dataType:"JSON",
				success(e){
					if(e.state==200){
						alert("新增收货地址成功")
					}else{
						alert("新增收货地址失败")
					}
				},
				error(xhr){
					alert("新增收货地址产生未知的异常"+xhr.status)
				}
			})
		})

到了这里,关于SpringBoot项目--电脑商城【新增收货地址】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot项目--电脑商城【加入购物车】

    1.使用use命令先选中store数据库 2.在store数据库中创建t_cart用户数据表 在entity包下创建购物车的Cart实体类并使其继承BaseEntity 1.向购物车表中插入商品数据的SQL语句 2.如果当前商品已经在购物车存在,则直接更新商品即可 3.在插入或者更新具体执行哪个语句,取决于数据库中是否

    2024年02月09日
    浏览(60)
  • 基于springboot框架的电脑商城项目(八)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 这里需要将商品表和购物车表进行连表查询 2.设计接口和抽象方法 在store包下创建一个vo包,在该包下面创建CartVO类,不需要继承BaseController类,那相应的就需要单独实现Serializa

    2024年02月05日
    浏览(39)
  • 基于springboot框架的电脑商城项目(四)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 在store数据库中创建t_address表 在entity包下创建实体类Address继承baseEntity类 1.规划sql 1.新增收货地址对应的是插入语句: 2.大部分平台都会规定一个用户的收货地址数量,这里规定最多20个

    2024年02月03日
    浏览(36)
  • 基于springboot框架的电脑商城项目(九)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 用户在购物车列表页中通过随机勾选相关的商品,在点击\\\"结算\\\"按钮后跳转到\\\"确认订单页\\\",在这个页面中需要展示用户在上个页面所勾选的\\\"购物车列表页\\\"中对应的数据.且展示

    2024年02月05日
    浏览(35)
  • 基于springboot框架的电脑商城项目(六)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 在删除之前判断该数据是否存在,需要执行查询语句看能否查到该数据,还需要根据返回的aid获取uid并和session中的uid进行比较判断归属是否正确,这一条SQL语句在设置收货地址时

    2024年02月03日
    浏览(45)
  • 基于springboot框架的电脑商城项目(五)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划需要执行的SQL语句 其中order by is_default DESC是为了让默认收货地址展示在最上面,order by可以有多个子句,中间用逗号隔开,后面加的create_time DESC是为了让非默认收货地址创建的越晚

    2024年02月03日
    浏览(34)
  • 基于springboot框架的电脑商城项目(七)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 根据商品id显示商品详情的SQL语句 2.设计接口和抽象方法 在ProductMapper接口中添加抽象方法 在ProductMapper.xml文件中配置findById(Integer id)方法的映射 2.规划异常 如果商品数据不存

    2024年02月05日
    浏览(41)
  • 基于springboot框架的电脑商城项目(二)

    当用户输入用户名和密码将数据提交给后台数据库进行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。 1.规划sql语句 依据用户提交的用户名和密码做select查询。 2.设计接口和抽象方法 在

    2024年02月05日
    浏览(35)
  • 基于springboot框架的电脑商城项目(十)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 在store数据库中创建t_order和t_order_item数据表 在entity包下创建Order实体类并继承BaseEntity类 在com.cy.store.entity包下创建OrderItem实体类并继承BaseEntity类 1.规划sql 插入订单数据的SQL语句 插入

    2024年02月06日
    浏览(34)
  • 【五一创作】基于springboot框架的电脑商城项目(三)

    1.规划sql 根据用户id修改信息的SQL语句 根据用户id查询的sql语句 2.接口与抽象方法 更新用户的信息方法的定义 在UserMapper.xml文件中进行映射编写 设计两个功能: 1.当打开页面时显示当前登录的用户的信息 2.点击修改按钮时更新用户的信息 1.异常规划 点击个人资料页面时可能找

    2024年02月04日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包