不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:php-note.com  发布于:2022-08-13 12:12  分类:Java框架/系统  编辑

1、parameterType

parameterType:接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到mapper 文件的 sql 语句。

  • int 或 java.lang.Integer
  • hashmap 或 java.util.HashMap
  • list 或 java.util.ArrayList
  • student 或 com.bjpowernode.domain.Student

<select>,<insert>,<update>,<delete>都可以使用 parameterType 指定类型。

例如:

<delete id="deleteStudent" parameterType="int">
    delete from student where id=#{studentId}
</delete>

等同于

<delete id="deleteStudent" parameterType="java.lang.Integer">
	delete from student where id=#{studentId}
</delete>

2、MyBatis 传递参数

从 Java 代码中把参数传递到 mapper.xml 文件。

3、一个简单参数

Dao 接口中方法的参数只有一个简单类型(Java基本类型和 String)占位符 #{ 任意字符 }和方法的参数名无关

接口方法:

/**
 * 一个简单类型的参数:
 *      简单类型:mybatis把java的基本数据类型和String都叫简单类型。
 * 在mapper文件获取简单类型的一个参数的值,使用 #{任意字符}
 * @param id
 * @return
 */
public Student selectStudentById(Integer id);

mapper 文件:

<select id="selectStudentById" resultType="com.zep.domain.Student" parameterType="java.lang.Integer">
	select id,name,email,age from student where id=#{studentId}
</select>

注意:

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

测试方法:

@Test
public void testSelectStudentById() {
	/**
	 * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
	 * getMapper能够获取dao接口对应的实现类对象。
	 */
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class); // 这句代码可以自动创建dao接口的实现类对象
	//调用dao的方法,执行数据库的操作
	Student student = dao.selectStudentById(1001);
	System.out.println("学生=" + student);

}

1.4 多个参数 —— 使用@Param

当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入@Param("自定义参数名"),mapper 文件使用#{自定义参数名}。

例如定义:List selectStudent( @Param("personName") String name ) { … }
mapper文件:select * from student where name = #{ personName}

接口方法:

/**
 * 多个参数:命名参数,在形参定义的前面加入@Param("自定义参数名称")
 */
public List<Student> selectMultiParam(@Param("myname") String name, @Param("myage") Integer age);

mapper 文件:

<!--多个参数,使用@Param命名-->
<select id="selectMultiParam" resultType="com.zep.domain.Student">
	select * from student where name=#{myname} or age=#{myage}
</select>

测试方法:

@Test
public void testSelectMultiParam() {
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class);

	List<Student> students = dao.selectMultiParam("李四", 20);
	for (Student student : students) {
		System.out.println("学生=" + student);
	}
	sqlSession.close();
}

5、多个参数 —— 使用对象

使用 Java 对象传递参数, Java 的属性值就是 SQL 需要的参数值。 每一个属性就是一个参数。

语法格式:

#{ property, javaType=java中数据类型名, jdbcType=数据类型名称 }

javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。

常用格式 #{ property }

创建保存参数值的对象 QueryParam:

package com.zep.vo;

public class QueryParam {
    private String paramName;
    private Integer paramAge;

    public String getParamName() {
        return paramName;
    }

    public void setParamName(String paramName) {
        this.paramName = paramName;
    }

    public Integer getParamAge() {
        return paramAge;
    }

    public void setParamAge(int paramAge) {
        this.paramAge = paramAge;
    }
}

接口方法:

/**
 * 多个参数,使用java对象作为接口中方法的参数
 *
 */
List<Student> selectMultiObject(QueryParam param);

mapper 文件:

<!--多个参数。使用java对象的属性值,作为参数的实际值
	适用对象的语法:#{属性名,javaType=类型名称,jdbcType=数据类型} 很少用
	javaType:指java中的属性数据类型
	jdbcType: 在数据库中的数据类型

	例如:#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
	select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
	or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}

  我们使用的简化方式:#{对应接口的参数的类型,即参数对象的属性名},javaType,jdbcType的值mybatis反射能获取。不用提供
-->
<select id="selectMultiObject" resultType="com.zep.domain.Student">
	select * from student where name=#{paramName}
	or age=#{paramAge}
</select>

或者

<select id="selectMultiObject" resultType="com.zep.domain.Student">
	select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
	or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}
</select>

测试方法:

@Test
public void testSelectMultiObject() {
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class);

	QueryParam queryParam = new QueryParam();
	queryParam.setParamName("张三");
	queryParam.setParamAge(28);
	List<Student> students = dao.selectMultiObject(queryParam);
	for (Student student : students) {
		System.out.println("学生=" + student);
	}
	sqlSession.close();
}

6、多个参数 —— 按位置

