Mybatis案例

1、模拟业务方法 根据用户id查询用户的角色和角色中的权限

  // 1、模拟业务方法 根据用户id查询用户的角色和角色中的权限
    public static UserVO selectUserById(Long userId) {
        SqlSession sqlSession = getSqlSession();
        UserDao userDao = getDao(UserDao.class, sqlSession);
        // 第一步:先根据用户id把用户的userVO查出来
        UserVO userVO = userDao.selectByPK(userId);
        String roles = userVO.getRoles();// 这个字符串就是以逗号分隔的角色id
        if (!isEmpty(roles)) {
            String[] split = roles.split(",");// 很可能报空指针异常
            // 第二步查询角色
            RoleDao roleDao = getDao(RoleDao.class, sqlSession);
            List<RoleVO> roleVOS = roleDao.selectRoleVOSByIds(split);
            // 这里设置角色,后边在设置权限也是可以的
            userVO.setRoleVOList(roleVOS);// 把查询出来的角色放到user对象里边,那么user对象就有了角色
            // 第三步,根据角色查询权限
            // 入门做法:做优化:一定在查询的时候,尽量查询次数,避免使用for循环去查询数据库,这种方式容易理解,但是性能不高,比联表查询还低。
            PermissionDao permissionDao = getDao(PermissionDao.class, sqlSession);

            // 封装查询参数集合
            // 先准备一个要查询的所有权限的id集合,用set集合来接收。
            Set<String> permissionSet = new HashSet<>();
            for (RoleVO r : roleVOS) {// 如果循环一百次,那么就要连接数据库一百次(连接数据库实际上是比较消耗时间)
                String permissions = r.getPermissions();// 这个是代表权限的字符串id,用逗号分隔的。
                if (!(isEmpty(permissions))) {
                    String[] pIds = permissions.split(",");
                    Collections.addAll(permissionSet, pIds);// 把当前权限id加到参数集合里边去(这个时间是忽略不计的,因为是在内存中进行的)
                }
            }
            // 封装查询参数集合
            // 一口气把所有要的权限全部查询出来(执行查询)

            if (permissionSet != null && permissionSet.size() > 0) {// 才做这一波操作
                List<PermissionVO> permissionVOS = permissionDao.selectPermissVOSByCollection(permissionSet);
                // 由于这样查询出来的权限是所有角色共同拥有的,所以需要将权限进行分组操作。
                Map<Integer, List<PermissionVO>> map = permissionVOS.stream().collect(Collectors.groupingBy(Permission::getPermissionId));
                // java8特性之流处理,就是要根据角色id分组
                for (RoleVO r : roleVOS) {// 如果循环一百次,那么就要连接数据库一百次(连接数据库实际上是比较消耗时间)
                    String permissions = r.getPermissions();// 这个是代表权限的字符串id,用逗号分隔的。
                    if (!(isEmpty(permissions))) {
                        String[] pIds = permissions.split(",");
                        List<PermissionVO> currentPermissionVOS = new ArrayList<>();// 准备一个权限集合,给这个角色放置权限
                        for (String pId : pIds) {// 每一个Pid就是一个权限id
                            List<PermissionVO> permissionVOS1 = map.get(Integer.valueOf(pId));// 取到的是一组权限
                            if (permissionVOS1 != null && permissionVOS1.size() > 0) {
                                PermissionVO permissionVO = permissionVOS1.get(0);
                                currentPermissionVOS.add(permissionVO);// 把取出来的权限放进当前角色的权限集合里边。
                            }
                        }
                        r.setPermissionVOS(currentPermissionVOS);// 把当前权限设置给这个角色
                    }
                }
            }

            userVO.setRoleVOList(roleVOS);
        }
        return userVO;
    }

    private static boolean isEmpty(String roles) {
        return "".equals(roles) || roles == null;
    }
    

