1.ResultMap
在谈论ResultMap有何作用之前,我们先来看一下一种常见的问题。一般情况下,我们项目中的实体类的属性名是与数据库中表的属性名对应的,但当两者的属性名不相同时,就会出现SQL语句所查询出来的结果集无法映射到对应的实体类属性,这时候我们查出来的属性值就会为空值。例如:
实体类User的属性如下所示:
package pojo;
//实体类
public class User {
private int id; //id
private String name; //姓名
private String password; //密码
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return password;
}
public void setPwd(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
而数据库表中的属性名则分别为:id、name、pwd。那么,当我们把从数据库中查询出来的结果集赋值给User实体类对象后,我们从User实体类对象中查询password的值就会为空值。
解决方法:
1.在sql语句中起别名
<select id="selectUser" resultType="pojo.User">
select id,name,pwd as password from user
</select>
2.利用ResultMap完成实体类属性与数据库属性的映射
ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
<resultMap id="UserMap" type="pojo.User">
<!-- <result column="id" property="id"/>
<result column="name" property="name"/> -->
<result column="pwd" property="password"/>
</resultMap>
<select id="selectUser" resultMap="UserMap">
select * from user
</select>
其中column代表的是数据库中的属性,而property则是实体类中的属性。
2.日志
对于以往的开发过程,我们会经常使用到debug模式来调节,跟踪我们的代码执行过程。但是现在使用Mybatis是基于接口,配置文件的源代码执行过程。因此,我们必须选择日志工具来作为我们开发,调节程序的工具。
Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。最常使用的为标准日志以及Log4j
2.1 标准日志实现
1.在mybatis核心配置文件:mybatis-config.xml中加上:
<settings>
<!--标准的日志工厂实现-->
<setting name="logImpl" value="STDOUT_LOGGING"/>-->
</settings>
2.随后通过mybatis框架执行数据库相关操作时,便会在控制台上打印出信息
2.2 log4j日志实现
log4j的优点如下:
1.Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…
2.我们也可以控制每一条日志的输出格式;
3.通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
4.通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
在log4j中,日志主要有三个级别,分别为:info,debug以及error。info级别的日志相当于控制台打印信息,debug级别的日志用于输入调试信息,error级别的日志用于输出错误信息。
mybatis采用log4j日志实现步骤:
1.导入log4j的包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.编写配置文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/information.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3、在mybatis核心配置文件:mybatis-config.xml中加上:
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
4.随后通过mybatis框架执行数据库相关操作时,便会在控制台上打印出信息:
3.分页
为什么需要进行分页?
因为我们在对数据库进行操作时,进行得最多的是对数据库进行查询操作。那么当我们查询大量数据的时,通常无法一次性将数据全部取出,那么这时我们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内。
3.1 利用limit实现分页
语法:
#语法,stratIndex代表的是开始的索引下标,pageSize代表的是页面大小
SELECT * FROM table LIMIT stratIndex,pageSize
SELECT * FROM table LIMIT 0,5; // 检索记录行 1-6
#为了检索从某一个偏移量到记录集的最后一行记录,可以指定第二个参数为 -1:
SELECT * FROM table LIMIT 10,-1; // 检索记录行 11-last.
#如果只给定一个参数,它表示返回最大的记录行数目:
SELECT * FROM table LIMIT 5; //检索前 5 个记录行
#换句话说,LIMIT n 等价于 LIMIT 0,n。
实现步骤:
1.Mapper接口添加方法
//利用limit实现分页,注意这里的参数可以通过map来传递
List<User> selectUserByLimit(Map<String,Integer> map);
2.修改mapper.xml文件
<select id="selectUserByLimit" resultType="pojo.User" parameterType="map">
select * from user limit #{startIndex},#{pageSize}
</select>
3.编写测试方法进行测试
@Test
public void selectUserByLimit(){
//通过工具类获得SqlSession对象
SqlSession session = MybatisUtils.getSession();
//获得mapper接口实现类对象,这里的mapper接口实现类对象我们并没有定义,但是mybatis框架根据mapper配置文件自动帮我们创建了
UserMapper mapper = session.getMapper(UserMapper.class);
//当前页数
int currentPage = 0;
//每页大小
int pageSize = 2;
//通过map传递参数,从而通过limit完成分页功能
Map<String,Integer> map = new HashMap<>();
map.put("startIndex",(currentPage-1)*pageSize);
map.put("pageSize",pageSize);
//调用执行对应的SQL查询语句
List<User> users = mapper.selectUserByLimit(map);
//循环输出查询结果
for(User user : users){
System.out.println(user);
}
}
4.测试结果
从图中可以看到,此次查询只查询出了前两行记录
3.2 利用RowBounds实现分页
Limit在SQL层面实现分页,而RowBounds是在Java代码层面实现分页,但其实查看RowBounds源码就不难发现,RowBounds的本质其实也是需要利用Limit实现分页,只是在此基础之上进行了封装。
实现步骤:
1、mapper接口
//RowBounds实现分页
List<User> selectUserByRowBounds();
2.mapper文件
<select id="selectUserByRowBounds" resultType="pojo.User">
select * from user
</select>
3.测试类
@Test
public void selectUserByRowBounds(){
//通过工具类获得SqlSession对象
SqlSession session = MybatisUtils.getSession();
//获得mapper接口实现类对象,这里的mapper接口实现类对象我们并没有定义,但是mybatis框架根据mapper配置文件自动帮我们创建了
UserMapper mapper = session.getMapper(UserMapper.class);
//当前页数
int currentPage = 1;
//每页大小
int pageSize = 2;
//通过RowBounds的有参构造函数创建RowBounds对象,传入的参数分别为:当前页数以及每页大小
RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);
//通过session.selectList()方法进行传递rowBounds,通过此方法完成分页
List<User> users = session.selectList("dao.UserMapper.selectUserByRowBounds", null, rowBounds);
for (User user: users){
System.out.println(user);
}
session.close();
}
4.测试结果
3.3 利用PageHelper实现分页
官方文档:https://pagehelper.github.io/