003-SSM三大框架(二)—— 深入理解 MyBatis 的参数传递


一、向 SQL 语句传递参数


一、parameterType

  parameterType : 传递给 SQL 语句的数据类型,它的值是 java 的数据类型全限定名称或者是mybatis定义的别名(更多别名的文件请参考 mybatis 的官方文件 mybatis-3.5.1.pdf 的 15 页,文末有获取方式)例如:

<delete id="deleteUser" parameterType="int">
delete from users where id=#{userId}
</delete>

<!--以上代码等同于-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from users where id=#{userId}
</delete>

  要注意的是 parameterType 不是强制的,因为 mybatis 可以通过反射机制能够发现接口文件里面方法参数的数据类型,所以我们可以不写。


二、一个简单参数的传递

   接口中方法的参数只有一个简单类型(java 基本类型和 String)时,在mapper文件中使用 #{任意字符(和方法的参数名无关)}的方式获取数据,例如 :

  1. 接口方法:
package com.dao;
import com.domain.User;

//接口操作User表
public interface UserDao {

	//可以根据你要操作表的方式定义不同的方法,例如
	//根据 id 查询信息
    User getByID(Integer id);

}
  1. mapper 文件:
<select id="getByID" parameterType="java.lang.Integer" resultType="com.domain.User">
        select * from users where userId = #{id}
</select>

三、多个简单参数的传递

   当接口方法多个参数,可以在方法形参前面加入@Param(“自定义参数名”),然后在mapper 文件使用#{自定义参数名}获取数据,例如 :

  1. 接口方法:
package com.mapper;

import org.apache.ibatis.annotations.Param;
import java.util.List;

public interface UserDao {

    List getByID_Name(@Param("id") Integer id ,
                      @Param("name") String name);

}

  1. mapper 文件:
<select id="getByID_Name"  resultType="com.domain.User">
        select * from users where userId = #{id} or userName = #{name}
</select>

四、使用对象进行参数传递

   接口中方法的参数是一个对象时,该对象的属性值就是 sql 需要的参数值,在mapper文件中使用 #{属性名,javaType=类型名称,jdbcType=数据类型}的方式获取数据。

  • javaType:指java中的属性数据类型。
  • jdbcType:在数据库中的数据类型。

   然而,javaType, jdbcType 的值 mybatis 可以通过反射能获取,因此可以省略不写,例如 :

  1. User 文件:
package com.domain;

public class User {

	// 属性名和表的列名一样
    private Integer userId;
    private String  userName;
    private String  password;
    private String  sex;
    private String  email;
    
    //记得补上构造方法和set ,get , toString等方法
}

  1. 接口方法:
package com.mapper;

import com.domain.User;

public interface UserDao {

    int addUser(User user);

}

  1. mapper 文件:
