文章目录
- 1、前言
- 2、查询一个实体类对象
- 字段名和属性名无法映射处理
- 方式一:起别名
- 方式二:使用全局配置文件配置映射规则
- 方式三:自定义resultmap
- 3、查询一个list集合
- 4、查询单个数据
- 5、查询一条数据为map集合
- 6、 查询多条数据为map集合
- 方式一、直接使用List来接受
- 方式二、使用Map+@MapKey("id")接受
1、前言
在使用MyBatis框架时,不可避免的需要和各种数据来打交道 ,可能的形式有查询出来一个实体对象,一个列表,一个map或者直接是一个基本类型。
为了方便说明,把所有能查的数据类型都用一个接口来进行定义:
public interface SelectMapper {
/**
* 根据id查询用户信息
*/
User getUserById(@Param("id") Integer id);
/**
* 查询所有用户信息
*/
List<User> getAllUser();
/**
* 查询用户信息的总记录数
*/
Integer getCount();
/**
* 根据id查询用户信息为一个map集合
*/
Map<String, Object> getUserByIdToMap(Integer id);
/**
* 查询所有用户信息为map集合
*/
// List<Map<String, Object>> getAllUserToMap();
@MapKey("id")
Map<String, Object> getAllUserToMap();
}
2、查询一个实体类对象
查询一个实体对象的SelectMapper
接口定义
public interface SelectMapper {
/**
* 根据id查询用户信息
*/
User getUserById(@Param("id") Integer id);
}
对应的配置文件内容
<!-- User getUserById(@Param("id") Integer id);-->
<select id="getUserById" resultType="User">
select * from t_user where id = #{id}
</select>
resultType
写的就是返回值的类型
测试类:
/**
* MyBatis的各种查询功能:
* 1。 若查询出的数据只有一条,可以通过实体类对象 / list集合 / map集合 来接收
* 2。 若查询处的数据有多条,一定不能通过实体类对象来接收,此时会抛出TooManyResultsException
*/
@Test
public void testGetUserById(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
User userById = mapper.getUserById(4);
System.out.println(userById);
}
字段名和属性名无法映射处理
由于字段名和属性名不一致,而且没有创建映射关系,java中是驼峰的命名方式,而我们mysql中是下划线的命名方式,所以这时,我们就需要一些操作来将它们进行对应。
比如我们查询到的数据是;
Emp{empId=null,empName='null',age=20,gender='男'}
一般我们有三种手段来保持一致;
- 为查询的字段设置别名,和属性名保持一致
- 当字段符合MySQL的要求使用_,而属性符合java的要求使用驼峰
此时可以在Mybatis的核心配置文件中设置一个全局配置,可以自动将下划线映射为驼峰
emp_id--》empId ,emp_name--》empName
- 使用
resultMap
自定义映射处理
方式一:起别名
select emp_id empId,emp_name empName,age,gender from t_emp where emp_id = #{empId}
方式二:使用全局配置文件配置映射规则
<settings>
<!--将下划线映射为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<select id="getEmpByEmpId" resultType="Emp">
select * from t_emp where emp_id = #{empId}
</select>
方式三:自定义resultmap
resultMap:设置自定义映射
resultMap
所有属性
id | 表示自定义映射的唯一标识 |
type | 查询的数据要映射的实体类的类型 |
子标签:
id | 设置主键的映射关系 |
result | 设置普通字段的映射关系 |
association | 设置多对一的映射关系(处理集合类型的属性) |
collection | 设置一对多的映射关系(处理集合类型的属性) |
属性:
property | 设置映射关系中实体类中的属性名,必须是处理的实体类类型中的属性名 |
column | 设置映射关系中表中的字段名,必须是sql查询出的某个字段 |
代码示例: |
<resultMap id="empResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
</resultMap>
<!-- Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpByEmpId" resultMap="empResultMap">
select * from t_emp where emp_id = #{empId}
</select>
3、查询一个list集合
SelectMapper接口:
public interface SelectMapper {
/**
* 查询所有用户信息
*/
List<User> getAllUser();
}
配置文件
<!-- List<User> getAllUser();-->
<select id="getAllUser" resultType="User">
select * from t_user
</select>
测试类:
/**
* MyBatis的各种查询功能:
* 1。 若查询出的数据只有一条,可以通过实体类对象 / list集合 / map集合 来接收
* 2。 若查询处的数据有多条,一定不能通过实体类对象来接收,此时会抛出TooManyResultsException
*/
@Test
public void testGetUserById(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
List<User> allUser = mapper.getAllUser();
allUser.forEach(user -> System.out.println(user));
}
4、查询单个数据
SelectMapper接口:
public interface SelectMapper {
/**
* 查询用户信息的总记录数
*/
Integer getCount();
}
配置文件:
<!-- Integer getCount();-->
<!-- integer写大小写都可以,写 Integer/integer/_int/_integer 都可以,都是java.lang.Integer的别名-->
<select id="getCount" resultType="java.lang.Integer">
select count(*) from t_user
</select>
测试类:
/**
* 获取记录数
*
* MyBatis中设置了默认的类型别名
* Java.lang.Integer -> int, integer
* int -> _int, _integer
* Map -> map
* List -> list
*/
@Test
public void testGetCount(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getCount());
}
其实对于很多基本类型数据,都有对应的别名,在returnType
中不用写全类名,直接写对应的别名也是一样的。
而对于自己自定义的实体,也可以通过在全局配置文件
中配置。配置形式有一下两种;
- 第一种方法,给单独的某个实体类配置别名,如同下面的形式
<!--为实体类com.demo.dao.User配置一个别名User-->
<typeAliases>
<typeAlias type="com.demo.dao.User" alias="User"/>
</typeAliases>
- 第二种方法,批量为某个包下的所有实体类设置别名,配置形式如下
<!-- 为com.demo.dao包下的所有实体类配置别名,
MyBatis默认的设置别名的方式就是去除类所在的包后的简单的类名,
比如com.demo.dao.User这个实体类的别名就会被设置成User
-->
<typeAliases>
<package name="com.demo.dao"/>
</typeAliases>
5、查询一条数据为map集合
SelectMapper接口:
public interface SelectMapper {
/**
* 根据id查询用户信息为一个map集合
*/
Map<String, Object> getUserByIdToMap(Integer id);
}
配置文件
<!-- Map<String, Object> getUserByIdToMap(Integer id);-->
<select id="getUserByIdToMap" resultType="map">
select * from t_user where id = #{id}
</select>
测试类:
/**
* 如果没有实体类对象,就把它映射成map集合
* 从数据库中查询数据,将其映射为map集合
* 例如把它传到网页端,就映射成json对象,所以转成map很常用
*
* 以字段为键
*/
@Test
public void testgetUserByIdToMap(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getUserByIdToMap(4));
}
6、 查询多条数据为map集合
SelectMapper接口:
public interface SelectMapper {
/**
* 查询所有用户信息为map集合,每一条记录是一个map
*/
Map<String, Object> getAllUserToMap();
}
配置文件:
<!-- Map<String, Object> getAllUserToMap();-->
<select id="getAllUserToMap" resultType="map">
select * from t_user
</select>
现在是查多条数据放在map集合里,我们会发现报错
我们现在查询的结果有4条,但是我们返回值设置的是个Map
集合,我们一条数据转换的就是map
,这时候4条数据转换4
个map
,我们用一个map
集合返回值是获取不到的。我们用的还是selectOne
方法,只能获取一个结果,但是我们查询出来的结果有4条。
方式一、直接使用List来接受
既然我们一条数据转换为一个map
,多条数据则是放到一个可以存储map集合的List集合中,返回值可以这样写
/**
* 查询所有的用户信息为map集合
* @return
*/
List<Map<String,Object>> getAllUserToMap();
@Test
public void testGetAllUserToMap(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
List<Map<String, Object>> list = mapper.getAllUserToMap();
System.out.println(list);
}
方式二、使用Map+@MapKey(“id”)接受
我们在接口中的方法还是可以这么写:Map<String,Object> getAllUserToMap();
因为Map
集合也可以存储多条数据,但是map
和list
不一样,你可以直接把每条数据转换为的map
放在list
中,但是不能把每条数据转换为的map
放在map
集合中,因为map
是键值对,我们查出来的数据作为值,但是谁作为键呢?所以说这时候要用到一个注解@Mapkey()
,这是把我们当前查询的数据所转换的map
集合,放到一个大的map
集合中,通过这个注解,可以设置map
集合的键。这里写的就是我们所查询出来的数据的字段,比如说我们把查询出来的id
作为map
的键,值就是当前的每一条数据所转换为的map
集合。
@MapKey("id")
Map<String,Object> getAllUserToMap();
@Test
public void testGetAllUserToMap(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
Map<String, Object> map = mapper.getAllUserToMap();
System.out.println(map);
}
注:
若查询的数据有多条时,并且要将每条数据转为map集合
此时有2种解决方案:
- 将
mapper
接口的方法返回值设置为泛型是map
的list
集合 - 可以将每条数据转换的map集合放在一个大的
map
中,但是必须要通过@MapKey
注解,将查询的某个字段的值作为大的map的键
@MapKey("id")
Map<String, Object> getAllUserToMap();