Skip to content

数据库操作

niucloud 常规数据库操作采用 MyBatis-PlusMyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。针对联表查询使用 MyBatis-Plus-Join,MyBatis-Plus-Join 是一个基于 MyBatis-Plus 的多表查询扩展库。它通过提供简洁的 API 和强大的查询构建器,极大地简化了多表关联查询的复杂性。无论是简单的连表查询还是复杂的一对一、一对多查询,MyBatis-Plus-Join 都能提供优雅的解决方案。本节重点讲解基本的数据库增删改查操作,然后下一节数据库查询,单独讲解查询方法。

MyBatis-Plus 与 MyBatis-Plus-Join 介绍

关于 MyBatis-Plus 的优势以及常用方法可以查看 MyBatis-Plus 手册。下面针对 niucloud 中常用数据的增删改查进行讲解

Mapper 层设计

数据表 mapper 继承 Mybatis-Plus 的 BaseMapper,也可以继承 Mybatis-Plus-Join 的 MPJBaseMapper,一般为了后期联表查询方便使用 MPJBaseMapper

例如:

java
package com.niu.core.mapper.shop;

import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.shop.SiteShop;
import org.apache.ibatis.annotations.Mapper;

/**
 * 店铺扩展表 Mapper
 */
@Mapper
public interface SiteShopMapper extends MPJBaseMapper<SiteShop> {
}

基本增删改查操作

数据添加

数据添加使用 insert 方法,注意 SaaS 系统站点 id 不是实际参数传入的,而是通过 RequestUtils 获取 siteId

例如下面店铺扩展信息添加:

java
    /**
     * 店铺扩展信息添加
     *
     * @param param 参数
     */
    public void add(SiteShopParam param) {
        // 检查是否已存在
        Long count = siteShopMapper.selectCount(
            new QueryWrapper<SiteShop>().eq("site_id", RequestUtils.siteId())
        );
        if (count > 0) {
            throw new CommonException("该站点已存在店铺扩展信息");
        }

        SiteShop siteShop = new SiteShop();
        // 设置参数
        siteShop.setSiteId(RequestUtils.siteId());
        siteShop.setIsSelf(param.getIsSelf());
        siteShop.setIsRecommend(param.getIsRecommend());
        siteShop.setCategoryId(param.getCategoryId());
        siteShop.setContactMobile(param.getContactMobile());
        siteShop.setFollowNumber(0);
        siteShop.setCreateTime(System.currentTimeMillis() / 1000);

        siteShopMapper.insert(siteShop);
    }

数据编辑

数据编辑使用 update 方法,如果传入主键 id 编辑使用 updateById 方法

例如店铺扩展信息编辑:

java
    /**
     * 店铺扩展信息编辑
     *
     * @param id 主键ID
     * @param param 参数
     */
    public void edit(Integer id, SiteShopParam param) {
        // 查询店铺信息
        SiteShop siteShop = siteShopMapper.selectOne(
            new QueryWrapper<SiteShop>()
                .eq("id", id)
                .eq("site_id", RequestUtils.siteId())
        );

        Assert.notNull(siteShop, "店铺扩展信息不存在!");

        // 更新参数
        siteShop.setIsSelf(param.getIsSelf());
        siteShop.setIsRecommend(param.getIsRecommend());
        siteShop.setCategoryId(param.getCategoryId());
        siteShop.setContactMobile(param.getContactMobile());
        siteShop.setUpdateTime(System.currentTimeMillis() / 1000);

        siteShopMapper.updateById(siteShop);
    }

数据删除

数据删除使用 delete 方法,一般单条删除,传入主键,或者对应条件

例如店铺扩展信息删除:

java
    /**
     * 店铺扩展信息删除
     *
     * @param id 主键ID
     */
    public void del(Integer id) {
        siteShopMapper.delete(
            new QueryWrapper<SiteShop>()
                .eq("id", id)
                .eq("site_id", RequestUtils.siteId())
        );
    }

数据查询

数据列表分为分页列表查询以及常规列表查询,注意分页列表返回数据结构 PageResult,常规列表直接使用查询的列表即可

