#{}和${}区别
- #{}:表示一个占位符号,通过#{}可以实现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包装类:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class QueryVo {
private UserInfo userInfo;
}
UserInfoMapper接口中添加方法:
/**
* 包装类作为参数
* @date 2021/10/31 9:12
* @param queryVo
* @return java.util.List<com.crud.entity.UserInfo>
*/
List<UserInfo> findQueryVo(QueryVo queryVo);
UserInfoMapper.xml添加sql语句:
<select id="findQueryVo" resultType="com.crud.entity.QueryVo" resultMap="base">
select * from USER_INFO where ID = #{userInfo.id}
</select>
测试代码:
@Test
public void testFindQueryVo(){
UserInfo userInfo = new UserInfo();
userInfo.setId(2);
QueryVo queryVo = new QueryVo();
queryVo.setUserInfo(userInfo);
List<UserInfo> userInfoList = userInfoMapper.findQueryVo(queryVo);
for (UserInfo userInfo2 : userInfoList){
System.out.println(userInfo2);
}
}
resultType属性
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型,当该属性返回的是实体类属性时,要求:实体类属性名要和数据库字段必须一致,否则无法实现封装。
- UserInfoMapper接口:
/**
* 查询全部
* @date 2021/10/30 9:27
* @return java.util.List<com.crud.entity.UserInfo>
*/
List<UserInfo> findAll();
- UserInfoMapper.xml
<!--查询全部-->
<select id="findAll" resultType="com.crud.entity.UserInfo">
SELECT *
FROM USER_INFO
</select>
将UserInfo实体中的属性值修改跟数据库字段不一致,看是否能封装数据
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {
private Integer id;
//该属性值和数据字段不一致
private String uName;
private Integer age;
private String gender;
private Date birthday;
private String address;
private Date createTime;
private Date updateTime;
}
测试代码:
@Test
public void testFindAll(){
List<UserInfo> userInfoList = userInfoMapper.findAll();
for (UserInfo userInfo:userInfoList){
System.out.println(userInfo);
}
}
通过输出结果可以看出来uName没有封装上值,有两种写法可以解决这种情况发生,实际工作中都写第二种
- 通过sql语句别名解决
<!--查询全部-->
<select id="findAll" resultType="com.crud.entity.UserInfo">
SELECT ID,
NAME as uName,
AGE,
GENDER,
BIRTHDAY,
ADDRESS,
CREATETIME,
UPDATETIME
FROM USER_INFO
</select>
再次执行测试代码看结果:
- 第二种就是通过 resultMap属性解决,这也是最常用的
resultMap属性
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实数据现封装。在select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。
映射配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.crud.mapper.UserInfoMapper">
<!--
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
-->
<resultMap id="base" type="com.crud.entity.UserInfo">
<id column="ID" property="id"></id>
<result column="NAME" property="uName"></result>
<result column="AGE" property="age"></result>
<result column="GENDER" property="gender"></result>
<result column="BIRTHDAY" property="birthday"></result>
<result column="ADDRESS" property="address"></result>
<result column="CREATETIME" property="createTime"></result>
<result column="UPDATETIME" property="updateTime"></result>
</resultMap>
<!--查询全部-->
<select id="findAll" resultMap="base">
SELECT *
FROM USER_INFO
</select>
</mapper>
再次执行测试代码看结果:
加油吧!!!