栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

day01-mp框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

day01-mp框架

1、什么是mp,优点是什么?

Mybatis-plus框架,简称mp。mp是mybatis的一种增强工具。
优点:简化开发,提高开发效率;在只用到单表操作的业务环境下,不需要写crud;不需要构建mapper的映射文件        

2、如何使用mp?

1)数据库环境准备【mp_db】
2)创建SpringBoot工程,引入MybatisPlus的启动依赖【mybatis-plus-boot-starter】


        
        
            mysql
            mysql-connector-java
            5.1.26
        
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.1
        
    

3)在yml中编写DataSource相关配置【spring的jdbc】
 

4)编写mapper【mapper接口需要继承一个类,这个类已经实现了单表的各种操作,所以无需再构建单表操作的映射文件】

5)测试【增、删、改、查】

3、实体类注解,简化开发

@TableId:指定当前表的主键【主键生成策略】

  1.  标识实体类中主键对应属性;
  2.  定义主键生成策略;【type=
    *          IdType.NONE/ASSIGN_ID:默认情况下使用雪花算法
    *          IdType.AUTO:使用数据库的主键自增
    *          IdType.INPUT:由用户自己指定主键大小
    *          ASSIGN_UUID:使用UUID生成一个全局唯一字符串
    】

@TableField:指定 java类的属性 和 数据库字段 的映射【属性名和表列名不一致】

@TableName("tb_user") // 指定表名
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    
    @TableId(type = IdType.AUTO)
    private Long id;
    private String userName;//数据库:user_name   驼峰映射
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String password;//数据库:password    名称一样
    
    @TableField("t_name")
    private String name;//数据库里是t_name,必须用注解映射
    private Integer age;//数据库:password    名称一样
    // 忽略此字段
    private String email;
}

      

4、mp单表的增删改 增:insert(T)
//【1】插入操作:insert()
    @Test
    public void testInsert(){
        User user = User.builder().userName("liuyan")
                .age(23)
                .email("liuyan@163.com")
                .name("柳岩")
                .password("123456")
                .build();
        int i=userMapper.insert(user);
        if (i>0) {
            System.out.println("添加成功!");
        }
    }
删:deleteById(int id);         deleteBatchIds(List list)         deleteByMap(Map map);       
//【2】删除操作
    //1.根据id删除:deleteById(int i)
    @Test
    public void testDelete01(){
        int id=22;
        int i=userMapper.deleteById(id);
        if(i>0)
            System.out.println("删除成功!");
    }
    //2.根据id集合删除:deleteBatchIds(List list)
    @Test
    public void testDelete02(){
        ArrayList listId = new ArrayList<>();
        Collections.addAll(listId,23,24,25);//一次性添加多个元素
        int i=userMapper.deleteBatchIds(listId);
        if(i>0)
            System.out.println("删除成功!");
    }
    //3.根据map构成条件删除:deleteByMap(Map map)
    @Test
    public void testDelete03(){
        HashMap map = new HashMap<>();
        //map集合作为删除条件【键=数组库字段名  值=数组库字段值】
        map.put("user_name","liuyan");
        int i=userMapper.deleteByMap(map);
        if(i>0)
            System.out.println("删除成功!");
    }
改:updateById(T)
只更新实体类中存在的数据,如果对应的属性为null,不更新;
/【3】更改操作:updateById
    //只更新实体类中存在的数据,如果对应的属性为null,不更新;
    @Test
    public void testUpdate(){
        //根据主键更新
        User user=User.builder().id(16L).userName("zhaoqishang").build();
        int i=userMapper.updateById(user);
        if(i>0)
            System.out.println("修改成功!");
        else
            System.out.println("修改失败!");
    }
5、mp单表的查询【分页、逻辑、模糊、排序、限定】

       1) 分页查询(无条件):selectPage(Page,null)

        【1】配置类:分页拦截器    {在主配置类中设置Bean}

@Configuration
@MapperScan("com.itheima.mapper")
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,-1不受限制
        paginationInterceptor.setMaxLimit(-1L);
        interceptor.addInnerInterceptor(paginationInterceptor);
        return interceptor;
    }
}

        【2】先分页、再查询、最后获取分页信息