下面是店铺扩展信息分页列表以及常规列表代码:

java
    /**
     * 店铺扩展信息分页列表
     *
     * @param pageParam 分页参数
     * @param searchParam 搜索参数
     * @return PageResult<SiteShopListVo>
     */
    @Override
    public PageResult<SiteShopListVo> page(PageParam pageParam, SiteShopSearchParam searchParam) {
        Integer page  = pageParam.getPage();
        Integer limit = pageParam.getLimit();

        MPJQueryWrapper<Site> queryWrapper = new MPJQueryWrapper<>();
        queryWrapper.select("ns.site_id, ns.site_name, ns.group_id, ns.keywords, ns.app_type, ns.logo, ns.`desc`, ns.status, ns.latitude, ns.longitude, ns.province_id, ns.city_id, ns.district_id, ns.address, ns.full_address, ns.phone, ns.business_hours, ns.create_time, ns.expire_time, ns.front_end_name, ns.front_end_logo, ns.front_end_icon, ns.icon, ns.member_no, ns.app, ns.addons, ns.initalled_addon, ns.site_domain, ns.isinit, nsg.group_name, nss.id, nssc.category_name, nss.is_recommend, nss.is_self, nss.contact_mobile, nss.category_id, nss.commission_rate, nss.shop_deposit, nss.money, nss.money_get, nss.money_cash_outing, nss.bank_type, nss.bank_account_name, nss.bank_account_no, nss.bank_name, nss.bank_address, nss.follow_number, nss.alipay_name, nss.alipay_account_no, nss.alipay_payment_code, nss.wechat_name, nss.wechat_account_no, nss.wechat_payment_code, nss.business_license")
                .setAlias("ns")
                .leftJoin("?_site_shop nss ON ns.site_id = nss.site_id".replace("?_", GlobalConfig.tablePrefix))
                .leftJoin("?_site_group nsg ON ns.group_id = nsg.group_id".replace("?_", GlobalConfig.tablePrefix))
                .leftJoin("?_site_shop_category nssc ON nss.category_id = nssc.category_id".replace("?_", GlobalConfig.tablePrefix));

        if (ObjectUtil.isNotEmpty(searchParam.getCreateTime())) {
            QueryMapperUtils.buildByTime(queryWrapper, "ns.create_time", searchParam.getCreateTime());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getGroupId())) {
            queryWrapper.eq("nss.group_id", searchParam.getGroupId());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getCategoryId())) {
            queryWrapper.eq("nss.category_id", searchParam.getCategoryId());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getStatus())) {
            queryWrapper.eq("ns.status", searchParam.getStatus());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getIsSelf())) {
            queryWrapper.eq("nss.is_self", searchParam.getIsSelf());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getKeyword())) {
            queryWrapper.and(i -> i.or(j -> j.like("ns.site_name", searchParam.getKeyword()))
                    .or(j-> j.like("ns.keywords", searchParam.getKeyword()))
            );
        }
        queryWrapper.orderByDesc("ns.create_time");
        IPage<SiteShopListVo> iPage = siteMapper.selectJoinPage(new Page<>(page, limit), SiteShopListVo.class, queryWrapper);
        for (SiteShopListVo item : iPage.getRecords()) {
            SiteShopListVo.SiteShop shop = new SiteShopListVo.SiteShop();
            BeanUtils.copyProperties(item, shop);
            item.setShop(shop);
        }
        return PageResult.build(iPage);
    }

    /**
     * 店铺扩展信息列表
     *
     * @param searchParam 搜索参数
     * @return List<SiteShopListVo>
     */
    @Override
    public List<SiteShopListVo> list(SiteShopSearchParam searchParam) {
        MPJQueryWrapper<Site> queryWrapper = new MPJQueryWrapper<>();
        queryWrapper.select("ns.site_id, ns.site_name, ns.group_id, ns.keywords, ns.app_type, ns.logo, ns.`desc`, ns.status, ns.latitude, ns.longitude, ns.province_id, ns.city_id, ns.district_id, ns.address, ns.full_address, ns.phone, ns.business_hours, ns.create_time, ns.expire_time, ns.front_end_name, ns.front_end_logo, ns.front_end_icon, ns.icon, ns.member_no, ns.app, ns.addons, ns.initalled_addon, ns.site_domain, ns.isinit, nsg.group_name, nss.id, nssc.category_name, nss.is_recommend, nss.is_self, nss.contact_mobile, nss.category_id, nss.commission_rate, nss.shop_deposit, nss.money, nss.money_get, nss.money_cash_outing, nss.bank_type, nss.bank_account_name, nss.bank_account_no, nss.bank_name, nss.bank_address, nss.follow_number, nss.alipay_name, nss.alipay_account_no, nss.alipay_payment_code, nss.wechat_name, nss.wechat_account_no, nss.wechat_payment_code, nss.business_license")
                .setAlias("ns")
                .leftJoin("?_site_shop nss ON ns.site_id = nss.site_id".replace("?_", GlobalConfig.tablePrefix))
                .leftJoin("?_site_group nsg ON ns.group_id = nsg.group_id".replace("?_", GlobalConfig.tablePrefix))
                .leftJoin("?_site_shop_category nssc ON nss.category_id = nssc.category_id".replace("?_", GlobalConfig.tablePrefix));

        if (ObjectUtil.isNotEmpty(searchParam.getCreateTime())) {
            QueryMapperUtils.buildByTime(queryWrapper, "ns.create_time", searchParam.getCreateTime());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getGroupId())) {
            queryWrapper.eq("ns.group_id", searchParam.getGroupId());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getCategoryId())) {
            queryWrapper.eq("nss.category_id", searchParam.getCategoryId());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getStatus())) {
            queryWrapper.eq("ns.status", searchParam.getStatus());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getIsSelf())) {
            queryWrapper.eq("ns.is_self", searchParam.getIsSelf());
        }
        if (ObjectUtil.isNotEmpty(searchParam.getKeyword())) {
            queryWrapper.and(i -> i.or(j -> j.like("ns.site_name", searchParam.getKeyword()))
                    .or(j-> j.like("ns.keywords", searchParam.getKeyword()))
            );
        }
        queryWrapper.orderByDesc("ns.create_time");
        List<SiteShopListVo> list = siteMapper.selectJoinList(SiteShopListVo.class, queryWrapper);
        for (SiteShopListVo item : list) {
            SiteShopListVo.SiteShop shop = new SiteShopListVo.SiteShop();
            BeanUtils.copyProperties(item, shop);
            item.setShop(shop);
        }
        return list;
    }

