select元素是用来定义查询操作的。
id:唯一标识符;用来引用这条语句,需要和接口的方法名一致
parameterType:参数类型;可以不传值,MyBatis会根据TypeHandler自动推断
resultType:返回值类型;别名或者全类名,如果返回的是集合,则定义集合中元素的类型。不能和resultMap同时使用
resultType
案例一:返回list
接口
public interface EmployeeMapper{
public List<Employee> getEmpsByLastNameLike(String lastName);
}
映射文件
resultType:如果返回的是一个集合,要写集合中元素的类型,而不是resultType="list"。
<select id="getEmpsByLastNameLike" resultType="com.mybatis.bean.Employee">
select * from tbl_employee where last_name like #{lastName}
</select>
测试
List<Employee> like = mapper.getEmpsByLastNameLike(%e%);
for(Employee employee : like){
System.out.println(employee);
}
结果
案例二:返回一条记录的map;key就是列名,value就是对应的值。
接口
public interface EmployeeMapper{
public Map<String Object> getEmpByIdReturnMap(Integer id);
}
映射文件
<select id="getEmpByIdReturnMap" resultType="map">
select * from tbl_employee where id=#{id}
</select>
测试
Map<String,Object> map = mapper.getEmpByIdReturnMap(1);
System.out.println(map);
结果
案例三:多条记录封装一个map:Map<Integer,Employee>:键是这条记录的主键,值是记录封装后的javabean。
接口
public interface EmployeeMapper{
public Map<Integer,Employee> getEmpByLastNameLikeReturnMap(String lastName)
}
映射文件
resultType始终写的是你想让MyBatis把这一条记录封装成什么类型
想要把查出的记录,每一条封装成Employee,所以resultType写的还是集合里面元素的类型
<select id="getEmpByLastNameLikeReturnMap" resultType="com.mybatis.bean.Employee">
select * from tbl_employee where last_name like #{lastName}
</select>
那么,mybatis怎么知道key要用主键来做呢?或者用lastName呢?
所以要在接口方法上添加一个注解@MapKey("id"),用来告诉mybatis封装这个map的时候key用哪个属性
测试
Map<Integer,Employee> map = mapper.getEmpByLastNameLikeReturnMap(%r%);
System.out.println(map);
结果
id作为封装的对象
或者改造一下接口
使用lastName作为Key
public interface EmployeeMapper{
@MapKey("lastName")
public Map<String,Employee> getEmpByLastNameLikeReturnMap(String lastName)
}
测试
Map<String,Employee> map = mapper.getEmpByLastNameLikeReturnMap(%r%);
System.out.println(map);
结果
名字作为封装的对象
resultMap
resultType:从sql语句中返回的期望类型的类的完全限定名或别名。注意,如果是集合,那应该是集合可以包含的类型,而不能是集合本身。该属性和resultMap不能同时使用。(跟自动封装有关)
resultMap:外部resultMap的命名引用。和resultType属性不能同时使用。
如果查询出的列名和javabean的属性名不一样,会封装不成功
解决办法可以是:
1、写别名;
2、如果列名和javabean的属性名符合驼峰命名法的规定,就可以开启驼峰命名法;
3、使用resultMap,自定义结果集,自定义javabean中的属性对应哪个列名。
自动映射
1、全局setting设置
autoMappingBehavior默认是PARTIAL,开启自动映射的功能。唯一的要求是列名和javaBean属性名一致
如果autoMappingBehavior设置为null则会取消自动映射
数据库字段命名规范,POJO属性符合驼峰命名法,如A_COUNT——>aColumn,我们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true。
2、自定义resultMap,实现高级结果集映射。
映射文件
namespace绑定的一定是接口的全类名
resultMap:自定义某个javabean的封装规则;type:自定义规则的java类型;id:唯一id方便引用。
(1)在resultMap标签内部指定主键列的封装规则;
id标签:定义主键,mybatis会在内部底层有优化;column:指定数据库中哪一列;property:指定对应的javabean属性。
(2)在resultMap标签内部定义普通列的封装规则;
result标签;column:指定数据库中哪一列;property:指定对应的javabean属性。
(3)在resultMap标签内部其他不指定的列会自动封装;
但是推荐只要写了resultMap就要把全部的映射规则都写上,方便检查。
<resultMap type="emp" id="MyEmp">
<id column="id" property="id" />
<result column="Last_name" property="LastName" />
<result column="email" property="email" />
<result column="gender" property="gender" />
</resultMap>
<mapper namespace="com.mybatis.dao.EmployeeMapperPlus">
<select id="getEmpById" resultMap="MyEmp">
select * from tbl_employee where id=#{id}
</select>
</mapper>
type="emp",使用“emp”是因为之前全局配置中使用了别名(但一般还是建议写类全名,避免混淆)
@Alias("emp")
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
//省略setter和getter方法
}
测试
@Test
public void test () throws IOException{
sqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
sqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
Employee empById = mapper.getEmpById(1);
System.out.println(empById);
}finally{
openSession.close();
}
}
结果