SSM-Mybatis-映射器-select
select元素代表select语句,用于查询。元素配置如下:
元素 | 说明 | 备注 |
---|---|---|
id | 它和Mapper的命名空间组合起来是唯一的,供Mybatis调用 | 如果命名空间和id结合起来不唯一,则Mybatis会抛出异常 |
parameter Type | 可以给出类的全命名,也可以给出别名,但是别名必须是Mybatis内部定义或者自定义 | 可选择java Bean,Map等简单的参数类型传递给SQL |
parameterMap | 即将废弃 | — |
resultType | 定义类的全路径,在允许自动匹配的情况下,结果集通过javaBean的规范映射;或定义int double float map等参数;也可以使用别名,但要符合别名规范,且不能和resultMap同时使用 | 常见的参数之一,比如统计总条数时可以把它的值设置为int |
resultMap | 他是映射集的引用,将执行强大的映射功能,不能与resultType同时使用,且resultMap提供自定义规则的机会 | Mybatis最复杂的元素,可以配置映射规则,联机,typeHandler等 |
flushCache | 调用SQL以后,是否要求Mybatis清除之前查询的本地缓存和二级缓存 | 取值为布尔,默认false |
useCache | 启动二级缓存的开关,是否要求Mybatis将此次结果存储 | 取值为布尔,默认true |
timeout | 设置超时参数,超时时将抛出异常,单位为秒 | 默认值是数据库厂商提供的JDBC驱动所设置的秒数 |
fetchSize | 获取记录的总条数设定 | 默认值是数据库厂商提供的JDBC驱动所设置的条数 |
statementType | 告诉Mybatis使用哪个JDBC的Statement工作,可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement | 默认值:PREPARED |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。 | 默认值是数据库厂商提供的JDBC驱动所设置 |
databaseId | 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。 | 提供多种数据库的支持 |
resultOrdered | 这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。 这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false 。 | 取值为布尔,默认false |
resultSets | 置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。 | 很少使用 |
自动映射和驼峰命名
在配置文件中通过元素settting元素可以配置这两种选项,autoMappingBehavior和mapUnderscoreToCamelCase,他们控制自动映射和驼峰命名的开关
这两种方式都建立在SQL列名和POJO属性名的映射关系上。
传递多个参数
-
使用map接口传递参数
Mybatis中允许map接口通过键值对传递多个值,把接口方法定义为:
public List<Role> finRoleByMap(Map<String,Object> parameterMap);
传递给映射器是一个map对象,使用他在SQL中的映射关系
<select id="finRoleByMap" parameterType="map" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
测试:
RoleMapperroleMapper=SqlSession.getMapper(RoleMapper.class); Map<String,Object> parameterMap=new HashMap<String,Object>(); parameterMap.put("roleName","1"); parameterMap.put("note","1"); List<Role> roles=roleMapper.finRoleByMap(parameterMap);
这种方式用的不多,原有有两个:
- map是一个键值对应的集合,使用者需要通过阅读它的键,才能明白其作用
- map不能限定传递的参数类型,业务性质差,可读性差
-
使用注解传递多个参数
@Param:可以通过去定义映射器的参数名称,使用它可以得到更好的可读性,接口定义如下:
public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);
上面代码可读性大大提高,能明确roleName的角色名称,而note是备注,一幕了然,修改如下映射文件代码:
<select id="findRoleByAnnotation" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
这种方式有一个缺点:当SQL很复杂,用于大于10个参数,那么接口方法参数个数多,使用起来不方便
-
使用Java Bean传递多个参数
这种方式需要定义一个参数POJO
package com.ssm; public class RoleParams{ private String roleName; private String note; //getter and setter //...s }
把接口定义为
public List<Role> findRolesByBean(RoleParams roleParams);
Java Bean的roleName属性代表角色名称,note代表备注,映射文件如下:
<select id="findRolesByBean" parameterType="com.ssm.RoleParams" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
测试:
RoleMapper roleMapper=SqlSession.getMapper(RoleMapper.class); RoleParams roleParams=new RoleParams(); roleParams.setRoleName("1"); roleParams.setNote("1"); List<Role> roles= roleMapper.findRolesByBean(roleParams);
-
混合使用
例如查询一个角色,可以通过角色名称和备注进行查询,于此同时还需要支持分页,分页的POJO代码如下:
public class PageParams{ private int start; private int limit; //getter and setter... }
接口设计:
//混合使用了注解和Java Bean方式 public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParam pageParam);
映射文件:
<select id="findByMix" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{params.roleName},'%') and note like concat('%',#{params.note},'%') limti #{page.start},#{page.limit} </select>
总结:
- Map方式不推荐使用,可读性差,扩展维护困难
- 注解方式,参数小于等于5个左右的推荐使用
- Java Bean方式,当参数大于等于5个的时候,推荐使用
- 混合方式,要明确参数的合理性
使用resultMap映射结构集
为了支持复杂的映射,select提供了resultMap属性,定义例子如下:
<mapper namespace="com.ssm.RoleMapper">
<!-- id为resultMap的唯一标识,type标识用哪个类作为其映射的类(可以使用别名和全限定类名) -->
<resultMap id= "roleMap" type="role">
<!--id代表resultMap的主键,result代表属性-->
<!--property代表POJO的属性名称,column代表SQL的列名-->
<id property="id" column="id"/>
<result property="roleName" column="role_name"/>
<result property="note" column="note"/>
</resultMap>
<!--resultMap制定了采用哪个resultMap作为其映射-->
<select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">
select id,role_name,note from t_role where id=#{id}
</select>
</mapper>
分页参数RowBounds
Mybatis内置一个专门处理分页的类:RowBounds
该类属性:
- offset:是偏移量,即从第几行开始读取记录。
- limit:是限制条数
例子:
//给接口添加一个RowBounds参数
public List<Role> findByRowBounds(@Param("roleName") String rolename,
@Param("note") String note,
RowBuounds rowBounds);
映射文件:
<select id="findByRowBounds" resultType="role">
select id ,role_name as roleName from t_role
where role_name like
concat('%',#{roleName},'%')
and note like concat('%',#{note},'%')
</select>
由于RowBounds是Mybatis的一个附加参数,Mybatis会自动识别它,进行分页功能,所以上面代码没有写入任何相关RowBounds的内容
使用:
SqlSession sqlSession=null;
try{
sqlSession=SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper=new RoleMapper();
RowBounds rowBounds=new RowBounds(0,20);
List<Role> roleList=roleMapper.findByRowBounds("role_name","note",rowBounds);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(SqlSession !=null){
sqlSession.close();
}
}
总结:RowBounds分页的运用场景,他只能运用于一些小数据量的查询。对大数据查询,它的性能不佳