关注店铺操作

下面是一个实际的业务操作示例,演示了如何更新关注数量和维护关注列表:

java
    @Override
    public void editFollowNumber(Integer siteId, Integer isFollow) {
        SiteShop siteShop = siteShopMapper.selectOne(new QueryWrapper<SiteShop>().eq("site_id", siteId));
        if (siteShop == null) {
            throw new CommonException("店铺扩展不存在");
        }
        if (isFollow.equals(1)) {
            siteShopMapper.update(null, new UpdateWrapper<SiteShop>().set("follow_number", siteShop.getFollowNumber() + 1).eq("site_id", siteId));
        } else {
            siteShopMapper.update(null, new UpdateWrapper<SiteShop>().set("follow_number", siteShop.getFollowNumber() - 1).eq("site_id", siteId));
        }
        
        // 更新关注列表
        SiteShopMember siteShopMember = siteShopMemberMapper.selectOne(
            new LambdaQueryWrapper<SiteShopMember>()
                .eq(SiteShopMember::getSiteId, siteId)
                .eq(SiteShopMember::getMemberId, RequestUtils.memberId())
        );
        
        if (siteShopMember == null) {
            siteShopMember = new SiteShopMember();
            siteShopMember.setSiteId(siteId);
            siteShopMember.setMemberId(RequestUtils.memberId());
        }
        siteShopMember.setIsFollow(Objects.equals(isFollow, 1) ? 1 : 0);
        siteShopMemberMapper.insertOrUpdate(siteShopMember);
    }

基于 MIT 协议发布