2

MyBatis的使用三(在sql语句中传值) - zwGitOne

 1 year ago
source link: https://www.cnblogs.com/zwgitOne123/p/17087704.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文主要介绍在mybatis中如何在sql语句中传递参数

一. #{ } 和 ${ }

  1. #{ } 和 ${ }的区别

  #{ }是预编译处理 ==> PreparedStatement

  ${ }是字符串替换 ==> Statement

  mybatis在处理 #{ } 时,会将sql中的 # { } 替换为?号,调用PreparedStatement的set()方法来赋值;

  mybatis在处理 ${ } 时,会将 ${ } 替换成变量的值。

  因此 #{ }可以防止sql注入,而 ${ }不可以防止sql注入。

  注意:在使用 ${ }时,需要在 ${ } 打上 '   ',即 ' ${ } '。

  2. #{ } 和 ${ } 的使用

  2.1 当查询条件只有一个时

  首先看看UserMapper接口的定义:

public interface UserMapper {
    // 按照姓名查询数据
    User getUserByName(String username);
}

  1)在UserMapper.xml文件中,使用 #{ } 传递参数

<mapper namespace="com.hspedu.mapper.UserMapper">
    <!--User getUserByName()-->
    <select id="getUserByName" resultType="User">
        <!--select * from t_user where username = #{username}-->
        select * from t_user where username = #{param2}
    </select>
</mapper>

  测试test

    // 按姓名查询数据
    @Test
    public void selectUserByName(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User jack = mapper.getUserByName("jack");
        System.out.println(jack);
        SqlSessionUtils.closeSqlSession();

    }
vip

   xml文件中的sql语句

select * from t_user where username = #{param2}

  上述的sql语句解析为:

select * from t_user where username = 'jack'

  注意:当mapper接口的查询方法的形参列表只有一个的情况下, #{ }中的参数可以随便书写

  2)在在UserMapper.xml文件中,使用 ${ } 传递参数

<mapper namespace="com.hspedu.mapper.UserMapper">
    <!--User getUserByName()-->
    <select id="getUserByName" resultType="User">
        select * from t_user where username = '${param2}'
    </select>
</mapper>

  注意:在使用 ${ }时,需要在 ${ } 打上 '   ',即 ' ${ } '。

  测试test

    // 按姓名查询数据
    @Test
    public void selectUserByName(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User jack = mapper.getUserByName("jack");
        System.out.println(jack);
        SqlSessionUtils.closeSqlSession();

    }
vip

   xml文件中的sql语句

select * from t_user where username = '${param2}'

  上述的sql语句解析为

select * from t_user where username = 'jack' 

  由此可见,${ } 并没有预编译处理,但是 #{ } 有预编译处理,显示出 #{ } 的安全性 【防止sql注入】

  注意:当mapper接口查询方法的形参列表只有一个的时候,${ }中的参数可以随便书写

  2.2 当查询条件不只有一个时

  以使用 #{ } 传递参数 举例

  情况1:若UserMapper接口声明如下

public interface UserMapper {
    // 按照姓名和密码查询
    User checkLogin(String username,String password);
}

  则 在xml文件中使用args0,args1,param1,param2...作为 #{ }的参数

<mapper namespace="com.hspedu.mapper.UserMapper"> 
    <!--User checkLogin(String username,String password)-->
    <select id="checkLogin" resultType="User" >
        <!--Available parameters are [arg1, arg0, param1, param2]-->
        select * from t_user where username = #{param1} and password = #{param2}
    </select>
</mapper>

  如果不用args0,args1,param1,param2...,则会报如下异常

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'param' not found. Available parameters are [arg1, arg0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'param' not found. Available parameters are [arg1, arg0, param1, param2]

  情况2:若UserMapper接口声明如下

public interface UserMapper {
    // 参数map查询数据
    User checkLoginByMap(Map<String,Object> map);
}
    

  则 在UserMapper接口的checkLogin()中传入Map类型,达到自定义 #{ } 中参数的名称

  xml文件声明如下,#{ } 传入的参数即Map中K键

<mapper namespace="com.hspedu.mapper.UserMapper">
    <!--User checkLoginByMap(Map<String,Object> map)-->
    <select id="checkLoginByMap" resultType="User" >
        select * from t_user where username = #{username} and password = #{password}
    </select>
</mapper>

  测试test

    @Test
    public void selectByMap(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("username","jack");
        map.put("password","tom12345");
        User user = mapper.checkLoginByMap(map);
        System.out.println(user);
        SqlSessionUtils.closeSqlSession();
        System.out.println(sqlSession);
    }

  注意:在这种情况下,#{ } 的参数必须是形参Map的 key 键。

  情况3:UserMapper接口声明如下

public interface UserMapper {
    // 参数为User添加数据
    int insertByUser(User user);
}

  则 在xml文件声明如下,#{ } 的参数即为User类的属性

<mapper namespace="com.hspedu.mapper.UserMapper"> 
    <!--int insertUser(User user)-->
    <insert id="insertByUser" >
        insert into t_user values(null,#{username},#{password},#{age},#{gender},#{email})
    </insert>
</mapper>

  测试test

     // 测试使用对象作为参数,添加用户
    @Test
    public void testInsertByUser(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(null, "hsp", "hsp12345", 25, "男", "[email protected]");
        int i = mapper.insertByUser(user);
        System.out.println(i);
        sqlSession.close();
    }

  情况4:UserMapper接口声明如下

public interface UserMapper {
    // @Param作为参数
    User checkLoginByParam(@Param("user") String username,@Param("pwd") String password);
}

  xml文件声明如下,使用@Param注解,指明在 #{ } 中传入的参数,更加方便

<mapper namespace="com.hspedu.mapper.UserMapper">
    <!--User checkLoginByParam(@Param("user") String username,@Param("pwd") String password)-->
    <select id="checkLoginByParam" resultType="User" >
        select * from t_user where username = #{user} and password = #{pwd}
    </select>
</mapper>

  测试test

    @Test
    // 通过注解@Param传递参数
    public void testByParam(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.checkLoginByParam("jack", "tom12345");
        System.out.println(user);
        sqlSession.close();
    }

  在 #{ } 中:增加,修改使用情况3的处理方式,传入User实体类对象

        查询,使用情况4的处理方式,在mapper接口定义的方法的形参列表中 添加 @Param注解。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK