## JPA与Mybatis-Plus随意切换(不用配置,可同时使用)
* 项目持久层默认推荐使用JPA,更简单易上手,且OOP首先应满足面向对象的要求,而不是面向数据库。复杂业务逻辑需联表查询时可选择Mybatis-Plus写sql
* 不想写sql?[Spring Data JPA](https://docs.spring.io/spring-data/jpa/docs/2.0.6.RELEASE/reference/html/#jpa.query-methods.query-creation)了解一下
* JPA开发提醒(具体请了解JPA持久化上下文 参考Hibernate三种基本状态),请注意避免导致误持久化
~~~
@PersistenceContext
private EntityManager entityManager;
User u = userService.findByUsername("username");
// 清除持久上下文环境 避免后面语句导致持久化
entityManager.clear();
u.setPassword(null); // 持久化状态时此处会自动执行update语句更新至数据库中
~~~
* 复杂业务逻辑JPA联表太蛋疼?[MyBatis-Plus](http://mp.baomidou.com/)了解一下
* JPA与MybatisPlus同时使用时需注意实体类注解区别,更多请见官方文档,常用注解区别:
~~~
//表名
JPA: @Table(name = "t_user")
MP: @TableName("t_user")
//排除非表字段
JPA: @Transient
MP: @TableField(exist=false)
~~~
> 由于单表设计,批量删除默认使用循环单条删除设计,目的为了方便以后手动删除关联数据
## JPA增删改查示例
* DAO层
~~~
public interface UserDao extends XbootBaseDao<User,String> {
/**
* 通过用户名和状态获取用户
* @param username
* @param status
* @return
*/
List<User> findByUsernameAndStatus(String username, Integer status);
}
~~~
\= "select \* from t\_user where username = username and status = status"
更多JPA示例详见[Spring Data JPA官网文档](https://docs.spring.io/spring-data/jpa/docs/2.0.6.RELEASE/reference/html/#jpa.query-methods.query-creation)
* Service层
~~~
public interface UserService extends XbootBaseService<User,String> {
/**
* 通过用户名获取用户
* @param username
* @return
*/
User findByUsername(String username);
/**
* 多条件分页获取用户
* @param user
* @return
*/
Page<User> findByCondition(User user, Pageable pageable);
}
~~~
* ServiceImpl层:
~~~
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public UserDao getRepository() {
return userDao;
}
@Override
public User findByUsername(String username) {
List<User> list = userDao.findByUsernameAndStatus(username, CommonConstant.USER_STATUS_NORMAL);
if(list!=null&&list.size()>0){
return list.get(0);
}
return null;
}
@Override
public Page<User> findByCondition(User user, Pageable pageable) {
return userDao.findAll(new Specification<User>() {
@Nullable
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
Path<String> usernameField = root.get("username");
Path<String> mobileField = root.get("mobile");
Path<String> emailField = root.get("email");
Path<Integer> sexField=root.get("sex");
Path<String> departmentIdField = root.get("departmentId");
Path<Date> createTimeField = root.get("createTime");
List<Predicate> list = new ArrayList<Predicate>();
//模糊搜素
if(StrUtil.isNotBlank(user.getUsername())){
list.add(cb.like(usernameField,'%'+user.getUsername()+'%'));
}
//性别
if(user.getSex()!=null){
list.add(cb.equal(sexField,user.getSex()));
}
//补充示例 between查询
list.add(cb.between(createTimeField, 起始时间, 结束时间);
//补充示例 or查询
if(StrUtil.isNotBlank(搜索词)){
Predicate p1 = cb.like(mobileField,'%'+搜索词+'%');
Predicate p2 = cb.like(emailField,'%'+搜索词+'%');
list.add(cb.or(p1, p2));
}
//补充示例 in查询
List<String> ids = new ArrayList();
list.add(departmentIdField.in(ids));
Predicate[] arr = new Predicate[list.size()];
cq.where(list.toArray(arr));
return null;
}
}, pageable);
}
}
~~~
* Controller层:
~~~
@RestController
@RequestMapping("/user")
public class UserController extends XbootBaseController<User, String> {
@Autowired
private UserService userService;
@Override
public UserService getService() {
return userService;
}
@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
@ApiOperation(value = "多条件分页获取用户列表")
public Result<Page<User>> getByCondition(@ModelAttribute User user,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo){
Page<User> page = userService.findByCondition(user, searchVo, PageUtil.initPage(pageVo));
return new ResultUtil<Page<User>>().setData(page);
}
}
~~~
* [官方Github示例](https://github.com/spring-projects/spring-data-examples/tree/master/jpa)
## Mybaiti-Plus增删改查示例
> 已更新至3.x版本
* DAO层
~~~
public interface UserMapper extends BaseMapper<User> {
}
~~~
* Service层
~~~
public interface IUserService extends IService<User> {
}
~~~
* ServiceImpl层:
~~~
@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Autowired
private UserMapper userMapper;
}
~~~
* Controller层:
~~~
@RestController
@RequestMapping("/xboot/user")
public class UserController {
@Autowired
private IUserService iUserService;
@RequestMapping(value = "/getByPage", method = RequestMethod.GET)
@ApiOperation(value = "分页获取")
public Result<Page<User>> getByPage(@ModelAttribute PageVo page){
Page<User> data = iStudentService.page(PageUtil.initMpPage(page));
return new ResultUtil<Page<User>>().setData(data);
}
@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
@ApiOperation(value = "多条件分页获取")
public Result<IPage<User>> save(@ModelAttribute User user,
@ModelAttribute PageVo page){
QueryWrapper<User> qw = new QueryWrapper<User>();
qw.eq("name", "'王'").ne("name", "王")
.gt("age", 18).ge("age", 18)
.lt("age", 18).le("age", 18)
.between("age", 18, 30).notBetween("age", 18, 30)
.like("name", "王").notLike("name", "王")
.isNotNull("name")
.in("age",1,2,3).notIn("age",1,2,3)
.inSql("id", "select id from table where id < 3")
.groupBy("id", "name")
.orderByAsc("id", "name").orderByDesc("id", "name")
.orderBy(true, true, "id", "name")
.having("sum(age) > {0}", 11)
.or().eq("name","老王");
IPage<User> data = iUserService.page(PageUtil.initMpPage(page), qw);
return new ResultUtil<IPage<User>>().setData(data);
}
// 补充常用增删改查方法示例``
// 单条
User user = iUserService.getById(id);
// 所有
List<User> list = iUserService.list();
// 编辑或保存
iUserService.saveOrUpdate(student))
// 通过id删除
iUserService.removeById(id);
其他自行查看接口方法以及官方文档
}
~~~
* 接口官方文档[https://mp.baomidou.com/guide/crud-interface.html#mapper-crud-%E6%8E%A5%E5%8F%A3](https://mp.baomidou.com/guide/crud-interface.html#mapper-crud-%E6%8E%A5%E5%8F%A3)
* 条件构造官方文档[https://mp.baomidou.com/guide/wrapper.html](https://mp.baomidou.com/guide/wrapper.html)