Mybatis-plus深入学习

1.排除非表字段的三种方式

如果不排除会遇到这种情况

解决方式:

      1.给字段加上transient,代表这是临时字段

private transient String remark;

     2. 给字段加上static

private static String remark;

    3. 是否为数据库字段,默认 true 存在,false 不存在。推荐这一种

@TableField(exist = false)
private  String remark;
  • static有一个问题,转换json的时候或者你要远程传递的属性的属性会排除在外
  • transient 被这个关键字修饰的字段,代表不会序列化到流中进行传递。比如:微服务RPC或者resttemplate传输的时候,被transient修饰的属性会自动忽略。

2.过滤掉字段不查询

      下面就代表查询的时候那个字段呗过滤不会查询

//过滤掉一个字段 content 不查询
lambdaQueryWrapper.select(Blog.class,blog->!blog.getColumn().equals("content"));
lambdaQueryWrapper.eq(Blog::getStatus,1);
List<Blog> list = this.list(lambdaQueryWrapper);

3.单表查询和关联表查询以及动态sql

        先创建两张表 博客内容表和用户表

CREATE TABLE `kss_blog` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '内容ID',
  `title` varchar(200) DEFAULT NULL COMMENT '标题',
  `content` longtext COMMENT '内容',
  `category_id` int(11) DEFAULT NULL COMMENT '分类ID',
  `category_title` varchar(100) DEFAULT NULL COMMENT '分类的标题',
  `img` varchar(200) DEFAULT NULL COMMENT '封面地址(oss文件存储)',
  `user_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `status` int(11) DEFAULT NULL COMMENT '控制内容是否在前台进行展示 0 不展示 1展示',
  `is_delete` int(1) DEFAULT NULL COMMENT '逻辑删除 0 未删除 1删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=613 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

CREATE TABLE `kss_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `nickname` varchar(100) DEFAULT NULL COMMENT '用户昵称',
  `password` varchar(60) DEFAULT NULL COMMENT '用户密码',
  `telephone` varchar(20) DEFAULT NULL COMMENT '用户手机(用于登录)',
  `email` varchar(200) DEFAULT NULL COMMENT '用户邮箱',
  `avatar` varchar(400) DEFAULT NULL COMMENT '用户头像的地址',
  `sign` varchar(100) DEFAULT NULL COMMENT '用户签名',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `active` int(1) DEFAULT NULL COMMENT '1激活 0未激活',
  `role` varchar(10) DEFAULT NULL COMMENT 'admin是超级管理员 nornal是普通用户',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

 实体类 就是对应数据库的字段就可以,驼峰命名

单表查询的需求:

1:根据用户名模糊查询用户信息 username like '%xxx%'

2:并且查询出激活的用户 active = 1

3:并且查询角色等于超级管理员 role=admin

4:查询出注册时间在某个时间段的:create_time betwwend starttime and endtime;

注意:默认情况下查询的所有的用户,只有用户操作了才开始拼接条件.

下面只是写了测试类,控制层就是和前端交互,一些变量自己到时候自己再根据情况来接受

实现上面的需求一共三种实现方式

  1. 原生的实现方案Mybatis+Xml来实现
  2. mybatis-plus加LambdaQueryWrapper来实现
  3. 采用Mybatis的Mapper+XML+LambdaQueryWrapper/QueryMapper来实现

1.第一种 基于mybatis的xml来实现

    //基于原生的mybatis xml
    @Test
    void test2() {
        User user = new User();
        user.setNickname("yykk");
        user.setActive(1);
        user.setRole("admin");
        List<User> users = userMapper.userList(user);
        for (User user1 : users) {
            System.out.println(user1);
        }
    }

 UserMapper.xml

 <select id="userList" resultType="com.neutech.ksswebproject.eneity.User">
        select * from kss_user  where 1=1
        <if test="nickname!=null and nickname!=''">
            <!--AND  nickname LIKE concat('%',#{username},'%')-->
            <bind name="keyword" value="'%' +nickname + '%'" />
            AND  nickname LIKE #{keyword}
        </if>
        <if test="role!=null and role!=''">
             and role = #{role}
        </if>

        <if test="active!=null and active!=''">
            and active = #{active}
        </if>
    </select>

2.第二种  基于mybatis-plus ,不用.xml(如果分页需要配置分页拦截器) 单表的用这种就可以

 //第二种实现方案 - 实现方案MP+LambdaQueryWrapper来实现 单表
    @Test
    void test3() {
        User user = new User();
        user.setNickname("yykk");
        user.setActive(1);
        user.setRole("admin");
        List<User> userList = findUserList(user);

    }

    public List<User> findUserList(User user) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //前面为条件,当用户姓名不为空时,才会在sql语句后面拼接
        lambdaQueryWrapper.like(user.getNickname()!=null&&user.getNickname()!="",User::getNickname,user.getNickname());
        lambdaQueryWrapper.eq(user.getRole()!=null&&user.getRole()!="",User::getRole,user.getRole());
        lambdaQueryWrapper.eq(user.getActive()!=null,User::getActive,user.getActive());
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        //分页查询
        Page<User> page = new Page<>(1,5);
        IPage<User> page1 = userMapper.selectPage(page, lambdaQueryWrapper);
        return users;
    }

