• MyBatis深入理解参数


    一、快速创建mapper文件

    由于每个接口都要创建一个对应的mapper文件,这个文件在IDEA中创建中没有提示,而且这个文件的整体都是一样的,所以创建一个模板,方便使用

    把自己感觉常用的代码添加进去,然后自定义名称,以及扩展名

    这样下次创建的时候就方便很多

    模板:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="">
        <select id="" resultType="">
        </select>
    </mapper>
    

    当然也可以设置主配置文件,方法和上面的类似

    二、parameterType

    dao接口中方法参数的数据类型
    值为java的数据类型全限定名称或者是mybatis定义的别名
    例:parameterType="java.lang.Integer",或者 parameterType="int"
    注意:这个一般不写,因为mybatis通过反射机制能够发现接口参数的数据类型

    例如:

        <select id="selectStudentById" resultType="com.md.domain.Student" parameterType="java.lang.Integer">
          select id , name , email , age from student where id=#{id}
        </select>
    <!--等同于-->
        <select id="selectStudentById" resultType="com.md.domain.Student" parameterType="int">
          select id , name , email , age from student where id=#{id}
        </select>
    
    

    三、MyBatis 传递参数

    1. 一个简单参数(掌握)

    Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),

    占位符 #{ 任意 字符 },和方法的参数名无关

    接口方法:

    Student selectById(int id);
    

    mapper文件

    <select id="selectById" resultType="com.md.domain.Student">
    select id,name,email,age from student where id=#{studentId}
    </select>
    

    #{studentId} , studentId 是自定义的变量名称,和方法参数名无关

    注意:

    使用#{}之后, mybatis执行sql是使用的jdbc中的PreparedStatement对象
    由mybatis执行下面的代码:

    1. mybatis创建Connection , PreparedStatement对象
                String sql="select id,name, email,age from student where id=?";
                PreparedStatement pst = conn.preparedStatement(sql);
                pst.setInt(1,1001);
    
    2. 执行sql封装为resultType="com.md.domain.Student"这个对象
                ResultSet rs = ps.executeQuery();
                Student student = null;
                while(rs.next()){
                   //从数据库取表的一行数据, 存到一个java对象属性中
                   student = new Student();
                   student.setId(rs.getInt("id"));
                   student.setName(rs.getString("name"));
                   student.setEmail(rs.getString("email"));
                   student.setAge(rs.getInt("age"));
                }
    
               return student;  //给了dao方法调用的返回值
    

    测试方法

    @Test
    public void testSelectById(){
    // 一个参数
    Student student = studentDao.selectById(1001);
    System.out.println(" 查询 id 是 1001 的学生:"+student);
    }
    

    2. 多个参数- 使用@Param(掌握)

    当 Dao 接口方法多个参数,需要通过名称使用参数。

    在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。

    接口方法

    List<Student> selectMultiParam(@Param("personName") String name,
    @Param("personAge") int age);
    

    mapper文件

    <select id="selectMultiParam" resultType="com.md.domain.Student">
    select id,name,email,age from student where name=#{personName} or age
    =#{personAge}
    </select>
    

    测试方法

    @Test
    public void testSelectMultiParam(){
    List<Student> stuList = studentDao.selectMultiParam("李白",20);
    stuList.forEach( stu -> System.out.println(stu));
    }
    

    3. 多个参数-使用对象(掌握)

    使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。

    每一个属性就是一个参数。

    常用格式 #{ property }

    1. 创建保存参数值的对象 QueryParam

    package com.md.vo;
        public class QueryParam {
        private String queryName;
        private int queryAge;
        //set , get 方法 有参无参
    }
    

    2. 接口方法:

    List<Student> selectMultiObject(QueryParam queryParam);
    

    3. mapper文件

    <select id="selectMultiObject" resultType="com.md.domain.Student">
    select id,name,email,age from student where name=#{queryName} or age
    =#{queryAge}
    </select>
    

    4. 测试方法

    @Test
    public void selectMultiObject(){
        QueryParam qp = new QueryParam();
        qp.setQueryName("白昊天");
        qp.setQueryAge(20);
        List<Student> stuList = studentDao.selectMultiObject(qp);
        stuList.forEach( stu -> System.out.println(stu));
    }
    

    4. 多个参数-按位置(了解)

    参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}
    注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。
    接口方法:

    List<Student> selectByNameAndAge(String name,int age);
    

    mapper 文件

    <select id="selectByNameAndAge" resultType="com.md.domain.Student">
    
    select id,name,email,age from student where name=#{arg0} or age =#{arg1}
    
    </select>
    
    

    测试方法:

    @Test
    
    public void testSelectByNameAndAge(){
    
    // 按位置参数
    
    List<Student> stuList = studentDao.selectByNameAndAge(" 李白",20);
    
    stuList.forEach( stu -> System.out.println(stu));
    
    }
    
    

    5. 多个参数- 使用 Map(了解)

    Map集合可以存储多个值,使用Map向mapper文件一次传入多个参数。Map集合使用String的key,
    Object 类型的值存储参数。

    mapper 文件使用 # { key } 引用参数值。

    接口方法:

    List<Student> selectMultiMap(Map<String,Object> map);
    

    mapper 文件:

    <select id="selectMultiMap" resultType="com.md.domain.Student">
    
    select id,name,email,age from student where name=#{myname} or age =#{myage}
    
    </select>
    
    

    测试方法:

    @Test
    
    public void testSelectMultiMap(){
    
    Map<String,Object> data = new HashMap<>();
    
    data.put("myname"," 李白");// #{myname}
    
    data.put("myage",20); // #{myage}
    
    List<Student> stuList = studentDao.selectMultiMap(data);
    
    stuList.forEach( stu -> System.out.println(stu));
    
    }
    
    

    6. # 和 $(重点)

    # :占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法

    mapper 文件

    <select id="selectById" resultType="com.md.domain.Student">
    
    select id,name,email,age from student where id=#{studentId}
    
    </select>
    
    

    转为 MyBatis 的执行是:

    String sql=” select id,name,email,age from student where id=?”;
    
    PreparedStatement ps = conn.prepareStatement(sql);
    
    ps.setInt(1,1005);
    
    

    解释:

    where id=? 就是 where id=#{studentId}
    
    ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
    
    

    $ 字符串替换, ,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的内容连接起来

    主要用在替换表名,列名,不同列排序等操作
    分别使用 id , email 列查询 Student
    接口方法:

    Student findById(int id);
    Student findByEmail(String email);
    

    mapper 文件:

    <select id="findById" resultType="com.md.domain.Student">
    
    select * from student where id=#{studentId}
    
    </select>
    
    <select id="findByEmail" resultType="com.md.domain.Student">
    select * from student where email=#{stuentEmail}
    </select>
    
    

    测试方法:

    @Test
    
    public void testFindStuent(){
    
    Student student1 = studentDao.findById(1002);
    
    System.out.println("findById:"+student1);
    
    Student student2 = studentDao.findByEmail("zhou@126.net");
    
    System.out.println("findByEmail:"+student2);
    
    }
    
    

    通用方法,使用不同列作为查询条件

    接口方法:

    Student findByDiffField(@Param("col") String colunName,@Param("cval") Object value);
    
    

    mapper 文件:

    <select id="findByDiffField" resultType="com.md.domain.Student">
    select * from student where ${col} = #{cval}
    </select>
    

    测试方法:

    @Test
    
    public void testFindDiffField(){
    
    Student student1 = studentDao.findByDiffField("id",1002);
    
    System.out.println("按 按 id 列查询:"+student1);
    
    Student student2 = studentDao.findByDiffField("email","zhou@126.net");
    
    System.out.println("按 按 email 列查询:"+student2);
    
    }
    
    

    这种方式使用更加灵活

    四、总结

    1. 参数

    从java代码中把实际的值传入到mapper文件中

    1. 一个简单 类型的参数:#{任意字符}
    2. 多个简单类型的参数:使用@Param("自定义名称")
    3. 使用一个java对象,对象的属性作为mapper文件要找的参数,#{java对象的属性名称}
    4. 使用参数的位置,#{arg0}、#{arg1}
    5. 使用Map作为参数,#{map的key}

    2. # 和 $ 的区别

    1. #是占位符,表示列的值,在等号右侧
    2. $是占位符,表示字符串的连接,把sql语句连接成一个字符串
    3. #占位符使用的是jdbc指定的PrepareStatement对象执行的Sql语句,效率高,没有sql注入的风险
    4. $占位符使用的是Statement对象执行的sql,效率低,有sql注入的风险
  • 相关阅读:
    Livepool
    Eclipse最新版注释模板设置详解
    hashcode详解
    开发集成工具MyEclipse中Outline的问题
    第三章 数据链路层(二)
    Java常考面试题(四)
    collections集合的总括。
    第三章 数据链路层(一)
    Java常考面试题(三)
    Java常考面试题(二)
  • 原文地址:https://www.cnblogs.com/mengd/p/13449442.html
Copyright © 2020-2023  润新知