#{}和${}区别
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 并且会引起sql注入问题。${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
parameterType
sql语句传参数就是通过该属性设置的,该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类。基 本 类 型 和 String 我 们可以直接写类型名称 , 也可以使用包名 . 类名的方式 , 例 如 :java.lang.String。在上一章写的增,删,改,查操作中根据根据id查询用户传入的参数就是Integer,保存用户中传入的参数时实体类User,也可以传入pojo包装类对象,下面演示一下maven工程可以参考上一章:
QueryVo包装类:
/**
* @ClassName QueryVo
* @description: 该类中包含一个对象属性
* @author: zjw
* @Date 2021/2/25 19:04
* @Version 1.0
**/
public class QueryVo implements Serializable {
//该属性是一个对象
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
UserMapper接口中添加方法:
/***
* @Description
* @Param: [vo]
* @return: java.util.List<com.zy.domin.User>
* @Date: 2021/2/26
*/
List<User> findQueryVo(QueryVo vo);
SqlMapConfig.xml核心配置文件跟上一章相同,UserMappe.xml添加sql语句:
<!--传入包装类-->
<select id="findQueryVo" parameterType="com.zy.vo.QueryVo" resultType="com.zy.domin.User">
select * from user where username like #{
user.username}
</select>
测试代码:
@Test
public void testFindQueryVo(){
QueryVo vo = new QueryVo();
User user = new User();
user.setUsername("%小%");
vo.setUser(user);
for (User u:userMapper.findQueryVo(vo)){
System.out.println(u);
}
}
resultType
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型,前面crud有用到。当实体类属性有一个要求是实体类属性名要和数据库字段必须一致,否则无法实现封装。
dao接口:
/***
* @Description 查询所有
* @Param: []
* @return: java.util.List<com.zy.domin.User>
* @Date: 2021/2/22
*/
List<User> findAll();
映射配置:
<!--查询所有-->
<select id="findAll" resultType="com.zy.domin.User">
select * from user
</select>
SqlMapConfig.xml,jdbc.properties,log4j.properties配置文件跟前一章都是一样的。
实体类,属性和数据库字段不一致:
public class User {
private Integer uid;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
//getXXX,setXXX,toString()方法此处省略
}
测试代码:
@Test
public void testFindAll(){
List<User> list = userMapper.findAll();
for (User user : list){
System.out.println(user);
}
}
从测试结果可以看出只有userName有值,这是因为MySQL数据库windos系统下是不区分大小写的。然而其他属性是没有值。那该如何解决,我们可以通过别名查询:
修改映射配置:
<!--查询所有-->
<select id="findAll" resultType="com.zy.domin.User">
select id as uid,
username as userName,
birthday as userBirthday,
sex as userSex,
address as userAddress
from user
</select>
再次执行测试代码看结果:
思考:如果我们查询很多,都使用别名会不会很麻烦,那有没有其他解决办法,那就请看下面。
resultMap
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。
映射配置:
<mapper namespace="com.zy.dao.UserMapper">
<resultMap id="userMap" type="com.zy.domin.User">
<!--
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
-->
<id property="id" column="uid"/>
<result property="userName" column="username"/>
<result property="userBirthday" column="birthday"/>
<result property="userSex" column="sex"/>
<result property="userAddress" column="address"/>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="userMap">
select id,username,birthday,sex,addressfrom user
</select>
</mapper>
再次执行测试代码看结果:
加油吧!!!