@Test
    public void testPageSelect(){
        //1、设置分页:每页5条,初始展示第1页【先分页再查询】
        Page page = new Page<>(1,5);
        //2、开始查询; 参数1:页面设置;参数2:条件设置,相当于sql中where语句【此处无条件,null】
        Page userPage = userMapper.selectPage(page,null);
        //3、获取分页查询后的数据信息
        // 获取分页数据信息
        List userList = page.getRecords();
        for (User user : userList) {
            System.out.println(user);
        }
        // 当前页
        long current = page.getCurrent();
        System.out.println("当前页数是:"+current);
        // 每页显示条数
        long size = page.getSize();
        System.out.println("每页数据数量:"+size);
        // 总条数
        long total = page.getTotal();
        System.out.println("当前查询数据总数:"+total);
        // 总页数
        long pages = page.getPages();
        System.out.println("总共页数:"+pages);
    }

        2)模糊查询:selectList(wrapper) + 逻辑转换符

        逻辑转换符:

@Test
    public void testQueryWrapper(){
        //1、建立QueryWrapper对象  泛型为User
        QueryWrapper wrapper = new QueryWrapper<>();
        //2、条件筛选
        wrapper.like("user_name","伤")
                .eq("password","123456")
                .in("age",19,25,29)
                .orderByDesc("age");
        //3、查询所有:selectList()
        List users = userMapper.selectList(wrapper);
        //4、遍历
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
解析:QueryWrapper对象相当于sql语句中where条件,但是它的限制——
QueryWrapper查询数据时,需要手写对应表的 数据库字段,
一旦之后更改了数据库的列名,也就是表结构更改后,那么对应的代码修改量也会变大,维护性较差
[改进方案]____:
LamQueryWrapper 查询数据时,用实体类的get()方法 代替 数据库字段
例如:
    eq("id",18)         >>  eq(User::getId,18)
    in("age",(1,2,3))   >>  in(User::getAge,(1,2,3))
//上述查询用LambdaQueryWrapper()完善后
    @Test
    public void testLambdaQueryWrapper(){
        //1、建立QueryWrapper对象  泛型为User
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        //2、条件筛选
        wrapper.like(User::getName,"伤")
                .eq(User::getPassword,"123456")
                .in(User::getAge,19,25,29)
                .orderByDesc(User::getAge);
        //3、查询所有:selectList()
        List users = userMapper.selectList(wrapper);
        //4、遍历
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
3)逻辑查询: or[or()]
 @Test
    public void testLambdaQueryWrapper02(){
        //1、建立QueryWrapper对象  泛型为User
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        //2、条件筛选
        wrapper.like(User::getName,"伤")
                .or()
                .in(User::getAge,19,25,29)
                .orderByDesc(User::getAge);
        //3、查询所有:selectList()
        List users = userMapper.selectList(wrapper);
        //4、遍历
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
     逻辑转换符or:主动调用or(),说明下一个方法为【或条件】,默认就是and连接!
 
【4】排序查询: orderByAsc()     orderByDesc() 
@Test
    public void testLambdaQueryWrapper03(){
        //1、建立QueryWrapper对象  泛型为User
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        //2、条件筛选
        wrapper.orderByAsc(User::getAge)
               .orderByDesc(User::getId);
        //3、查询所有:selectList()
        List users = userMapper.selectList(wrapper);
        //4、遍历
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
【5】限定查询:select()
 @Test
    public void testLambdaQueryWrapper04(){
        //1、建立QueryWrapper对象  泛型为User
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        //2、条件筛选
        wrapper.like(User::getName,"伤")
                .or()
                .in(User::getAge,19,25,29)
                .orderByDesc(User::getAge)
                .select(User::getId,User::getName);
        //3、查询所有:selectList()
        List users = userMapper.selectList(wrapper);
        //4、遍历
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
【5】分页条件查询:selectPage(Page,LambdaQueryWrapper)
 
@Test
    public void testLambdaQueryWrapper05(){
        //1、建立QueryWrapper对象和Page对象  泛型为User
        Page page = new Page<>(2,3);//【先分页再查询】
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        //2、条件筛选
        wrapper.like(User::getName,"伤")
                .or()
                .in(User::getAge,19,25,29)
                .orderByDesc(User::getAge)
                .select(User::getId,User::getName);
        //3、分页条件查询:selectPage()
        Page userPage = userMapper.selectPage(page,wrapper);
        //4、获取分页数据信息:getRecords()
        List userList = page.getRecords();
        for (User user : userList) {
            System.out.println(user);
        }
        long current = page.getCurrent();
        System.out.println("当前页数是:"+current);
        // 每页显示条数
        long size = page.getSize();
        System.out.println("每页数据数量:"+size);
        // 总条数
        long total = page.getTotal();
        System.out.println("当前查询数据总数:"+total);
        // 总页数
        long pages = page.getPages();
        System.out.println("总共页数:"+pages);
    }
6、mp封装service层
MP实现Service封装【所有的crud在参数中就已经实现!】
1.定义一个服务扩展接口,该接口继承公共接口IService;
2.定义一个服务实现类,该类继承ServiceImpl,并实现自定义的扩展接口;

注意事项:
  1.ServiceImpl父类已经注入了UserMapper对象,名称叫做baseMapper,
    所以当前实现类直接可以使用baseMapper完成操作
  2.因为ServiceImpl已经实现了IService下的方法,所以当前服务类没有必要再次实现

主要Api:
增——
save(T):boolean 保存单条操作【增加操作】
saveBatch(Collection):boolean 批量保存操作【批量增加】
删——
removeById(Serializable):boolean 根据id删除
removeByMap(Map):boolean 根据指定条件删除
改——
updateById(T):boolean 根据id更新【如果id不存在,更新失败】
update(Wrapper):boolean 根据wrapper条件更新【wrapper只是筛选条件,要想更新必须set:wrapper.set】
查——
getById(Serializable):T  根据id查询
listByIds(Collection lsit):List 根据id集合查询
getOne(Wrapper):T 根据指定条件,查询符合条件的某一条信息
list(Wrapper):List 根据指定条件,查询所有符合改条件的信息
page(E,Wrapper):E 将E按照条件Wrapper分页查询

目的: 

  • 开发更加快捷,对业务层也进行了封装Service层注入mapper ; 
  • 业务层开发时,提供的接口和实现类,编码更加高效

操作步骤:

1.定义一个服务扩展接口,该接口继承公共接口IService;

public interface UserService extends IService {
}

2.定义一个服务实现类,该类继承ServiceImpl,并实现自定义的扩展接口;

@Service
//继承在前,实现在后
public class UserServiceImpl 
extends ServiceImpl 
implements UserService{}

使用: 测试类中使用时不需要注入mapper,但是Service。实际应用中,因为业务开发都在Service层中,所以不需要@Autowired注入,只要定义一个Service的对象即可

下面主要Api的测试:

//【1】 save(T):boolean 保存单条操作【增加操作】
    @Test
    public void testUserService01(){
        User user1 = User.builder().name("wangwu1").userName("laowang2").
                email("444@163.com").age(20).password("333").build();
        boolean isSuccess = userService.save(user1);
        System.out.println(isSuccess?"保存成功":"保存失败");
    }
    //【2】saveBatch(Collection):boolean 批量保存操作【批量增加】
    @Test
    public void testUserService02(){
        User user1 = User.builder().name("wangwu2").userName("laowang2").
                email("444@163.com").age(20).password("333").build();
        User user2 = User.builder().name("wangwu3").userName("laowang3").
                email("444@163.com").age(20).password("333").build();
        
        boolean isSuccess = userService.saveBatch(Arrays.asList(user1, user2));
        System.out.println(isSuccess?"保存成功":"保存失败");
    }
    //【3】removeById(Serializable):boolean 根据id删除
    @Test
    public void testUserService03(){
        int id=31;
        boolean result = userService.removeById(id);
        System.out.println("result = " + result);
    }
    //【4】removeByMap(Map):boolean 根据指定条件删除
    @Test
    public void testUserService04(){
        HashMap map = new HashMap<>();
        map.put("id","32");
        boolean result = userService.removeByMap(map);
        System.out.println("result = " + result);
    }
    //【5】updateById(T):boolean 根据id更新一条数据【如果id不存在,更新失败】
    @Test
    public void testUserService05(){
        //将id为30的user_name修改为:老王
        User user = User.builder().userName("老王").id(30L).build();
        boolean result = userService.updateById(user);
        System.out.println("result = " + result);
    }
    //【6】update(Wrapper):boolean 根据wrapper条件批量更新【wrapper.set】
    @Test
    public void testUserService06(){
        //将id为{1,3,5}的age修改为:40       LambdaUpdateWrapper实现
        LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(User::getId,Arrays.asList(1l,3l,5l)).set(User::getAge,40);
        boolean result = userService.update(wrapper);
        System.out.println("result = " + result);
    }
    //【7】根据id查询
    @Test
    public void testUserService07(){
        int id=15;
        User user = userService.getById(id);
        System.out.println("user = " + user);
    }
    //【8】listByIds(Collection lsit):List 根据id集合批量查询
    @Test
    public void testUserService08(){
        ArrayList list = new ArrayList<>();
        Collections.addAll(list,1,3,5);
        List userList = userService.listByIds(list);
        for (User user : userList) {
            System.out.println("user = " + user);
        }
    }
    //【9】getOne(Wrapper):T 根据指定条件,查询符合条件的某一条信息
    //    ***getOne:sql查询的结果必须为1条或者没有,否则报错 !!!!***
    @Test
    public void testUserService09(){
        //查询年龄<19的用户【必须只有一个,如果有多个用户年龄<19,查询报错!!】
        // LambdaQueryWrapper实现
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(User::getAge, 19);
        User one = userService.getOne(wrapper);
        System.out.println(one);
    }
    //【10】list(Wrapper):List 根据指定条件,查询所有符合改条件的信息
    @Test
    public void testUserService10(){
        //查询id:1~5中,年龄=20的用户
        // LambdaQueryWrapper实现
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        ArrayList idList = new ArrayList<>();
        Collections.addAll(idList,1,2,3,4,5);
        wrapper.in(User::getId,idList).eq(User::getAge,20);
        List userList = userService.list(wrapper);
        for (User user : userList) {
            System.out.println("user = " + user);
        }
    }
    //【11】page(E,Wrapper):E 将E按照条件Wrapper分页查询    先分页,在查询
    @Test
    public void testUserService11(){
        //1.Page分页
        Page userPage = new Page<>(1, 4);
        //2.Wrapper条件筛选
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(User::getAge,35);
        //3.查询
        Page page = userService.page(userPage, wrapper);
        //4.获取分页信息
        System.out.println(page.getRecords());//记录内容
        System.out.println(page.getPages());//总页数
        System.out.println(page.getTotal());//当前查询到的记录数量
    }
7、mp自动填充字段
应用场景:插入或者更新数据时,希望有些字段可以自动填充数据,比如密码、version等。例如:初始注册的用户,密码默认都是123456
怎么用?【@TableField的fill属性+配置】
    【1】在需要pojo类中,需要自动填充的字段上添加注解:
        @TableField并设置属性fill,fill本质是一个枚举四种权限————
        DEFAULT,默认不处理
        INSERT,插入时填充字段
        UPDATE,更新时填充字段
        INSERT_UPDATE,插入和更新时填充字段【常用!】
    【2】编写配置类,实现MetaObjectHandler接口
//插入时,自动填充
    @Test
    public void testQueryUesrById01() {
        User user = User.builder().age(18)
                .email("aa@itheima.com")
                .name("小明2")
                .password("1234")
                .age(18)
                .build();
        userMapper.insert(user);
    }
    //更新时,自动填充
    @Test
    public void testQueryUesrById02() {
        User user = User.builder().age(18)
                .email("aa@itheima.com")
                .name("小明2222222")
                .age(18)
                .id(39L)
                .build();
        userMapper.updateById(user);
    }

 

8、mp代码生成器

两种方式:

idea插件【Mybatis】   或   

代码脚本:https://gitee.com/jitheima/mp_generator.git 【推荐,自由度高,泛用性广】

 

        
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/936857.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号