在Mybatis里有一個叫TypeHandler的類型處理器,我們常見的PO當中的這些成員變量的數據類型,它都有對應的處理器,因此它就能自動實現這些Java數據類型與數據庫類型的相互轉換。
它里面還有一個叫EnumOrdinalTypeHandler的枚舉處理器,但是它不能幫我們把這個枚舉跟數據庫里面的int做轉換。MybatisPlus對這些類型處理器做了擴展,加入了幾個類型處理器,其中有一個叫MybatisEnumTypeHandler是Mybatis枚舉的一個類型處理器,還有一個叫AbstractJsonTypeHandler顧名思義就是JSON類型的處理器。也就是說這兩個處理器,一個用來處理枚舉類型,一個用來處理JSON類型的。
要使用MybatisEnumTypeHandler枚舉類型處理器分兩步。
1.首先將來我們要把這個枚舉轉成int存到數據庫,所以要告訴mp哪個是對應的數據庫里面的這個int。我們要把這個成員變量標記出來,mp提供了一個注解@EnumValue,把它加到枚舉對應數據庫字段的值上面。那么將來它就知道了原來枚舉中的這個value的值和數據庫對應的,它就會拿這兩個往數據庫里面去寫,查詢的時候就反過來操作。
2.讓MybatisEnumTypeHandler枚舉處理器生效。
package com.itheima.mp.service.impl;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.itheima.mp.domain.po.Address;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.AddressVO;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.enums.UserStatus;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;import java.util.*;
import java.util.stream.Collectors;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic void deductBalance(Long id, Integer money) {//1.查詢用戶User user = getById(id);//2.校驗用戶狀態if(user == null || user.getStatus() == UserStatus.FROZEN){throw new RuntimeException("用戶狀態異常!");}//3.校驗余額是否充足if(user.getBalance() < money){throw new RuntimeException("用戶余額不足!");}//4.扣減余額update tb_user set balance = balance - ?int remainBalance = user.getBalance()-money;lambdaUpdate().set(User::getBalance,remainBalance).set(remainBalance == 0,User::getStatus,UserStatus.FROZEN).eq(User::getId,id).eq(User::getBalance,user.getBalance())//樂觀鎖.update();}@Overridepublic List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {return lambdaQuery().like(name != null,User::getUsername,name).eq(status != null,User::getStatus,status).gt(minBalance != null,User::getBalance,minBalance).lt(maxBalance != null,User::getBalance,maxBalance).list();}@Overridepublic UserVO queryUserAndAddressById(Long id) {//1.查詢用戶User user = getById(id);if(user == null || user.getStatus() == UserStatus.NORMAL){throw new RuntimeException("用戶狀態異常!");}//2.查詢地址List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, id).list();//3.封裝VO//3.1.轉User的PO為VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//3.2.轉地址VOif (CollUtil.isNotEmpty(addresses)){userVO.setAddress(BeanUtil.copyToList(addresses, AddressVO.class));}return userVO;}@Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {//1.查詢用戶List<User> users = listByIds(ids);if (CollUtil.isEmpty(users)){return Collections.emptyList();}//2.查詢地址//2.1.獲取用戶id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());//2.2.根據用戶id查詢地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();//2.3.轉換地址VOList<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);//2.4.用戶地址集合分組,相同用戶的放入一個集合(組)中Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);if (CollUtil.isNotEmpty(addressVOList)){addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}//3.轉換VO返回List<UserVO> list = new ArrayList<>(users.size());for (User user : users) {//3.1.轉化User的PO為VOUserVO vo = BeanUtil.copyProperties(user, UserVO.class);list.add(vo);//3.2.轉換地址VOvo.setAddress(addressMap.get(user.getId()));}return list;}
}
?枚舉默認在做JSON數據格式處理的時候,就會以英文名返回,就是枚舉項的名字。那如果說你想讓它以value返回,也就是1和2返回,或者是以desc這個中文返回,那么你就需要告訴我們程序,我們這個程序的數據往前端返回由Spring MVC處理,Spring MVC 底層它在處理JSON的時候用到一個Jackson包,Jackson它提供一些注解用來標記這個枚舉里面的值到底把誰進行返回。
?