参数位置从 0 开始, 引用参数语法 #{ arg 位置 }, 第一个参数是#{arg0}, 第二个是#{arg1}

注意:mybatis-3.3 版本和之前的版本使用#{0}, #{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

接口方法:

/**
 * 多个参数,简单类型的,按位置来传值
 * mybatis 3.4之前,使用#{0},#{1}
 * mybatis 3.4之后,使用#{arg0},#{arg1}
 */
List<Student> selectMultiPosition(String name,Integer age);

mapper 文件:

<!--多个参数使用位置-->
<select id="selectMultiPosition" resultType="com.zep.domain.Student">
	select * from student where name=#{arg0}
	or age=#{arg1}
</select>

测试方法:

@Test
public void testSelectMultiPosition() {
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class);

	List<Student> students = dao.selectMultiPosition("李四",20);
	for (Student stu : students) {
		System.out.println("学生=" + stu);
	}
}

7、多个参数 —— 使用 Map

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

例如:Map<String,Object> data = new HashMap<String,Object>();
data.put("myname", "李力");
data.put("myage", 20);

接口方法:

/**
 * 多个参数,使用Map存放多个值
 */
List<Student> selectMultiByMap(Map<String,Object> map);

mapper 文件:

<!--多个参数,使用Map,使用的语法:#{map的key}-->
<select id="selectMultiByMap" resultType="com.zep.domain.Student">
	select * from student where name=#{myname}
	or age=#{myage}
</select>

测试方法:

@Test
public void testSelectMultiByMap() {
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class);

	Map<String,Object> data = new HashMap<>();
	data.put("myname","张三");
	data.put("myage",20);

	List<Student> students = dao.selectMultiByMap(data);
	for (Student stu : students) {
		System.out.println("学生=" + stu);
	}
}

8、#和$

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

mapper 文件

<select id="selectStudentById" resultType="com.zep.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 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。

select id,name, email,age from student where id=#{studentId}

# 的结果: select id,name, email,age from student where id=? 
select id,name, email,age from student where id=${studentId}

$ 的结果:select id,name, email,age from student where id=1001
String sql="select id,name, email,age from student where id=" + "1001";
使用的Statement对象执行sql, 效率比PreparedStatement低。

$:可以替换表名或者列名, 你能确定数据是安全的。可以使用$

接口方法:

List<Student> selectUse$Order(@Param("colName") String colName);

mapper文件:

<!--$替换列名-->
<select id="selectUse$Order" resultType="com.zep.domain.Student">
	select * from student order by ${colName}
</select>

测试文件:

@Test
public void testSelectUse$Order() {
	SqlSession sqlSession = MybatisUtils.getSqlSession();
	StudentDao dao = sqlSession.getMapper(StudentDao.class);

	List<Student> students = dao.selectUse$Order("name");
	for (Student student : students) {
		System.out.println("学生=" + student);
	}
	sqlSession.close();
}

1.8.1 # 和 $区别

  1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
  2. #能够避免sql注入,更安全。
  3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
  4. $有sql注入的风险,缺乏安全性。
  5. $:可以替换表名或者列名

9、完整代码

StudentDao.java:

package com.zep.dao;

import com.zep.domain.Student;
import com.zep.vo.QueryParam;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface StudentDao {

    /**
     * 一个简单类型的参数:
     *      简单类型:mybatis把java的基本数据类型和String都叫简单类型。
     * 在mapper文件获取简单类型的一个参数的值,使用 #{任意字符}
     * @param id
     * @return
     */
    public Student selectStudentById(Integer id);

    /**
     * 多个参数:命名参数,在形参定义的前面加入@Param("自定义参数名称")
     */
    public List<Student> selectMultiParam(@Param("myname") String name, @Param("myage") Integer age);

    /**
     * 多个参数,使用java对象作为接口中方法的参数
     *
     */
    List<Student> selectMultiObject(QueryParam param);

    List<Student> selectMultiStudent(Student student);


    /**
     * 多个参数,简单类型的,按位置来传值
     * mybatis 3.4之前,使用#{0},#{1}
     * mybatis 3.4之后,使用#{arg0},#{arg1}
     */
    List<Student> selectMultiPosition(String name,Integer age);


    /**
     * 多个参数,使用Map存放多个值
     */
    List<Student> selectMultiByMap(Map<String,Object> map);

    /**
     *
     */
    List<Student> selectUse$(@Param("myname") String name);

    List<Student> selectUse$Order(@Param("colName") String colName);

}

mapper文件(StudentDao.xml):

