mybatis输入映射、输出映射

mybatis比较重要的就是输入映射和输出映射了

一 、输入映射

输入映射可以是简单数据类型,可以是包装类也可以是hashmap,下面主要分享下包装类

应用场景:用于复杂的综合查询的时候,比如商城中查询订购某个商品的用户有多少
,就需要构建我们的包装类,用于组装我们的查询条件,传入到对应statement中执行综合查询sql

实现下这个简单的例子,项目采用的是mapper代理模式开发,如果不懂的可以查看我的写的mybatis原始dao开发和mapper代理开发,整个项目数据库只用到了user表来演示如何封装的

1.1先建立包装类

package cn.eugene.po;

public class UserQueryVo {
    private UserCustom userCustom;

    public UserCustom getUserCustom() {
        return userCustom;
    }
    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }
    @Override
    public String toString() {
        return "UserQueryVo [userCustom=" + userCustom + "]";
    }   
       //下面可以封装商品类和订单类

}

包装类很简单,就是将普通类作为一个属性进行封装,这里使用的是UseCutom没有使用User,由于正式开发中可以采用自动化工具程序自动生成po类,一般不会去修改po类,我们可以使用一个类来拓展po类,这里我们使用UserCustom来代替User

package cn.eugene.po;

public class UserCustom extends User{

}
package cn.eugene.po;

public class User {
    private int id;
    private String userName;
    private String userAge;
    private String userAddress;
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    /**
     * @return the id
     */
    public int getId() {
        return id;
    }
    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }
    /**
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }
    /**
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }
    /**
     * @return the userAge
     */
    public String getUserAge() {
        return userAge;
    }
    /**
     * @param userAge the userAge to set
     */
    public void setUserAge(String userAge) {
        this.userAge = userAge;
    }
    /**
     * @return the userAddress
     */
    public String getUserAddress() {
        return userAddress;
    }
    /**
     * @param userAddress the userAddress to set
     */
    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", userAge=" + userAge + ", userAddress=" + userAddress
                + "]";
    }   
}

1.2 编写statement

  
     

这里需要格外的注意,新手犯错误一般是在这个地方
1.sql语句要写对
2.设计到的变量要写对,比如这里是userCustom.userName ,userCutom是UserQueryVo的属性,userName是userCutom的属性,写了程序就会报错
比如写成了UserCustom.userName,程序报错找不到UserCustom这个属性

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'UserCustom' in 'class cn.eugene.po.UserQueryVo'
### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'UserCustom' in 'class cn.eugene.po.UserQueryVo'
.........

写成userCustom.Name报错找不到Name这个属性

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'userCustom.name'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: cn.eugene.po.UserCustom.name
### Cause: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'userCustom.name'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: cn.eugene.po.UserCustom.name
......

1.3编写 mapper接口和测试类

注意遵循使用mapper接口的规范

    public List findUserList(UserQueryVo userQueryVo) throws Exception;

编写测试类

     //用户综合信息查询
    @Test
    public void testFindUserList() throws Exception {       
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mybatis自动生成接口实现类代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);             
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setUserName("运费");
        userQueryVo.setUserCustom(userCustom);
        List list = userMapper.findUserList(userQueryVo);
        System.out.println(list);
    }

这个例子中只封装了User类,也可以在UserQuery中封装其他综合查询的类如商品订单,从而实现综合查询

输出映射

2.1 输出简单类型

需求:用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。

mapper.xml

      
     

mapper.java

public int findUserCount(UserQueryVo userQueryVo) throws Exception;

测试代码

                @Test
        public void testFindUserCount() throws Exception {
            
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //mybatis自动生成接口实现类代理对象
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            
            
            UserQueryVo userQueryVo = new UserQueryVo();
            UserCustom userCustom = new UserCustom();
            userCustom.setUserName("运费");
            userQueryVo.setUserCustom(userCustom);
            int count  = userMapper.findUserCount(userQueryVo);
            System.out.println("count: "+count);
        }

2.2 输出pojo和pojo列表

不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的。
在mapper.java指定的方法返回值类型不一样:
1、输出单个pojo对象,方法返回值是单个对象类型

public  User findUserById(int id) throws Exception;

2、输出pojo对象list,方法返回值是List

public List findUserList(UserQueryVo userQueryVo) throws Exception;

2.3 resultmap

a、 为什么需要使用

  • 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功
  • 如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
  • 只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象
    当查询出来的列名和pojo属性名不一致的时候,会创建pojo对象,但部分值会为null,因为这部分的值和sql查询出来的值对应不上,如果解决对应这个问题呢?
    mybatis框架为我们提供了resultmap

mybatis中使用resultMap完成高级输出结果映射。

b、resultMap使用方法

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

1、定义resultMap

2、使用resultMap作为statement的输出映射类型

2.4 具体例子

需求: 将下面sql使用resultmap完成映射,User类中属性名和查询列名不一致。

select id id_,userName userName_  from user where id =#{id}

a、定义resultmap

  
    
        
        
        
        
    

b、使用resultMap作为statement的输出映射类型

    
    

c、mapper.java

public User findUserById2(int id) throws Exception;

d、测试代码

    @Test
    public void testFindUserById2() throws Exception {
        
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mybatis自动生成接口实现类代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById2(1);
        System.out.println(user);
    }

从例子中可以看出,resultMap起到映射或则说对应的作用,当sql语句查询出来的列名和pojo属性名不一致的时候,可以使用resultMap来对应,resultMap作为statement的输出映射,resultMap同时映射到对应的Java对象

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