<!--插入操作-->
    <insert id="addUser">
        insert into users(userName,password,sex,email) value (#{userName},#{password},#{sex},#{email})
    </insert>

五、按位置进行参数传递

   接口中方法的参数为多个时,在mapper文件可以根据接口中方法参数的位置来获取参数,参数位置从 0 开始, 引用参数语法 #{ arg 位置 },一个参数是#{arg0}, 第二个是#{arg1}(mybatis-3.3 版本和之前的版本使用#{0},#{1}方式),例如 :

  1. 接口方法:
package com.mapper;

import org.apache.ibatis.annotations.Param;
import java.util.List;

public interface UserDao {

    List getByID_Name(Integer id , String name);

}

  1. mapper 文件:
<select id="getByID_Name"  resultType="com.domain.User">
        select * from users where userId = #{arg0} or userName = #{arg1}
</select>

六、使用 Map进行参数传递

   接口中方法的参数是一个 Map 集合,Map 集合可以存储多个值,使用 Map 向 mapper 文件一次传入多个参数。Map 集合使用 String 的 key,Object 类型的值存储参数,在mapper 文件使用 # { key } 引用参数值,例如 :

  1. 接口方法:
package com.mapper;


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

public interface UserDao {

    List getByID_Name(Map<String,Object> map);

}

  1. mapper 文件:
<select id="getByID_Name"  resultType="com.domain.User">
        select * from users where userId = #{id} or userName = #{name}
</select>
  1. 测试文件 :
 @Test
    public void testSGetByID_Name(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao dao  =  sqlSession.getMapper(UserDao.class);
        Map<String,Object> data = new HashMap<String,Object>();
        data.put("name","张三");
        data.put("id","5");
        List<User> uses = dao.getByID_Name(data);

        System.out.println("uses ="+uses);
    }

七、# 和 $ 的区别

  1. 占位符 # :告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}去代替sql 语句的“?”,这样做更安全,更迅速,通常也是首选做法,例如:
<select id="getByID"  resultType="com.domain.User">
        select * from users where userId = #{id} 
</select>

转为 MyBatis 的执行是:
String sql=” select * from users where userId=?;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(5);
  1. 字符串替换 $ ,告诉 mybatis 使用 $ 包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。例如:
<select id="getByID"  resultType="com.domain.User">
        select * from users where userId = ${id} 
</select>

转为 MyBatis 的执行是:
String sql=” select * from users where userId=+5;
Statement ps = conn.Statement(sql);

例如:

  1. 接口方法:
package com.mapper;


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

public interface UserDao {

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

}

  1. mapper 文件:
 <select id="findByDiffField" resultType="com.domain.User">
        select * from users where ${col} = #{cval}
 </select>
  1. 测试文件 :
 @Test
    public void testSGetByID_Name(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao dao  =  sqlSession.getMapper(UserDao.class);
        User user = dao.findByDiffField("userId",5);
        System.out.println("按 按 id  列查询:"+user);
        User student2 = dao.findByDiffField("email","123@qq.com");
        System.out.println("按 按 email  列查询:"+student2);
    }
  • $ 和 # 的区别
    • #是使用 ?在sql语句中做占位的,使用PreparedStatement执行sql,效率高;
    • #能够避免sql注入问题,更安全;$有sql注入的风险,缺乏安全性。
    • $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低;
    • $:可以替换表名或者列名



二、封装 SQL 语句的输出结果


一、resultType

  指sql语句执行完毕后, 数据转为的java对象的类型,使用类型的完全限定名或别名(更多别名的文件请参考 mybatis 的官方文件 mybatis-3.5.1.pdf 的 15 页,文末有获取方式),如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。例如:

  1. 接口方法:
package com.dao;
import com.domain.User;

//接口操作User表
public interface UserDao {

	//根据 id 查询信息,返回java对象类型
    User getByID(Integer id);

	//计算个数,返回简单类型
	int countUser();

}
  1. mapper 文件:
<select id="getByID" parameterType="java.lang.Integer" resultType="com.domain.User">
        select * from users where userId = #{id}
</select>

<select id="countUser" resultType="int">
	select count(*) from users
</select>

  处理方式:mybatis 执行 sql 语句, 通过调用该类的无参数构造方法,创建对象在指定列值付给同名的属性,因此需要实体类中有无参构造方法和属性值与数据库表中列名一致。


二、resultMap

   resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性,常用在列名和 java 对象属性名不一样的情况。用法如下 :

   1.先定义 resultMap ,指定列名和属性的对应关系。
   2.在中把 resultType 替换为 resultMap。

  1. mapper 文件:

<!--  创建 resultMap
id: 自定义的唯一名称,在 <select> 使用
type: 期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="userMap" type="com.domain.User">
<!--  主键字段使用 id -->
<id column="userId" property="userId" />
<!-- 非主键字段使用 result-->
<result column="userName" property="userName"/>
<result column="email" property="email" />
<result column="sex" property="sex" />
</resultMap>
<!--resultMap: resultMap 标签中的 id 属性值 -->
<select id="selectUseResultMap" resultMap="userMap">
	select userId,userName,email,sex from users
</select>



三、模糊查询:like

  1. java 代码中给查询数据加上“%” ;

  接口方法:

package com.mapper;


import java.util.List;

public interface UserDao {

    List<User> getByName(String name);

}

  mapper 文件:

<select id="getByName"  resultType="com.domain.User">
        select * from users where userName  like  #{name} 
</select>

  测试文件 :

 @Test
    public void testSGetByID_Name(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao dao  =  sqlSession.getMapper(UserDao.class);
        String name="% 李%";
        List<User> uses = dao.getByName(name);

        System.out.println("uses ="+uses);
    }
  1. mapper 文件中使用 like name “%” #{xxx} “%”

  接口方法:

package com.mapper;


import java.util.List;

public interface UserDao {

    List<User> getByName(String name);

}

  mapper 文件:

<select id="getByName"  resultType="com.domain.User">
        select * from users where userName like "%" #{name}  "%" 
</select>

  测试文件 :

 @Test
    public void testSGetByID_Name(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao dao  =  sqlSession.getMapper(UserDao.class);
        String name="李";
        List<User> uses = dao.getByName(name);

        System.out.println("uses ="+uses);
    }



写在最后

以上 MyBatis 中关于 SQL 语句中的参数的接收与封装返回的具体内容,后续如果有时间的话我也将持续更新,如果有错误或者是哪里不足的地方,欢迎各位大大提出宝贵的意见呀~

此外,为了让大家更方便地使用,如果需要 mybatis 的官方文件 mybatis-3.5.1.pdf 可以关注下方公众号,后台回复 “mybatis ”即可获取,期待着您的光临~

在这里插入图片描述




相关链接:

链接: 002-SSM三大框架(二)—— 基于Maven工程搭建 MyBatis 开发环境.
链接: 001-SSM三大框架(一)—— 三层架构.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值