1. ResultMap
- 结果集映射
- resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来。
- ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
1. 自动映射
-
之前写的就是简单映射语句的示例,但并没有显式指定 resultMap
<select id="getAllUser" resultType="User" > select * from user </select>
-
上述语句只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定。虽然在大部分情况下都够用,但是 HashMap 不是一个很好的模型
2. 手动映射
-
修改返回值类型为 resultMap
<select id="selectUserById" resultMap="UserMap"> select id , name , pwd from user where id = #{id} </select>
-
编写resultMap,实现手动映射
<resultMap id="UserMap" type="User"> <!-- id 是一个标识方便后面的引用 ; type 就是需要把结果集映射为一个什么类型--> <id column="id" property="id"/> <!-- column是查询语句中的列名 , property是对应实体类的属性名 --> <result column="name" property="name"/> <result column="pwd" property="password"/> </resultMap>
- 手动声明,实体类中的属性 和 数据库中的字段的 对应关系
- 数据库中,存在一对多,多对一的情况,之后会使用到一些高级的结果集映射,association,collection这些
2. 属性名和字段名不一致问题
1. 问题演示
- 查看之前的数据库的字段名
- Java中的实体类设计
public class User {
private int id; //id
private String name; //姓名
private String password; //密码和数据库不一
}
- 密码和数据库不一
- 结果
User{id=1, name=‘hehe’, password=‘null’}
- 查询出来发现 password 为空 . 说明出现了问题!
2. 解决办法
-
方案一:为列名指定别名 , 别名和java实体类的属性名一致 .
<select id="selectUserById" resultType="User"> select id , name , pwd as password from user where id = #{id} </select>
-
方案二:使用结果集映射->ResultMap 【推荐】
<resultMap id="UserMap" type="User"> <id column="id" property="id"/> <!-- column是数据库表的列名 , property是对应实体类的属性名 --> <result column="name" property="name"/> <result column="pwd" property="password"/> </resultMap> <select id="selectUserById" resultMap="UserMap"> select id , name , pwd from user where id = #{id} </select>
3. 分页
- 为什么需要分页?
使用分页进行查询,每次处理小部分数据,这样对数据库压力就在可控范围内。
1. limit实现分页
-
语法
SELECT * FROM table LIMIT stratIndex,pageSize
-
示例
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 #如果只给定一个参数,它表示返回最大的记录行数目: SELECT * FROM table LIMIT 5; //检索前 5 个记录行 #换句话说,LIMIT n 等价于 LIMIT 0,n。
-
具体使用
-
接口
//分页查询 List<User> getUserByLimit(Map<String,Integer> map);
-
Mapper.xml
<select id="getUserByLimit" resultType="user" parameterType="map"> select * from user limit #{startIndex},#{pageSize} </select>
-
测试
@Test public void getUserByLimit(){ SqlSession session = MyBatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); Map<String,Integer> map = new HashMap<>(); map.put("startIndex", 0); map.put("pageSize", 2); List<User> userByLimit = mapper.getUserByLimit(map); System.out.println(userByLimit); session.close(); }
2. RowBounds分页
- 我们除了使用Limit在SQL层面实现分页,也可以使用RowBounds在Java代码层面实现分页,当然此种方式作为了解即可
- mapper接口
//选择全部用户RowBounds实现分页
List<User> getUserByRowBounds();
- mapper文件
<select id="getUserByRowBounds" resultType="user">
select * from user
</select>
- 测试类
在这里,我们需要使用RowBounds类
@Test
public void testUserByRowBounds() {
SqlSession session = MybatisUtils.getSession();
int currentPage = 2; //第几页
int pageSize = 2; //每页显示几个
RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);
//通过session.**方法进行传递rowBounds,[此种方式现在已经不推荐使用了]
List<User> users = session.selectList("com.mapper.UserMapper.getUserByRowBounds", null, rowBounds);
for (User user: users){
System.out.println(user);
}
session.close();
}