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>