MyBatis学习——查询、map、模糊查询
述:上一篇已经进入了MyBatis学习入门阶段(历史+入门demo),这一篇将会继续往下学习mybatis:
0. 简单复习一下流程:
-
配置核心文件
configuration.xml文件(dtd规则,environments,mappers)
-
定义工具类:MyBatisUtils
获取SqlSessionFactoryBuilder,给工人一张图纸,也就是核心文件, 配置一个输入流,inputStream-->读取核心文件 获取SqlSessionFactory对象 builder.build(inputStream) 获取SqlSession对象 factory.openSession(true) //参数true 事务自动提交
-
定义相应接口的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.dao.UserMapper"> <insert id="insert"> INSERT INTO USER VALUES(NULL,'qifeng','111') </insert> </mapper>
-
通过MyBatisUtils获取SqlSession
通过sqlSession对象调用方法执行即可
1. 使用MyBatis进行查询操作
增删改这三者的操作其实都差不多,对返回值的操作也很简单,但是查询操作就需要有返回值了,所以在使用查询的时候,我们要指定返回值的类型等,下面就用一个小demo来试试水:
前期配置上期都已经部署好了,有一个地方需要提一下:
在工具类MyBatisUtils中,读取核心配置文件的方式,官方文档使用的是通过
Resources类中的getResourceAsStream方法(如下):
InputStream re = Resources.getResourceAsStream(resource);
这一种方式,我认为有两个缺点:
- Resources这个类是MyBatis框架提供的,它的依赖度比较高,如果我想换一套框架并且也要读取资源,那么MyBatis框架提供的这个方法重用性就不高了,因为你还要导入MyBatis才能用
- 方法与利用ClassLoader加载的方法名一一致,容易混淆,而且MyBatis提供的方法有异常,必须要处理,我认为不是很方便。
所以我使用的是以下方式:
String resource = "configuration.xml";
InputStream re = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(re);
接下来咱就直接上代码啦:
- 定义一个方法:
/**
* 通过id查询某一个用户
* @param id
* @return
*/
User selectOne(int id);
- 配置好UserMapper.xml
<select id="selectOne" resultType="com.domain.User" parameterType="int">
select * from user where id=${id}
</select>
- 测试执行
public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectOne(1);
System.out.println(user);
}
}
- 运行结果
- 总结
- namespace
namespace中的包名要和mapper接口的包名要一致!
- 一些参数
① id:就是对应的namespace中的方法名
②resultType:Sql语句执行的返回值
③parameterType:参数类型!- 增删改需要提交事务
- 小技巧
因为有时候会报以下错误:
其原因是以下代码参数传入mapper时会乱
我们可以这样解决:在每一个参数前面加一个参数注解就行了
- #{} 与 ${}的区别
#{} -----> 表示类型和值 通常用来做条件 列的值
${} -----> 表示的就是一个普通字串 “asc” 通常是表名 列名 关键字
2. 万能模板之Map
说明: 使用map集合,有好处也有不好的地方,下面我们来仔细推敲:
不好处
- 可读性不如对象好一点
好处:
- 可以不用指定每个参数的名称,自定义进行命名。
- 可以传递任意数量和任意类型的参数,当我们传入的值非常多的话,我们就可以考虑使用map集合,非常的方便
下面我们来一个小小的demo:
- 定义方法
/**
* 定义插入方法
* @param user
* @return
*/
int insert(Map<String,Object> user);
- 编写mapper
此处的“username”和“password”的map集合中的key,可以随意定义,不像domain实体类一样,已经严格规定好,这样的话,我们就可以动态的去改变(其实之前说的使用注解也是一种好的方法)
<insert id="insert" parameterType="map">
insert into user (username,password) VALUES("username","password")
</insert>
- 测试
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> user = new HashMap<String,Object>();
user.put("username","qifeng");
user.put("password",111);
userMapper.insert(user);
sqlSession.commit();
-
实验结果
成功:
-
总结一下:
- 一路下来没有什么毛病,但还是有一些地方需要我们注意
- map里面的键要和mapper里面的参数名字要一致
- 事务事务事务,注意提交
- 使用map可以自定义参数名字,可以传多个值,非常方便
3. 模糊查询
说明: 在写项目时,模糊查询这一项肯定是必不可少的,下面我们就来试试水。
两种方式可以实现:
1. 在传值的时候加上% %
- 即如下:
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectUserByLike("%张%");
for (User user : users) {
System.out.println(user);
}
- 编写方法
/**
* 进行模糊查询
* @param value
* @return
*/
List<User> selectUserByLike(String value);
- 编写mapper
<select id="selectUserByLike" resultType="com.domain.User" parameterType="string">
select * from user where username like #{value}
</select>
- 测试
2. 在sql拼接时使用通配符
- 比之以上过程,即只需改变sql就行
<select id="selectUserByLike" resultType="com.domain.User" parameterType="string">
select * from user where username like "%" #{value} "%"
</select>
- 测试
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectUserByLike("张");
for (User user : users) {
System.out.println(user);
}