Java -- MyBatis学习笔记7、# 和 $的区别

1、# 占位符

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

  • 在Dao层接口中添加如下方法:
public int insert(UserInfo userInfo);
  • 在mapper映射文件中添加对应的标签和SQL语句:
<insert id="insert" parameterType="com.rg.entity.UserInfo">
    insert into UserInfo(Name,Age) values(#{Name},#{Age})
</insert>
  • 在测试类中测试、如下:
@Test
public void insert()
    {
        UserInfo userInfo = new UserInfo();
        userInfo.setName("王昭君");
        userInfo.setAge(16);
        int result = this.userInfoDao.insert(userInfo);
        sqlSession.commit();
        System.out.println(result);
    }
  • 观察日志记录、如下:
==> Preparing: insert into UserInfo(Name,Age) values(?,?) 
==> Parameters: 王昭君(String), 16(Integer)
==> //........

可以看到、values()里边是 ? 、也就是说:转为JDBC代码使用的就是PreparedStatement、如下:

String sql = "insert into UserInfo(Name,Age) values(?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"张三");
ps.setInt(2,30);

values(?,?)就是values(#{Name},#{Age})。
ps.setString(1,"张三")中的"张三"会替换掉#{Name}。
使用PreparedStatement更安全、高效、可以防止SQL注入。

2、$ 字符串替换

$和#差不多、#能使用的地方$都可以使用。但是不使用占位符的方式给参数赋值、而是使用直接拼接的方式,主要用在替换表名,列名,不同列排序等操作。在Java里就是字符串的拼接。比如:

String name = "张三";
System.out.println("你好、我是" + name);
//结果就是:你好、我是张三
  • 在Dao层接口中添加如下方法:
public List<UserInfo> selectAll(@Param("age") String age);
  • 在mapper映射文件中添加对应的标签和SQL语句:
<select id="selectAll" resultType="com.rg.entity.UserInfo">
     select * from UserInfo order by ${age}
</select>
  • 在测试类中测试、如下:
@Test
    public void selectAll()
    {
        List<UserInfo> userList = userInfoDao.selectAll("age");
        //循环输出集合中的结果
        userList.forEach(x -> System.out.println(x));
    }
  • 观察日志记录、如下:
==> Preparing: select * from UserInfo order by age 
==> Parameters: 

可以看到、传入的字符串类型的参数age、直接将${age}替换掉了、但是并没有双引号、如果要传入的类型在数据库里是字符串类型的、那么就需要这样写:selectAll("'age'")。这样、SQL语句就变成了:

select * from UserInfo order by 'age'

使用$替换、在接口中的方法参数要使用@Param给参数定义别名、在mapper映射文件对应的SQl语句中就使用别名 $(别名)。最后、$使用的是Statement对象执行SQL、效率比较低、不安全。需合理使用。

3、查询通用方法

还可以使用$编写通用方法,使用不同列作为查询条件:

  • 接口方法:
UserInfo findByDiffField(@Param("col") String colunName,@Param("cval") Object
value);
  • mapper文件
<select id="findByDiffField" resultType="com.rg.entity.UserInfo">
select * from UserInfo where ${col} = #{cval}
</select>
  • 测试方法:
@Test
public void testFindDiffField()
{
    UserInfo userInfo1 = this.userInfoDao.findByDiffField("id",3);
    System.out.println("按按id 列查询:"+userInfo1);
    Student userInfo2 = this.userInfoDao.findByDiffField("Name","王五");
    System.out.println("按按Name列查询:"+userInfo2);
}
posted @ 2021-05-09 11:53  初晨~  阅读(722)  评论(0编辑  收藏  举报