一、快速创建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注入的风险

MyBatis深入理解参数的更多相关文章

  1. MyBatis中传入参数parameterType类型详解

    前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType属性,用于对应的mapper接口方法接受的参数类型.本文主要给大家 ...

  2. 静态代理、动态代理与Mybatis的理解

    静态代理.动态代理与Mybatis的理解 这里的代理与设计模式中的代理模式密切相关,代理模式的主要作用是为其他对象提供一种控制对这个对象的访问方法,即在一个对象不适合或者不能直接引用另一个对象时,代理 ...

  3. MyBatis的返回参数类型和查询结果遍历

    MyBatis的返回参数类型分两种 1. 对应的分类为: 1.1.resultMap: 1.2.resultType: 2 .对应返回值类型: 2.1.resultMap:结果集 2.2.result ...

  4. MyBatis 传List参数 nested exception is org.apache.ibatis.binding.BindingException: Parameter 'idList' not found.

    在MyBatis传入List参数时,MyBatis报错:nested exception is org.apache.ibatis.binding.BindingException: Paramete ...

  5. mybatis中String参数的传递

    mybatis中String参数的传递 Keywords selectKeywords(@Param("key") String key); 可以在mapper方法的参数钱添加 @ ...

  6. MyBatis的传入参数parameterType类型

    1. MyBatis的传入参数parameterType类型分两种 1. 1. 基本数据类型:int,string,long,Date; 1. 2. 复杂数据类型:类和Map 2. 如何获取参数中的值 ...

  7. Mybatis 的输入参数学习

    mybatis 的输入参数: 指得就是parameterType的参数 这个参数就代表的sql语句中的输入参数 sql语句中的参数使用  有两种方式 : 使用#{} 获取:  8个基本数据类型 + S ...

  8. MyBatis的返回参数类型

    MyBatis的返回参数类型分两种 1. 对应的分类为: 1.1.resultMap: 1.2.resultType: 2 .对应返回值类型: 2.1.resultMap:结果集 2.2.result ...

  9. 源码解析之 Mybatis 对 Integer 参数做了什么手脚?

    title: 源码解析之 Mybatis 对 Integer 参数做了什么手脚? date: 2021-03-11 updated: 2021-03-11 categories: Mybatis 源码 ...

随机推荐

  1. 05 drf源码剖析之认证

    05 drf源码剖析之认证 目录 05 drf源码剖析之认证 1. 认证简述 2. 认证的使用 3. 源码剖析 4. 总结 1. 认证简述 当我们通过Web浏览器与API进行交互时,我们可以登录,然后 ...

  2. 01 flask源码剖析之werkzurg 了解wsgi

    01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...

  3. tf.nn.conv2d函数和tf.nn.max_pool函数介绍

    tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None) 介绍参数: input:指卷积需要输入的 ...

  4. 基于.NetCore3.1系列 ——认证授权方案之Swagger加锁

    一.前言 在之前的使用Swagger做Api文档中,我们已经使用Swagger进行开发接口文档,以及更加方便的使用.这一转换,让更多的接口可以以通俗易懂的方式展现给开发人员.而在后续的内容中,为了对a ...

  5. Python Ethical Hacking - BACKDOORS(8)

    Cross-platform hacking All programs we wrote are pure python programs They do not rely on OS-specifi ...

  6. 洛谷 P5350 序列 珂朵莉树

    题目描述 分析 操作一.二.三为珂朵莉树的基本操作,操作四.五.六稍作转化即可 不会珂朵莉树请移步至这里 求和操作 把每一段区间分别取出,暴力相加 ll qh(ll l,ll r){ it2=Spli ...

  7. ​​​​​​​爆力破解Windows操作系统登录密码核心技术

    一.不借助U盘等工具二.已将win7登录账户为test,密码为666666,全套C/C++黑客资料请加:726920220QQ 1.将电脑开机关机几次,进入以下界面

  8. 猴子吃桃问题之《C语言经典案例分析》

    猴子吃桃问题之<C语言经典案例分析>一.[什么是猴子吃桃]       猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个.第二天早上又将第一天剩下的桃子吃掉一半 ...

  9. 题解 洛谷 P4695 【[PA2017]Banany】

    考虑用动态点分治来解决像本题这样带修的树上路径问题. 首先对原树进行点分治,建出点分树,在点分树每个节点上用动态开点线段树来维护以该节点为起点,到其点分树子树中每个节点的利润. 查询时只需在点分树上当 ...

  10. javac不是内部或外部命令,也不是可运行的程序或批处理文件的错误解决方法(Windows10/Windows7)

    前言:在配置JDK环境变量后,java显示正常,javac则显示javac不是内部或外部命令,也不是可运行的程序或批处理文件.造成javac不是内部或外部命令,也不是可运行的程序或批处理文件的问题一般 ...