3、输入和输出映射(mybatis笔记)

一、输入映射

  • 通过parameterType指定输入参数的类型,类型可以是简单类型、HashMappojo的包装类型。

  • 对于HashMap类型:


这里我们主要说明一下pojo包装类型的使用情况。

  • 需求:完整一个用户信息的综合查询,需要传入很多的查询条件,可能会包含用户信息,甚至一些其他的信息,比如商品、订单。针对这里的需求我们建议使用自定义的包装类型的pojo
    pojo中将复杂的条件包装进去。(工程mybatis04

UserQueryVo.java

package cn.itcast.pojo;

//包装类型
public class UserQueryVo {
    //包装所需要的查询条件
    private UserCustom userCustom ;
    //还可以包装其他的查询条件,订单、商品。

    public UserCustom getUserCustom() {
        return userCustom;
    }

    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }
}

注意:这里我们使用的UserCustom.java类是User.java类的一个增强类,当然其实这里这个类和User.java是一样的,这里主要是为了说明以后如果发现某个pojo的属性不够用,需要增强时不要直接在类中进行添加,而应该编写一个其增强类。
UserCustom.java

package cn.itcast.pojo;

//用户类的扩展类
public class UserCustom extends User{
    //可以来扩展用户的信息
}
  • 定义映射文件mapper.xml
    UserMapper.xml中定义用户信息的综合查询(查询条件复杂)。
    
    
  • 测试

UserMapperTest.java

    //用户信息综合查询测试
    @Test
    public void findUserList(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("小明");
        userQueryVo.setUserCustom(userCustom);
        
        List list = userMapper.findUserList(userQueryVo);
        
        for(UserCustom user : list){
            System.out.println(user.getUsername());
        }
        sqlSession.close();
    }

二、输出映射

2.1 resultType

当我们使用这样sql时:

select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'

我们测试发现可以映射成功,但是如果这样:

SELECT id id_, username username_, sex, birthday FROM USER 
WHERE user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'

这里凡是使用了别名的,在测试时发现都不能映射成功,但是我们在数据库中是能够使用别名的。
总结:如果使用resultType进行输出的映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功,如果全部不一致,则不会创建pojo对象,只要查询出的列名有一个一致,就会创建pojo对象。

  • 有一种需求:用户信息的综合查询列表总数,通过查询总数和上面用户综合查询列表才可以实现分页。也就是输出简单类型。
    
    

说明:查询出来的结果集只有一行且一列,才可以使用简单类型进行输出映射。

  • 输出pojo对象和pojo列表
    不管是输出的单个对象还是输出的对象列表,resultType指定的类型是一样的,不一样的是在接口中指定方法的返回值不一样,一个是User,一个是List

  • 输出HashMap
    输出pojo对象可以该用HashMap输出类型,将输出的字段名作为Mapkeyvalue为字段值。

2.2 resultMap

  • mybatis中可以使用resultMap完成高级输出结果映射,这里我们讲入门使用。

  • 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和属性名之间做一个映射。

  • 使用方法

    • 定义resultMap
    • 使用resultMap作为statement的输出映射类型
  • 需求:将下面的sql使用UserCutom完成映射

SELECT id id_, username username_ FROM USER WHERE id = #{value}

这里User类中属性名和sql中查询列名不一致。注意:resultMap的值就是下面定义的resultMapid

  • 定义resultMap
    
    
        
        
        
        
        
    

说明:这里注意唯一标识和普通属性的区别,唯一标识一般是主键。

  • 使用resultMap作为statement的输出映射类型
    
    
  • 接口
public User findUserByIdResultMap(int id );
  • 测试
    //用户信息综合查询总数测试
    @Test
    public void findUserByIdResultMap(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("小明");
        userQueryVo.setUserCustom(userCustom);
        
        User user  = userMapper.findUserByIdResultMap(1);
        System.out.println(user.getUsername());
        sqlSession.close();
        
    }

三、动态sql

mybatis的核心:对sql语句进行灵活的操作,通过表达式sql来进行判断,对sql进行灵活的拼接、组装。

3.1 需求(工程mybatis05

用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql

  • 对查询条件进行判断,如果如果输入参数不为空才进行查询条件的拼接。
    
    
    
    
    

说明:这里我们就对这两个查询进行了改造。更多的标签请参考文档。

  • 测试
    //用户信息综合查询测试
    @Test
    public void findUserList(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        //由于这里使用了动态sql,如果不设置值,条件就不会拼接到sql中
        //userCustom.setSex("1");
        //userCustom.setUsername("小明");
        userQueryVo.setUserCustom(userCustom);
        
        List list = userMapper.findUserList(userQueryVo);
        
        for(UserCustom user : list){
            System.out.println(user.getUsername());
        }
        sqlSession.close();
        
    }

3.2 需求(工程mybatis06

将上面实现sql动态判断的代码抽取出来,组成一个sql片段。其他的statement中就可以引用此sql片段。

  • 定义sql片段
    
        
            
                and user.sex = #{userCustom.sex}
            
            
                and user.username like '%${userCustom.username}%'
            
        
    

说明:

  • id : 表示sql片段的唯一标识。

  • 经验:一般定义sql片段都是基于单表定义,这样的话这个sql片段的可重用性才会很高。在sql片段中不要包括where,便于在以后进行任意组装。

  • 引用sql片段

    
    
    
    
    
  • 测试
    测试方法和之前的一样,这里不再多说。

3.3 foreach标签

如果现在向sql中传递了一个List(或数组等),mybatis使用foreach解析

  • 需求(工程mybatis07
    在用户查询列表和查询总数的statement中增加多个id输入查询。这里给出sql语句:
(1)SELECT * FROM USER WHERE ... and (id = 1 OR id = 10 OR id = 16);
(2)SELECT * FROM USER WHERE ... and id IN(1, 10, 16)

这里两个sql的功能是一样的。当然sql中可能会有多个条件。

  • 在输出的参数类型中添加List ids来传入多个id

UserQueryVo.java

package cn.itcast.pojo;
import java.util.List;

//包装类型
public class UserQueryVo {
    //传入多个id
    private List ids ;
    
    //包装所需要的查询条件
    private UserCustom userCustom ;
    //还可以包装其他的查询条件,订单、商品。

    public UserCustom getUserCustom() {
        return userCustom;
    }

    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }

    public List getIds() {
        return ids;
    }

    public void setIds(List ids) {
        this.ids = ids;
    }
    
}
  • 修改配置
    需要修改sql片段
    
    
        
            
                and user.sex = #{userCustom.sex}
            
            
                and user.username like '%${userCustom.username}%'
            
        
        
            
            
            
                
                id = #{id}
            
        
    
  • 测试
    //用户信息综合查询测试
    @Test
    public void findUserList(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        //由于这里使用了动态sql,如果不设置值,条件就不会拼接到sql中
        userCustom.setSex("1");
        //传入多个id
        List ids = new ArrayList();
        ids.add(1);
        ids.add(10);
        ids.add(16);
        userQueryVo.setIds(ids);
        userQueryVo.setUserCustom(userCustom);
        List list = userMapper.findUserList(userQueryVo);
        
        for(UserCustom user : list){
            System.out.println(user.getUsername());
        }
        sqlSession.close();
        
    }
  • 如果我们使用第二条sql则可以这样写



    #{id}

你可能感兴趣的:(3、输入和输出映射(mybatis笔记))