zoukankan      html  css  js  c++  java
  • java-mybaits-00401-Mapper-输入输出

    Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

    1、parameterType(输入类型)

    1.1、#{}与${}

    #{}
      实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符即?。
      使用占位符#{}可以有效防止sql注入
      在使用时不需要关心参数值的类型,mybatis会自动进行java类型和jdbc类型的转换
      可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
    <!-- 根据id查询用户信息 -->
        <select id="findUserById" parameterType="int" resultType="user">
           select * from user where id = #{id}
        </select>
    ${}
      和#{}不同,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换
      可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
      使用${}不能防止sql注入,但是有时用${}会非常方便,如下的例子:
    <!-- 根据名称模糊查询用户信息 -->
        <select id="selectUserByName" parameterType="string" resultType="user">
           select * from user where username like '%${value}%'
        </select>
     如果本例子使用#{}则传入的字符串中必须有%号,而%是人为拼接在参数中,显然有点麻烦,如果采用${}在sql中拼接为%的方式则在调用mapper接口传递参数就方便很多。 
    //如果使用#{}占位符号则必须人为在传参数中加% 
    List<User> list = userMapper.selectUserByName("%管理员%"); 
    //如果使用${}原始符号则不用人为在参数中加%
    List<User>list = userMapper.selectUserByName("管理员");
    再比如order by排序,如果将列名通过参数传入sql,根据传的列名进行排序,应该写为:
    ORDER BY ${columnName}
    如果使用#{}将无法实现此功能。

    1.2、传递简单类型

    参考上边的例子。

    1.3、传递pojo对象

     Mybatis使用ognl表达式解析对象字段的值,如下例子:
    <!—传递pojo对象综合查询用户信息 -->
        <select id="findUserByUser" parameterType="user" resultType="user">
           select * from user where id=#{id} and username like '%${username}%'
        </select>
    上边红色标注的是user对象中的字段名称。
     注意参数名称,如果不一致,会产生异常。

    1.4、传递pojo包装对象

              开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

    1.4.1、定义包装对象

    定义包装对象将查询条件(pojo)以类组合的方式包装起来。
    Vo:视图层对象
    Po:持久层
    Pojo:自定义的综合体
    完成用户信息的综合查询,需要传入查询条件很复杂(可能包括用户信息、其它信息,比如商品、订单的)
    package com.lhx.mybatis.po;
    
    public class QueryVo {
        private User user;
        // 自定义用户扩展类
        private UserCustom userCustom;
        private String ordercode;
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        public UserCustom getUserCustom() {
            return userCustom;
        }
        public void setUserCustom(UserCustom userCustom) {
            this.userCustom = userCustom;
        }
        public String getOrdercode() {
            return ordercode;
        }
        public void setOrdercode(String ordercode) {
            this.ordercode = ordercode;
        }
        
    }
    View Code

    如果用户需要扩展

    package com.lhx.mybatis.po;
    
    public class UserCustom extends User {
        private String phone;
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
        
    }
    View Code

    1.4.2 mapper.xml映射文件

        <select id="findUserList" parameterType="com.lhx.mybatis.po.QueryVo" 
        resultType="com.lhx.mybatis.po.User">
        select * from user where #{user.username} and sex=#{user.sex} 
        </select>
    View Code

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

    说明:mybatis底层通过ognl从pojo中获取属性值:#{user.username},user即是传入的包装对象的属性。queryVo是别名,即上边定义的包装对象类型。

    1.4.3、编写Mapper

        public List<User> findUserList(QueryVo queryVo) throws Exception;

    1.5、传递hashmap

    Sql映射文件定义如下:

    <!-- 传递hashmap综合查询用户信息 -->
    <select id="findUserByHashmap" parameterType="hashmap" resultType="com.lhx.mybatis.po.User">
      select * from user where id=#{id} and username like '%${username}%'
    </select>

    上边红色标注的是hashmap的key。
    测试: 
        public void testFindUserByHashmap() throws Exception {
            // 获取session
            SqlSession session = sqlSessionFactory.openSession();
            // 获限mapper接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 构造查询条件Hashmap对象
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("id", 1);
            map.put("username", "管理员");
    
            // 传递Hashmap对象查询用户列表
            List<User> list = userMapper.findUserByHashmap(map);
            // 关闭session
            session.close();
        }
    View Code
    异常测试:
    传递的map中的key和sql中解析的key不一致。
    测试结果没有报错,只是通过key获取值为空。

    2、resultType(输出类型)

    2.1  输出简单类型

    参考getnow输出日期类型,看下边的例子输出整型: 
    Mapper.xml文件
    <!-- 获取用户列表总数 -->
        <select id="findUserCount" parameterType="user" resultType="int">
           select count(1) from user
        </select>
    Mapper接口
    public int findUserCount(User user) throws Exception;
    调用:
    public void testFindUserCount() throws Exception{
           //获取session
           SqlSession session = sqlSessionFactory.openSession();
           //获取mapper接口实例
           UserMapper userMapper = session.getMapper(UserMapper.class);
       
           User user = new User();
           user.setUsername("管理员");
     
           //传递Hashmap对象查询用户列表
           int count = userMapper.findUserCount(user);
          
           //关闭session
           session.close();
        }
    View Code
    总结:
    输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。
    使用session的selectOne可查询单条记录。

    2.2  输出pojo对象

    参考findUserById的定义:
    Mapper.xml
       <!-- 根据id查询用户信息 -->
        <select id="findUserById" parameterType="int" resultType="user">
           select * from user where id = #{id}
        </select>
    Mapper接口: 
    public User findUserById(int id) throws Exception;
    测试:
    public void testFindUserById() throws Exception {
           //获取session
           SqlSession session = sqlSessionFactory.openSession();
           //获限mapper接口实例
           UserMapper userMapper = session.getMapper(UserMapper.class);
           //通过mapper接口调用statement
           User user = userMapper.findUserById(1);
           System.out.println(user);
           //关闭session
           session.close();
        }
    View Code
    使用session调用selectOne查询单条记录。

    2.3  输出pojo列表 

    参考selectUserByName的定义:
    Mapper.xml
    <!-- 根据名称模糊查询用户信息 -->
        <select id="findUserByUsername" parameterType="string" resultType="user">
           select * from user where username like '%${value}%'
        </select>
    Mapper接口:
    public List<User> findUserByUsername(String username) throws Exception;

    测试:

    public void testFindUserByUsername()throws Exception{
           //获取session
           SqlSession session = sqlSessionFactory.openSession();
           //获限mapper接口实例
           UserMapper userMapper = session.getMapper(UserMapper.class);
           //如果使用占位符号则必须人为在传参数中加%
           //List<User> list = userMapper.selectUserByName("%管理员%");
           //如果使用${}原始符号则不用人为在参数中加%
           List<User> list = userMapper.findUserByUsername("管理员");
           //关闭session
           session.close();
        }
    使用session的selectList方法获取pojo列表。

    2.4  resultType总结:

    使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
    如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
    只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
     
    输出pojo对象和输出pojo列表在sql中定义的resultType是一样的。
    返回单个pojo对象要保证sql查询出来的结果集为单条,内部使用session.selectOne方法调用,mapper接口使用pojo对象作为方法返回值。
     
    返回pojo列表表示查询出来的结果集可能为多条,内部使用session.selectList方法,mapper接口使用List<pojo>对象作为方法返回值。

    2.5  输出hashmap

    输出pojo对象可以改用hashmap输出类型,将输出的字段名称作为map的key,value为字段值。

    3、resultMap

             resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
             如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
             resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

    3.1  Mapper.xml定义

        <select id="findUserListResultMap" parameterType="com.lhx.mybatis.po.QueryVo"
            resultMap="userListMap">
            select id id_,username username_ from user where
            #{user.username} and
            sex=#{user.sex}
        </select>

    使用resultMap指定上边定义的personmap。

    3.2  定义resultMap

    由于上边的mapper.xml中sql查询列和Users.java类属性不一致,需要定义resultMap:userListResultMap将sql查询列和Users.java类属性对应起来
        <resultMap type="com.lhx.mybatis.po.User" id="userListMap">
            <id column="id_" property="id"></id>
            <result column="username_" property="username"></result>
        </resultMap>

    <id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。
    Property:表示类的属性。
    Column:表示sql查询出来的字段名。
    Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
    <result />:普通结果,即pojo的属性。

    3.3  Mapper接口定义 

    public List<User> findUserListResultMap(QueryVo queryVo) throws Exception;

    3.4 测试

    public void testFindUserListResultMap() throws Exception {
            // 获取session
            SqlSession session = sqlSessionFactory.openSession();
            // 获限mapper接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);
            QueryVo queryVo = new QueryVo();
            User user = new User();
            user.setUsername("张");
            user.setSex("女");
            queryVo.setUser(user);
            // 传递Hashmap对象查询用户列表
            List<User> list = userMapper.findUserListResultMap(queryVo);
            // 关闭session
            session.close();
        }
    View Code

     小结

    使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
    如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
     
     
     
     
     
     
  • 相关阅读:
    自定义事件 Event 、CustomEvent的使用
    移动端适配方案总结
    @media screen媒体查询实现页面自适应布局
    判断页面所有图片加载完成后执行操作
    JQ选择器篇2
    JQ 选择器篇1
    sql 日期转换字符大法
    SQL server从入门精通----3种分页
    SQL server从入门精通----触发器
    SQL server从入门精通---- 事务
  • 原文地址:https://www.cnblogs.com/bjlhx/p/6820593.html
Copyright © 2011-2022 走看看