5 MP实现Service封装
5.1 MP封装Service介绍
5.1.1 说明
MybatisPlus为了开发更加快捷,对业务层也进行了封装,直接提供了相关的接口和实现类;
我们在进行业务层开发时,可以继承它提供的接口和实现类,使得编码更加高效;
5.1.2 实现流程
- 定义一个服务扩展接口,该接口继承公共接口IService;
- 定义一个服务实现类,该类继承ServiceImpl<Mapper,Entity>,并实现自定义的扩展接口;
注意事项:
1.ServiceImpl父类已经注入了UserMapper对象,名称叫做baseMapper,所以当前实现类直接可以使用baseMapper完成操作
2.因为ServiceImpl已经实现了IService下的方法,所以当前服务类没有必要再次实现思想:共性的业务代码交给框架封装维护,非共性的业务,在接口UserService定义,然后在当前的服务类下实现;
5.2 MP封装Service快速入门
代码实现:
5.2.1 定义服务扩展接口
//在公共接口的基础上扩展
public interface UserService extends IService<User> {
}
5.2.2 定义服务实现
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
5.2.3 测试测试
package com.itheima;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.omg.PortableInterceptor.USER_EXCEPTION;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* @Description
* @Created by itheima
*/
@SpringBootTest
public class MpTestService {
@Autowired
private UserService userService;
/**
* @Description 测试查询操作 根据id查询
*/
@Test
public void test1(){
User user = userService.getById(3l);
System.out.println(user);
}
}
5.3 MP封装Service实现CRUD操作
服务层API的封装大致与持久层一致:
/**
* @Description 测试条件查询,且仅返回一个
* getOne:sql查询的结果必须为1条或者没有,否则报错 !!!!
*/
@Test
public void test2(){
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
wrapper.gt(User::getAge,20);
User one = userService.getOne(wrapper);
System.out.println(one);
}
/**
* @Description 根据条件批量查询
*/
@Test
public void test3(){
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
wrapper.gt(User::getAge,20);
List<User> list = userService.list(wrapper);
System.out.println(list);
}
/**
* @Description 根据条件批量查询并分页
*/
@Test
public void test4(){
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
wrapper.gt(User::getAge,20);
//构建分页对象
IPage<User> page=new Page<>(2,3);
userService.page(page,wrapper);
System.out.println(page.getRecords());
System.out.println(page.getPages());
System.out.println(page.getTotal());
}
/**
* @Description 测试服务层save保存单条操作
*/
@Test
public void test5(){
User user1 = User.builder().name("wangwu").userName("laowang4").
email("444@163.com").age(20).password("333").build();
boolean isSuccess = userService.save(user1);
System.out.println(isSuccess?"保存成功":"保存失败");
}
/**
* @Description 测试服务层批量保存
*/
@Test
public void test6(){
User user2 = User.builder().name("wangwu2").userName("laowang2").
email("444@163.com").age(20).password("333").build();
User user3 = User.builder().name("wangwu3").userName("laowang3").
email("444@163.com").age(20).password("333").build();
boolean isSuccess = userService.saveBatch(Arrays.asList(user2, user3));
System.out.println(isSuccess?"保存成功":"保存失败");
}
/**
* @Description 根据id删除操作
*/
@Test
public void test7(){
boolean isSuccess = userService.removeById(17l);
System.out.println(isSuccess?"保存成功":"保存失败");
}
/**
* @Description 根据条件批量删除
*/
@Test
public void test8(){
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class);
wrapper.gt(User::getId,12)
.gt(User::getAge,20);
boolean remove = userService.remove(wrapper);
System.out.println(remove);
}
/**
* @Description 测试根据id更新数据
*/
@Test
public void test9(){
//UPDATE tb_user SET password=?, t_name=? WHERE id=?
User user2 = User.builder().name("wangwu2").password("333").id(3l).build();
boolean success = userService.updateById(user2);
System.out.println(success);
}
/**
* @Description 测试根据条件批量更新
*/
@Test
public void test10(){
LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(User.class);
//UPDATE tb_user SET age=? WHERE (id IN (?,?,?))
wrapper.in(User::getId,Arrays.asList(1l,3l,5l)).set(User::getAge,40);
boolean update = userService.update(wrapper);
System.out.println(userService);
}
6 MP代码生成器
6.1 开发现状
开发中当有一个新的业务要实现时,通常我们需要构建一下信息:
-
定义PO类
数据库表和实体类的映射 Java Bean,打各种mp的注解。
-
定义DAO层
需要编写接口 Mapper ,接口 Mapper 需要去继承 MP 中的 BaseMapper 接口。
-
定义Service层
编写 Service 层接口和实现类。
业务接口需要去继承 MP 中的 IService,业务实现类需要继承 MP 中的 ServiceImpl 和 实现业务接口。
-
定义Controller层
编写 Controller 并标注 Spring MVC 中的相关注解。
显然上述存在固定的流程,且存在大量重复操作,you now 代码价值低且没效率!
6.2 MP逆向工程介绍
针对目前开发的现状,MP的代码生成器就可以一展身手了;
通过MP代码生成器可以生成模板性的代码,减少手工操作的繁琐,使开发人员聚焦于业务开发之上,提升开发效率;
AutoGenerator 类是MyBatis-Plus 的核心代码生成器类,通过 AutoGenerator 可以快速生成 Mapper接口、Entity实体类、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
6.3 代码生成
参考代码:资料\mp_generator
或者是gitee开源链接:https://gitee.com/jitheima/mp_generator.git
完整代码:
说明:以后在项目中使用时,先在本工程生成,然后就可以把代码拷贝到对应的项目目录中使用