09-MyBatis 占位符#和$

1.#占位符

在这里插入图片描述

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

xml

    <select id="getUserById" resultType="com.limi.entity.User">
        <!--要执行的 sql 语句-->
        select * from t_user where id = #{id}
    </select>

dao

    User getUserById(int id);
    @Test
    public void test1() throws IOException {

        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();

        //使用dao接口操作数据库
        User user = userDao.getUserById(2);
        System.out.println(user);

        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }
//转为 MyBatis 的执行是:
//String sql=” select * from t_user where id = ?”;
//PreparedStatement ps = conn.prepareStatement(sql);
//ps.setInt(1,2);

在这里插入图片描述

2. $占位符

$ 字符串替换,告诉 mybatis 使用 $ 包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的
内容连接起来。主要用在替换表名,列名,不同列排序等操作。

1.属性值参数

作为属性值参数时, 规则为${ 属性变量}, 注意属性变量的`值要加引号, 如name = " ‘cindy’ "

xml

    <select id="getUserByName" resultType="com.limi.entity.User">
        <!--要执行的 sql 语句-->
        select * from t_user where user_name = ${name}
    </select>
//${}表示字符串连接,把sq1语句的其他内容和${}里的内容使用字符串(+)连接的方式连在一起
//select * from t_user where user_name = ${name};
//mybatis创建 statement对象,执行sql语句。
//Statement stmt conn createStatement(sql):Resultset rs = stmt.executeQueryo

dao

List<User> getUserByName(@Param("name") String name);

a. 不加单引号的情况

    @Test
    public void test6() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();
        //使用dao接口操作数据库
        List<User> userList = userDao.getUserByName("cindy");
        userList.forEach(user -> System.out.println(user));
        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }

在这里插入图片描述

b. 所以要注意加上单引号

    @Test
    public void test6() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();
        //使用dao接口操作数据库
        List<User> userList = userDao.getUserByName("'cindy'");
        userList.forEach(user -> System.out.println(user));
        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }

在这里插入图片描述

c. 但是其实我们并不推荐使用这种方式来传递属性值参数, 因为会出现sql注入风险
比如下面的代码, 我把参数写成"‘cindy’ or id > 0"

    @Test
    public void test6() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();
        //使用dao接口操作数据库
        List<User> userList = userDao.getUserByName("'cindy' or id > 0");
        userList.forEach(user -> System.out.println(user));
        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }

就会执行select * from t_user where user_name = ‘cindy’ or id > 0 , 从而暴露了整个数据库表的数据
在这里插入图片描述
虽然不推荐使用${}来传递属性值参数, 但是它也有一些巧妙用法, 比如用来传递列名或者表名

2.列名或表名参数

xml

    <select id="getAllUser" resultType="com.limi.entity.User">
        <!--要执行的 sql 语句-->
        select * from t_user order by ${column} desc
    </select>

dao

    List<User> getAllUser(@Param("column") String column);

a. 输入"user_name"作为排序参数

    @Test
    public void test6() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();
        //使用dao接口操作数据库
        List<User> userList = userDao.getAllUser("user_name");
        userList.forEach(user -> System.out.println(user));
        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }

在这里插入图片描述
b. 输入"id"作为排序参数

    @Test
    public void test6() throws IOException {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //上面这行代码等价于UserDao userDao = new UserDaoImpl();
        //使用dao接口操作数据库
        List<User> userList = userDao.getAllUser("id");
        userList.forEach(user -> System.out.println(user));
        sqlSession.close();  //关闭会话一定要在数据库操作执行之后
    }

在这里插入图片描述

表名参数的传递也是同理, 在此不做重复介绍.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值