3.第三种 基于mybais的xml和mybatis-plus的LambdaQueryWrapper来实现

测试类:

@Test
    void test6() {
        User user = new User();
        user.setNickname("yykk");
        user.setActive(1);
        user.setRole("admin");
        findUserList2(user);
    }

    public IPage<User> findUserList2(User user) {
        //第一种利用LambdaQueryWrapper加mybatis的xml来实现动态拼接
        // select * from kss_user ku WHERE (nickname LIKE ? AND role = ? AND active = ?) LIMIT ?
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //前面为条件,当用户姓名不为空时,才会在sql语句后面拼接
        lambdaQueryWrapper.like(user.getNickname()!=null&&user.getNickname()!="",User::getNickname,user.getNickname());
        lambdaQueryWrapper.eq(user.getRole()!=null&&user.getRole()!="",User::getRole,user.getRole());
        lambdaQueryWrapper.eq(user.getActive()!=null,User::getActive,user.getActive());
        //分页查询
        Page<User> page = new Page<>(1,5);
        IPage<User> userListPage = userMapper.userListPage(page, lambdaQueryWrapper);

        //第二种利用QueryWrapper加mybatis的xml来实现动态拼接
        // select * from kss_user ku WHERE (ku.nickname LIKE ? AND ku.role = ? AND ku.active = ? AND DATE_FORMAT(ku.create_time,'%Y') = ?) LIMIT ?
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like(user.getNickname()!=null&&user.getNickname()!="","ku.nickname",user.getNickname());
        queryWrapper.eq(user.getRole()!=null&&user.getRole()!="","ku.role",user.getRole());
        queryWrapper.eq(user.getActive()!=null,"ku.active",user.getActive());
        queryWrapper.eq("DATE_FORMAT(ku.create_time,'%Y')",2020);
        IPage<User> userListPage1 = userMapper.userListPage(page, queryWrapper);
        return userListPage1;
    }

mapper:

public interface UserMapper extends BaseMapper<User> {
  
    IPage<User> userListPage(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
}

xml:

  <select id="userListPage" resultType="com.neutech.ksswebproject.eneity.User">
    select * from kss_user ku
     ${ew.customSqlSegment}
    </select>

第三种方式单表总结:

        利用LambdaQueryWrapper可以实现动态sql的拼接,但是当如果吧表中的字段进行格式化再去当作条件查询就不能使用了 (比如:我想查询用户在2020年创建的用户信息,但是数据库的数据为2020-11-10 21:18:17,这样的时候就要利用mysql的日期函数(DATE_FORMAT(ku.create_time,'%Y'))去格式化创建日期这个字段)。利用LambdaQueryWrapper是不可以实现的,注意的是LambdaQueryWrapper也不能拼接sql的时候起别名,QueryWrapper是可以起别名的

多表查询

多表查询的需求:

1:根据用户名模糊查询用户信息 username like '%xxx%'

2:并且查询出激活的用户 active = 1

3:并且查询角色等于超级管理员 role=admin

4:查出每个用户写的博客数量(用户表和博客内容表进行关联)

        

他实现只有两种方式,但是实现分页必须借助分页插件或者自己封装一个分页类,所以还是直接用mybatis-plus自己封装的分页类。

1.基于原生的mybatis xml 关联查询