常用方法

    public static <T> T getDao(Class<T> cls, SqlSession sqlSession) {
        // 第三步:调用sqlSession 增删改查方法完成数据库的相关操作。
        T mapper = sqlSession.getMapper(cls);
        // sqlSession.close();
        return mapper;
    }

    public static SqlSession getSqlSession() {
        // 第一步:去加载mybatis的配置文件 得到SqlSessionFactory
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(TestMybatis.class.getClassLoader().getResourceAsStream("mybatis/mybatisConfig.xml"));
        // 第二步:拿到qlSessionFactory 紧接着拿到sqlSession对象
        return sqlSessionFactory.openSession();
    }

    public static String collectionToStringWithSeparator(Collection c, String... separator) {
        String s = ",";// 默认就用逗号拆分
        if (separator != null && separator.length > 0) {
            s = separator[0];
        }
        StringBuffer buffer = new StringBuffer();
        for (Object o : c) {
            buffer.append(o.toString()).append(s);
        }
        if (buffer.length() > 0) {
    

3、将一些角色添加到用户的角色里边。

public static boolean addRolesToUser(List<Role> roles, User u) {
        // 1、到底是在数据库呢还是不在数据库呢?
        // 2、每个角色一定会有相应的权限ids 所以,我们就先根据 ids去角色表里边查看 角色是否存在,如果不存在这个角色就创建这个角色,如果存在,就直接把角色id给这个用户就行了
        // 为了方便大家理解,我们就假设添加的角色全是新的角色。
        // 首先应该 先把角色批量插入到数据库之中,然后得到每一个角色的id,然后再将每一个角色的id给当前用户
        SqlSession sqlSession = getSqlSession();
        RoleDao roleDao = getDao(RoleDao.class, sqlSession);
        Set<String> roleIds = new HashSet<>();// 这个集合就是新增的角色id集合
        int x = 0;
        for (Role role : roles) {// 但是跟新操作的时候,这个性能差距不大。查询的时候才避免for循环,如果非要提升性能,可以用mybatis的foreach循环插入
            // insert into 表名 values (列值1,列值2),(列值1,列值2),(列值1,列值2),(列值1,列值2)
            int i = roleDao.insertSelective(role);// 正常情况下i==1
            x += i;
            if (i == 1) {
                roleIds.add(role.getRoleId().toString());// 由于mybatis会自动将主键赋值给当前插入的对象,所以这里是能够取到角色的id的
            }
        }
        // 要把用户本身的角色取出来
        UserDao userDao = getDao(UserDao.class, sqlSession);
        User dbUser = userDao.selectByPrimaryKey(u.getUserId());
        String roles1 = dbUser.getRoles();
        if (!isEmpty(roles1)) {
            String[] split = roles1.split(",");
            Collections.addAll(roleIds, split);
        }
        StringBuffer buffer = new StringBuffer();
        for (String roleId : roleIds) {
            buffer.append(roleId).append(",");
        }
        if (buffer.length() > 0) {
            buffer.delete(buffer.length() - 1, buffer.length());// 删除最后一个逗号
        }
        User updateUser = new User();
        updateUser.setUserId(u.getUserId());
        updateUser.setRoles(buffer.toString());// 1,2,3,4
        int y = userDao.updateByPrimaryKeySelective(updateUser);
        sqlSession.commit(); // 提交事务操作。
        sqlSession.close();// 关闭sqlSession
        return y == 1 && x == roles.size();
    }

4、用一些角色从用户角色里边移除

    
    public static boolean removeRolesFromUser(List<Role> roles, User u) {
        // 1、先查出用户本身拥有的角色=>变成set1集合
        // 2、把传进来的角色也同样变成set2集合,然后两个集合做差集, (set1-set2)
        // 3、把查集又变回id字符串
        // 4、修改用户角色字段
        SqlSession sqlSession = getSqlSession();
        UserDao dao = getDao(UserDao.class, sqlSession);

        UserVO userVO = dao.selectUserById(u.getUserId());
        // 双击66,用户本身的角色集合
        Set<Integer> collect = userVO.getRoleVOList().stream().map(Role::getRoleId).collect(Collectors.toSet());
        Set<Integer> collect2 = roles.stream().map(Role::getRoleId).collect(Collectors.toSet());
        // 现在假如我记得不得方法??
        // 从集合里边移除元素的时候,千万不能用for循环!不然就要报ConcurrentModificationException

        Iterator<Integer> iterator = collect.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            for (Integer integer1 : collect2) {
                if (next.equals(integer1)) {
                    iterator.remove();// 这才是正确的从集合里边移除元素
                }
            }
        }
        String s = collectionToStringWithSeparator(collect);// 就是用户现在的角色字符串
        User updateUser = new User();
        updateUser.setUserId(u.getUserId());
        updateUser.setRoles(s);
        boolean b = dao.updateByPrimaryKeySelective(updateUser) == 1;
        sqlSession.commit();
        sqlSession.close();
        return b;
    }

// 5、批量根据商家id查询商户的是所有商品,并且商品需要带上商品类型

 public static List<MerchantVO> getMerchantsGoods(List<MerchantVO> list) throws Exception {
        SqlSession sqlSession = getSqlSession();
        GoodsDao goodsDao = getDao(GoodsDao.class, sqlSession);
        if (list != null && list.size() > 0) {
            List<GoodsVO> listVos = goodsDao.getMerchantsGoods(list);// 得到了所有商户的商品
            GoodsTypeDao goodsTypeDao = getDao(GoodsTypeDao.class, sqlSession);
            if (listVos != null && listVos.size() > 0) {
                List<GoodsTypeVO> goodsTypeVOS = goodsTypeDao.selectByCollection(listVos);
                Map<Long, List<GoodsTypeVO>> collect = goodsTypeVOS.stream().collect(Collectors.groupingBy(GoodsTypeVO::getGoodsTypeId));
                for (GoodsVO listVo : listVos) {
                    List<GoodsTypeVO> goodsTypeVOS1 = collect.get(listVo.getGoodsTypeId());
                    if (goodsTypeVOS1 != null && goodsTypeVOS1.size() > 0) {
                        listVo.setGoodsType(goodsTypeVOS1.get(0));
                    }
                }

            }
            Map<Long, List<GoodsVO>> collect = listVos.stream().collect(Collectors.groupingBy(GoodsVO::getMerchantId));// 得到了所有根据商户id分组的商品
            for (MerchantVO merchantVO : list) {
                List<GoodsVO> goodsVOS = collect.get(merchantVO.getMerchantId());// 从map里边取出这一组(当前商户id对应的)的商品
                merchantVO.setGoodsVOS(goodsVOS);
            }


        } else {
            throw new Exception("你集合都不传,让我查什么呀!");
        }
        return list;
    }

7、根据用户id查询用户半年之内的订单,包含订单详情

    public static List<OrderVO> getUserOrderVOByUserId(Long userId) {
        SqlSession sqlSession = getSqlSession();
        SgOrderDao sgOrderDao = getDao(SgOrderDao.class, sqlSession);
        OrderQuery query = new OrderQuery();
        query.setUserId(userId);
        Date endDate = new Date();
        query.setEndDate(endDate);
        Date startDate = MyDateUtil.getDateAddNumbers(endDate, Calendar.MONTH, -6);
        query.setStartDate(startDate);

        List<OrderVO> resList = sgOrderDao.selectOrdersByQuery(query);
        OrderItemDao orderItemDao = getDao(OrderItemDao.class, sqlSession);
        return getOrderVOS(resList, orderItemDao);// 将订单集合传进去,查询出订单详情,而后把订单详情设置给传进来的订单集合
    }


    /**
     * @param resList      已经查询出来的订单集合
     * @param orderItemDao 操作订单详情的dao
     * @return
     */
    private static List<OrderVO> getOrderVOS(List<OrderVO> resList, OrderItemDao orderItemDao) {
        if (resList != null && resList.size() > 0) {
            List<OrderItemVO> orderItemVOS = orderItemDao.selectItemsByOrders(resList);
            Map<Long, List<OrderItemVO>> collect = orderItemVOS.stream().collect(Collectors.groupingBy(OrderItemVO::getOrderId));
            for (OrderVO od : resList) {
                od.setOrderItemVOS(collect.get(od.getOrderId()));
            }
        }

        return resList;
    }

8、根据商户id查询商户三个月之内的所有订单,以及所有订单的实际付款总价。

    // 8、根据商户id查询商户三个月之内的所有订单,以及所有订单的实际付款总价。

    public static MerchantVO getMerchantLatestOrders(Long merchantId) {
        SqlSession sqlSession = getSqlSession();
        MerchantDao merchantDao = getDao(MerchantDao.class, sqlSession);
        MerchantVO merchantVO = merchantDao.selectByPk(merchantId);// 查询出商户了
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setMerchantId(merchantId);
        Date endDate = new Date();
        Date startDate = MyDateUtil.getDateAddNumbers(endDate, Calendar.MONTH, -3);
        orderQuery.setStartDate(startDate);
        orderQuery.setEndDate(endDate);
        SgOrderDao sgOrderDao = getDao(SgOrderDao.class, sqlSession);

        List<OrderVO> orderVOS = sgOrderDao.selectOrdersByQuery(orderQuery);

        orderVOS = getOrderVOS(orderVOS, getDao(OrderItemDao.class, sqlSession));

        merchantVO.setOrderVOS(orderVOS);

        BigDecimal x = BigDecimal.ZERO;
        for (OrderVO od : orderVOS) {
            x = x.add(od.getActuallyPaid());
        }
       // BigDecimal reduce = orderVOS.stream().map(SgOrder::getActuallyPaid).reduce(x, BigDecimal::add);


        merchantVO.setAllActuallyPaid(x);

        return merchantVO;
    }

9、根据经纬度,查询用户当前经纬度 圆形范围内5公里的所有商户

  public List<MerchantVO> getMerchantsByRange(MerchantQuery query) {
        SqlSession sqlSession = getSqlSession();
        MerchantDao merchantDao = getDao(MerchantDao.class, sqlSession);
        List<MerchantVO> list = merchantDao.selectByQuery(query);
        Iterator<MerchantVO> iterator = list.iterator();

        while (iterator.hasNext()) {// 过滤四个角的距离超出的商家
            MerchantVO next = iterator.next();
            double distance = MathUtil.distance(query.getLng(), query.getLat(), next.getLng(), next.getLat()) * 0.001;
            if (distance > query.getLength()) {// 这个商家就远了
                iterator.remove();
            }
        }
        return list;
    }

11、根据批量的商户,查询出这堆商户中,每个商户卖的最好的商品。(有点难)

  //  11、根据批量的商户,查询出这堆商户中,每个商户卖的最好的商品。(有点难)

    public static List<MerchantVO> selectMerchantBestGoods(List<MerchantVO> list) {

        SqlSession sqlSession = getSqlSession();
        GoodsDao goodsDao = getDao(GoodsDao.class, sqlSession);
        List<GoodsVO> goodsVOS = goodsDao.selectMerchantBestGoods(list);

        Map<Long, List<GoodsVO>> collect = goodsVOS.stream().collect(Collectors.groupingBy(GoodsVO::getMerchantId));
        for (MerchantVO m : list) {
            List<GoodsVO> goodsVOS1 = collect.get(m.getMerchantId());
            if (goodsVOS1 != null && goodsVOS1.size() > 0) {
                m.setBestGoods(goodsVOS1.get(0));
            }
        }
        return list;
    }

sql

 <select id="selectMerchantBestGoods" resultType="com.qianfeng.study.pojo.vo.GoodsVO">
        select g.goods_id, g.merchant_id, g.pic, g.title, g.old_price, g.now_price, g.sold from goods
        g
        where g.merchant_id in
        <foreach collection="ids" open="(" close=")" item="m" separator=",">
            #{m.merchantId}
        </foreach>
        and g.on_sale=1
        and g.sold=(select max(sold) from goods where merchant_id=g.merchant_id)
        limit 1
    </select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值