<?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="com.zep.dao.StudentDao">

    <!--
        parameterType:dao接口中方法参数的数据类型。
            parameterType它的值是java的数据类型全限定名称或者是mybatis定义的别名
            例如:parameterType="java.lang.Integer"
                    parameterType="int"
            注意:parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型,所以可以没有。一般我们也不写。

            使用#{}之后,mybatis执行sql使用的是jdbc中的PreparedStatement对象
            由mybatis执行下面的代码:
            1. mybatis创建Connection,PreparedStatement对象
                String = "select id,name,email,age from student where id=?";
                PreparedStatement pst = conn.preparedStatement(sql);
                pst.setInt(1,1001);
            2.执行sql封装为resultType="com.zep.domain.Student"这个对象
                ResultSet rs = pst.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方法调用的返回值

       -->
    <select id="selectStudentById" resultType="com.zep.domain.Student" parameterType="java.lang.Integer">
        select id,name,email,age from student where id=#{studentId}
    </select>


    <!--多个参数,使用@Param命名-->
    <select id="selectMultiParam" resultType="com.zep.domain.Student">
        select * from student where name=#{myname} or age=#{myage}
    </select>

    <!--多个参数。使用java对象的属性值,作为参数的实际值
        适用对象的语法:#{属性名,javaType=类型名称,jdbcType=数据类型} 很少用
        javaType:指java中的属性数据类型
        jdbcType: 在数据库中的数据类型

        例如:#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
        select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
        or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}

      我们使用的简化方式:#{对应接口的参数的类型,即参数对象的属性名},javaType,jdbcType的值mybatis反射能获取。不用提供
    -->
    <select id="selectMultiObject" resultType="com.zep.domain.Student">
        select * from student where name=#{paramName}
        or age=#{paramAge}
    </select>


    <select id="selectMultiStudent" resultType="com.zep.domain.Student">
        select * from student where name=#{name}
        or age=#{age}
    </select>

    <!--多个参数使用位置-->
    <select id="selectMultiPosition" resultType="com.zep.domain.Student">
        select * from student where name=#{arg0}
        or age=#{arg1}
    </select>

    <!--多个参数,使用Map,使用的语法:#{map的key}-->
    <select id="selectMultiByMap" resultType="com.zep.domain.Student">
        select * from student where name=#{myname}
        or age=#{myage}
    </select>

    <!--使用 ${} -->
    <select id="selectUse$" resultType="com.zep.domain.Student">
        select * from student where name=${myname}
    </select>
    <!--$替换列名-->
    <select id="selectUse$Order" resultType="com.zep.domain.Student">
        select * from student order by ${colName}
    </select>
</mapper>

测试代码:

package com.zep;

import com.zep.dao.StudentDao;
import com.zep.domain.Student;
import com.zep.utils.MybatisUtils;
import com.zep.vo.QueryParam;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestMybatis {

    @Test
    public void testSelectStudentById() {
        /**
         * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
         * getMapper能够获取dao接口对应的实现类对象。
         */
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class); // 这句代码可以自动创建dao接口的实现类对象
        //调用dao的方法,执行数据库的操作
        Student student = dao.selectStudentById(1001);
        System.out.println("学生=" + student);

    }

    @Test
    public void testSelectMultiParam() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        List<Student> students = dao.selectMultiParam("李四", 20);
        for (Student student : students) {
            System.out.println("学生=" + student);
        }
        sqlSession.close();
    }


    @Test
    public void testSelectMultiObject() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        QueryParam queryParam = new QueryParam();
        queryParam.setParamName("张三");
        queryParam.setParamAge(28);
        List<Student> students = dao.selectMultiObject(queryParam);
        for (Student student : students) {
            System.out.println("学生=" + student);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectMultiStudent(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        Student student = new Student();
        student.setAge(20);
        student.setName("张三");

        List<Student> students = dao.selectMultiStudent(student);
        for (Student stu : students) {
            System.out.println("学生=" + stu);
        }
    }

    @Test
    public void testSelectMultiPosition() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);


        List<Student> students = dao.selectMultiPosition("李四",20);
        for (Student stu : students) {
            System.out.println("学生=" + stu);
        }
    }



    @Test
    public void testSelectMultiByMap() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        Map<String,Object> data = new HashMap<>();
        data.put("myname","张三");
        data.put("myage",20);

        List<Student> students = dao.selectMultiByMap(data);
        for (Student stu : students) {
            System.out.println("学生=" + stu);
        }
    }


    @Test
    public void testSelectUse$() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        List<Student> students = dao.selectUse$("'李四'");
        for (Student student : students) {
            System.out.println("学生=" + student);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectUse$Order() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        List<Student> students = dao.selectUse$Order("email");
        for (Student student : students) {
            System.out.println("学生=" + student);
        }
        sqlSession.close();
    }

}

10、总结

 

 

摘自:https://blog.csdn.net/weixin_44827418/article/details/111429783