    @Test
    void test4() {
        User user = new User();
        user.setNickname("yykk");
        user.setActive(1);
        user.setRole("admin");
        List<Map<String, Object>> maps = userMapper.userList1(user);
        for (Map<String, Object> map : maps) {
            //map里面放的key值为数据库字段,value值就是对应字段的值。key值如果想不是数据库的字段,就在sql语句中起别名
            System.out.println(map.get("create_time"));
            System.out.println(map.get("num"));
        }
    }

mapper:

public interface UserMapper extends BaseMapper<User> {

    List<Map<String,Object>> userList1(User user);
}

xml:sql语句代表的含义是满足这些条件用户写的博客数量( COUNT(1) num,代表分组以后博客的数量和

<select id="userList1" resultType="java.util.Map">
      SELECT COUNT(1) num,ku.* FROM kss_blog kb LEFT JOIN  kss_user ku  ON ku.id=kb.user_id
        where 1=1
        <if test="nickname!=null and nickname!=''">
            <!--AND  nickname LIKE concat('%',#{username},'%')-->
            <bind name="keyword" value="'%' +nickname + '%'" />
            AND  nickname LIKE #{keyword}
        </if>
        <if test="role!=null and role!=''">
            and role = #{role}
        </if>

        <if test="active!=null and active!=''">
            and active = #{active}
        </if>
        GROUP BY ku.id order by num desc
    </select>

总结: 这里利用User当作条件传递值,是因为测试(当然也可以这样写),只根据用户的信息去查询用户信息和博客的信息,但如果需要博客和用户信息同时当作条件,就可以定义一个vo类,同时包括两者条件的信息。利用List<Map>的形式接收,是因为里面不只是用户的信息,还有一个用户类没有的字段,所以定义成一个map,当时也可以定义成一个vo类进行接收。这个没有分页,自己定义就比较麻烦。注意:List<Map>接收的数据,map里面放的key值为数据库字段,value值就是对应字段的值。key值如果想不是数据库的字段,就在sql语句中起别名

第二种:基于mybais的xml和mybatis-plus的LambdaQueryWrapper来实现.

  @Test
    void test5() {
        User user = new User();
        user.setNickname("yykk");
        user.setActive(1);
        IPage<Map<String, Object>> userListPage = findUserListPage(user);
    }


    public  IPage<Map<String, Object>> findUserListPage(User user) {
        //动态拼接sql
        //  WHERE (nickname LIKE ? AND active = ?) GROUP BY id ORDER BY create_time ASC LIMIT ? 
        //  %yykk%(String), 1(Integer), 2(Long)
        
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //前面为条件,当用户姓名不为空时,才会在sql语句后面拼接
        //public Children eq(boolean condition, R column, Object val) {}
        lambdaQueryWrapper.like(user.getNickname()!=null&&user.getNickname()!="",User::getNickname,user.getNickname());
        lambdaQueryWrapper.eq(user.getRole()!=null&&user.getRole()!="",User::getRole,user.getRole());
        lambdaQueryWrapper.eq(user.getActive()!=null,User::getActive,user.getActive());
        lambdaQueryWrapper.orderByAsc(User::getCreateTime);
        lambdaQueryWrapper.groupBy(User::getId);
        Page<User> page = new Page<>(1,2);
        IPage<Map<String, Object>> mapIPage = userMapper.selectUserPage(page, lambdaQueryWrapper);

        long total = mapIPage.getTotal();
        long size = mapIPage.getSize();
        List<Map<String, Object>> records = mapIPage.getRecords();
        return mapIPage;
    }

mapper:

public interface UserMapper extends BaseMapper<User> {

    IPage<Map<String,Object>>  selectUserPage(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
}

xml:

  <select id="selectUserPage" resultType="java.util.Map">
        SELECT COUNT(1) num,ku.* FROM kss_blog kb LEFT JOIN  kss_user ku  ON ku.id=kb.user_id
          ${ew.customSqlSegment}
    </select>

总结:LambdaQueryWrapper和QueryWrapper都可以实现动态sql的拼接,拼接sql的时候表中的字段的名字不相等的情况下,就可以利用LambdaQueryWrapper或者QueryWrapper来查询数据。如果有重名的数据就必须使用QueryWrapper来查询数据。并且第二种方式可以直接完成分页

学习资料:飞哥-学相伴的个人空间_哔哩哔哩_Bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值