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);
}