上一篇我们介绍了在pom文件中引入mybatis依赖,配置了mybatis配置文件,通过读取配置文件创建了会话工厂,使用会话工厂创建会话获取连接对象读取到了数据库的基本信息。
如果您需要对上面的内容进行了解,可以参考Mybatis引入与使用https://blog.csdn.net/m1729339749/article/details/132457971
本篇我们在上一篇的基础上了解如果使用mybatis查询数据:
一、准备数据
这里我们直接使用脚本初始化数据库中的数据
-- 如果数据库不存在则创建数据库
CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARSET utf8;
-- 切换数据库
USE demo;
-- 创建用户表
CREATE TABLE IF NOT EXISTS T_USER(
ID INT PRIMARY KEY,
USERNAME VARCHAR(32) NOT NULL,
AGE INT NOT NULL
);
-- 插入用户数据
INSERT INTO T_USER(ID, USERNAME, AGE)
VALUES(1, '张三', 20),(2, '李四', 22),(3, '王五', 24);
创建了一个名称为demo的数据库;并在库里创建了名称为T_USER的用户表并向表中插入了数据
二、创建用户实体类
在cn.horse.demo2包下创建UserInfo实体类,为了方便打印用户的信息这里重写了ToString()方法
package cn.horse.demo2;
public class UserInfo {
private int id;
private String username;
private int age;
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append('[');
result.append("id: " + this.id);
result.append(", ");
result.append("username: " + this.username);
result.append(", ");
result.append("age: " + this.age);
result.append(']');
return result.toString();
}
}
三、配置Mapper文件
这里我在resources下创建了一个demo2的目录,并在目录下创建了一个UserInfoMapper.xml的配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="UserInfoMapper">
<select id="findById" resultType="cn.horse.demo2.UserInfo">
SELECT *
FROM T_USER
WHERE ID = #{id}
</select>
<select id="findAll" resultType="cn.horse.demo2.UserInfo">
SELECT *
FROM T_USER
</select>
</mapper>
namespace:代表的是名称空间;如果有多个Mapper配置文件,名称空间不允许重复
select:查询标签;
id代表的是编号,同一个名称空间下编号不允许重复;
resultType代表的是结果类型,指将数据库查询出来的数据转换成结果类型对象,转换的前提是结果类型需要提供无参数的构造方法(用于创建结果类型对象),数据库中的列需要与结果类型中的字段一一对应(使用反射的方式进行对象中字段的赋值),否则无法创建结果类型对象或者无法将数据绑定到结果类型对象的字段上。
标签内容是SQL语句,代表使用ID查询用户信息,其中#{id}是参数;在执行当前查询语句时需要携带此参数。
四、引入Mapper配置
Mapper配置完成后,并没有生效;需要在mybatis-config.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="${driver}"/>
<property name="url" value="jdbc:mysql://${ip}:${port}/${database}?useUnicode=true&useSSL=false&characterEncoding=utf8"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="demo2/UserInfoMapper.xml" />
</mappers>
</configuration>
其中mapper标签是我们引入的配置,resource用于指向Mapper配置文件的位置。
五、查询一条数据
// 读取mybatis配置文件
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 根据配置创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession = null;
try {
// 创建SqlSession
sqlSession = sqlSessionFactory.openSession();
// 根据用户编号查询一条用户信息
UserInfo userInfo = sqlSession.selectOne("UserInfoMapper.findById", 2);
System.out.println(userInfo);
} finally {
// 关闭会话
if(Objects.nonNull(sqlSession)) {
sqlSession.close();
}
}
代码中我们使用selectOne查询一条数据:
第一个参数代表的是语句,其实就是【名称空间.编号】,根据名称空间和编号可以找到我们在Mapper配置文件中配置的SQL语句
第二个参数代表的是参数值,用于解析SQL语句中的参数
测试:
执行上面代码的结果如下:
查询的结果与我们库中的数据一致。
六、查询数据列表
// 读取mybatis配置文件
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 根据配置创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession = null;
try {
// 创建SqlSession
sqlSession = sqlSessionFactory.openSession();
// 查询数据列表
List<UserInfo> userInfoList = sqlSession.selectList("UserInfoMapper.findAll");
for (UserInfo userInfo: userInfoList) {
System.out.println(userInfo);
}
} finally {
// 关闭会话
if(Objects.nonNull(sqlSession)) {
sqlSession.close();
}
}
代码中我们使用selectList查询数据列表,由于没有使用到参数,所以没有传递任何参数
测试:
执行上面代码的结果如下:
查询的结果与我们库中的数据一致。
七、查询数据Map
// 读取mybatis配置文件
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 根据配置创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession = null;
try {
// 创建SqlSession
sqlSession = sqlSessionFactory.openSession();
// 查询数据列表
Map<Integer, UserInfo> userInfoMap = sqlSession.selectMap("UserInfoMapper.findAll", "id");
for (Map.Entry<Integer, UserInfo> entry: userInfoMap.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
} finally {
// 关闭会话
if(Objects.nonNull(sqlSession)) {
sqlSession.close();
}
}
代码中我们使用selectMap查询数据Map,这里需要指定哪个字段作为Map的Key,这里我是用id字段作为Map的Key;这样可以直接得到用户编号到用户对象的Map集合。
需要注意的是Map的Key字段来源于返回类型中的字段而不是数据库中表的列字段
测试:
执行上面代码的结果如下:
查询的结果与我们库中的数据一致。
八、使用结果处理器查询数据
// 读取mybatis配置文件
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 根据配置创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession = null;
try {
// 创建SqlSession
sqlSession = sqlSessionFactory.openSession();
// 查询数据列表
sqlSession.select("UserInfoMapper.findAll", new ResultHandler<UserInfo>() {
@Override
public void handleResult(ResultContext<? extends UserInfo> resultContext) {
System.out.println(resultContext.getResultObject());
}
});
} finally {
// 关闭会话
if(Objects.nonNull(sqlSession)) {
sqlSession.close();
}
}
代码中我们使用select查询数据,此方法没有返回值,而是使用ResultHandler匿名内部类直接对每条数据进行处理
测试:
执行上面代码的结果如下:
查询的结果与我们库中的数据一致。
九、使用游标查询数据
// 读取mybatis配置文件
InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
// 根据配置创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession = null;
Cursor<UserInfo> cursor = null;
try {
// 创建SqlSession
sqlSession = sqlSessionFactory.openSession();
// 查询数据列表
cursor = sqlSession.selectCursor("UserInfoMapper.findAll");
for (Iterator<UserInfo> it = cursor.iterator(); it.hasNext();) {
System.out.println(it.next());
}
} finally {
// 关闭游标
if(Objects.nonNull(cursor)) {
try {
cursor.close();
} catch (IOException e) { }
}
// 关闭会话
if(Objects.nonNull(sqlSession)) {
sqlSession.close();
}
}
代码中我们使用selectCursor查询数据,此方法返回一个游标对象,使用迭代器获取数据列表。
需要注意的是游标对象需要关闭
测试:
执行上面代码的结果如下:
查询的结果与我们库中的数据一致。