mybatis映射器之select
select元素是最常用的,也是功能最强大的元素。他的功能就是执行select查询,可以动态设定入参,还可以把resultset的数据转为指定的javabean。
select元素的配置
元素 | 说明 | 备注 |
---|---|---|
id | 他和mapper的命名空间组合起来必须是唯一的,提供给mybatis调用 | 如果命名空间和id组合起来不唯一,mybatis将会抛异常 |
paramterType | 入参类型可以是类的全命名,也可以使类的别名(必须是在mybatis中定义好的) | 可以选择javabean,map等复杂类型传递参数给sql |
parameterMap | 废弃 | 废弃 |
resultType | 返回结果类型,可以是类的全路径,也可以是别名,也可以是八大基础类型 | 不能和resultMap一起使用 |
resultMap | 返回结果的复杂映射,可以定义复杂映射规则 | 需要在配置文件中设置映射规则 |
flushCache | 在调用sql后,是否清空之前查询的本地缓存和二级缓存 | 取值为布尔类型,true/false |
useCache | 启动二级缓存,是否缓存此次结果 | 取值为布尔类型,true/false |
timeout | 设置超时参数,等待超时将抛出异常,单位为秒 | 默认值是jdbc驱动或连接池设置的秒数 |
fetchSize | 获取记录的总条数设置 | 默认是jdbc驱动所设置的条数 |
statementType | 选择一种statement,取值为STATEMENT,PREPARED,CallableStatement | 默认为PREPARED |
resultSetType | 这是对JDBC的resultSet接口而言,他的值包括FORWARD_ONLY(游标允许向前访问),SCROLL_SENSITIVE(双向滚动,但不及时更新),SCROLL_INSENSITIVE(双向滚动,并及时跟踪数据库的更新,以便更改resultSet中的数据) | 默认值是数据库厂商提供的JDBC驱动所设置的 |
databaseId | 标识数据库厂商 | 提供多种数据库支持 |
resultOrdered | 嵌套结果集使用 | 默认值为false |
resultSets | 适合于多个结果集的情况,它将列出执行SQL后每个结果集的名称,每个名称之间用逗号分隔 | 很少使用 |
自动映射
在mybatis的配置文件的settings中有一项配置参数autoMappingBehavior,当它不设置为NONE时,mybatis会提供自动映射的功能,只需要返回的sql列名和javabean的属性一致,mybatis就会帮助我们回填这些字段而无需任何配置。
autoMappingBehavior可以设置三种值。
- NONE,取消自动映射。
- PARTIAL,只会自动映射,阿弥有定义嵌套结果集映射的结果集。
- FULL,会自动映射任意复杂的结果集(无论是否嵌套)。
默认值为PARTIAL。所以在默认情况下,它可以做到当前对象的映射,使用FULL是嵌套映射,在性能上会下降。
如果你的数据库字段是规范命名的,即每个单词都用下划线分隔,POJO采用驼峰命名,那么你也可以设置mapUnderscoreToCamelCase为true,这样就可以实现从数据库到POJO的自动映射了。
入参传递
入参传递的方式有三种,分别是map,注解和javabean。以下分别来演示,数据库配置等见之前的文章。
整个文件结构如下:
src/main/java/
--------------/MybatisSelectMain.java
--------------/com/gavinzh/mybatis/
----------------------------------/modal/MyInfo.java
----------------------------------/MyInfoMapper.java
src/main/resources/
------------------/mybatis_select.xml
------------------/xxx/mybatis_mapper_select.xml
首先先设置一个javabean,作为返回参数也可以作为查询入参MyInfo.java:
package com.gavinzh.mybatis.modal;
/**
* @author gavin
* @version V1.0
*/
public class MyInfo {
private int id;
private String userName;
private String userAge;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAge() {
return userAge;
}
public void setUserAge(String userAge) {
this.userAge = userAge;
}
}
接下来需要有一个mybatis的配置文件mybatis_select.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 对事务的管理和连接池的配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- mapping 文件路径配置 -->
<mappers>
<mapper resource="xxx/mybatis_mapper_select.xml" />
</mappers>
</configuration>
设置了mybatis的配置文件,还需要一个带有sql的mapper配置文件mybatis_mapper_select.xml:
<?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.gavinzh.mybatis.MyInfoMapper">
<select id="selectTestByMap" resultType="com.gavinzh.mybatis.modal.MyInfo">
SELECT id ,user_name as userName,user_age as userAge,column_4 as column4 FROM test.my_info
WHERE id = #{id}
</select>
<select id="selectTestByParam" resultType="com.gavinzh.mybatis.modal.MyInfo" >
SELECT id ,user_name as userName,user_age as userAge,column_4 as column4 FROM test.my_info
WHERE id = #{id} OR user_name = #{userName} OR user_age = #{userAge}
</select>
<select id="selectTestByBean" resultType="com.gavinzh.mybatis.modal.MyInfo" >
SELECT id ,user_name as userName,user_age as userAge,column_4 as column4 FROM test.my_info
WHERE id = #{id}
</select>
</mapper>
有了mapper配置文件,mybatis允许我们写一个mapper文件的接口MyInfoMapper.java,有了这个接口,我们就能通过mapper来访问指定sql,而不是通过命名空间+ID的方式:
package com.gavinzh.mybatis;
import com.gavinzh.mybatis.modal.MyInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author gavin
* @version V1.0
*/
public interface MyInfoMapper {
List<MyInfo> selectTestByMap(Map<String,Object> map);
List<MyInfo> selectTestByParam(@Param("id") int id,@Param("userName") String userName,@Param("userAge") int userAge);
List<MyInfo> selectTestByBean(MyInfo myInfo);
}
有了上边的基础,接下来就可以看看Main方法了,MybatisSelectMain.java:
import com.alibaba.fastjson.JSON;
import com.gavinzh.mybatis.MyInfoMapper;
import com.gavinzh.mybatis.modal.MyInfo;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author gavin
* @version V1.0
*/
public class MybatisSelectMain {
public static void main(String[] args) throws IOException {
//配置
String resource = "mybatis_select.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//入参
MyInfo myInfo = new MyInfo();
myInfo.setId(1);
Map<String, Object> parameter = new HashMap<>();
parameter.put("id", 1);
//ibatis方式调用
// map方式
System.out.println(JSON.toJSONString(sqlSession.selectList("com.gavinzh.mybatis.MyInfoMapper.selectTestByMap", parameter)));
// 在ibatis方式中只能通过map代替注解
System.out.println(JSON.toJSONString(sqlSession.selectList("com.gavinzh.mybatis.MyInfoMapper.selectTestByParam", parameter)));
// javabean方式
System.out.println(JSON.toJSONString(sqlSession.selectList("com.gavinzh.mybatis.MyInfoMapper.selectTestByBean", myInfo)));
System.out.println();
//mybatis方式调用
MyInfoMapper mapper = sqlSession.getMapper(MyInfoMapper.class);
// 入参为map
System.out.println(JSON.toJSONString(mapper.selectTestByMap(parameter)));
// 入参为注解方式接入
System.out.println(JSON.toJSONString(mapper.selectTestByParam(2, "", 22)));
// 入参为javabean
System.out.println(JSON.toJSONString(mapper.selectTestByBean(myInfo)));
}
}
总结
- 使用map传递参数。因为map导致业务可读性丧失,从而导致后续扩展和维护困难,我们应该在实际的应用中放弃这种传递参数的方式。
- 使用注解@Param传递参数。这种方式收到参数个数的影响,当入参大于5个时,调用起来比较困难。
- 当入参大于5个或者以后有可能扩展到5个以上,建议使用javabean方式。
高级结果映射
当我们需要在返回的结果中有嵌套或者返回的结果是组合形式的,那就需要高级结果映射了,具体的映射方法参考官网。