5. Mybatis 单表查询 - resultMap标签 - 多条件查询 - 模糊查询

网友投稿 782 2022-11-21

5. Mybatis 单表查询 - resultMap标签 - 多条件查询 - 模糊查询

5. Mybatis 单表查询 - resultMap标签 - 多条件查询 - 模糊查询

5. Mybatis 单表查询 - resultMap标签 - 多条件查询 - 模糊查询

数据准备

# 数据准备DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` datetime default NULL COMMENT '生日', `sex` varchar(10) default NULL COMMENT '性别', `address` varchar(256) default NULL COMMENT '地址', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;/*Data for the table `user` */insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2019-05-27 17:47:08','男','北京'),(42,'王小二','2019-03-02 15:09:37','女','北京金燕龙'),(43,'老李','2019-03-04 11:34:34','女','北京修正'),(45,'传智播客','2019-03-04 12:04:06','男','北京金燕龙'),(46,'王小二','2018-09-07 17:37:26','男','北京TBD'),(48,'小马宝莉','2019-03-08 11:44:00','女','北京修正');

resultMap标签

如果数据库返回结果的列名和要封装的实体的属性名完全一致的话用 resultType 属性如果数据库返回结果的列名和要封装的实体的属性名有不一致的情况用 resultMap 属性

使用resultMap手动建立对象关系映射。

如果数据库返回结果的列名和要封装的实体的属性名完全一致的话用 resultType 属性

在前面篇章中,我们编写查询的都是 ​​select * from user​​​ 这样的查询,而查询的结果集字段名 都是对应 我们编写的实体类 User 相关属性名。所以我们设置返回的结果都是用 ​​resultType​​ 属性,如下:

image-20210314220431852

但是如果查询的结果集字段名 与 实体类User 属性名称不一致的话,那样就会导致获取不到参数的情况。

我们可以在​​UserMapper.xml​​修改一下查询的字段,使其与实体类 User 属性名称不一致,如下:

image-20210314220952906

现在我们在测试方法再执行查询看看结果,如下:

image-20210314221157415

// 使用MyBatisUtil工具类@Testpublic void test07() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); List allUsers = mapper.findAllUsers(); for (User user : allUsers) { System.out.println(user); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession);}

那么假设我们就是需要将查询的字段设置别名,那么我们该怎么做呢?下面来看看 resultMap 属性。

如果数据库返回结果的列名和要封装的实体的属性名有不一致的情况用 resultMap 属性

① UserMapper接口

查询接口方法不需要改变,还是照样接收 ​​List​​ 作为查询的结果。

image-20210314221359562

/* * # 查询 : 查询表中所有的用户 * 1.sql * select id,username,birthday,sex,address * from user * * 2.没有参数 * 3.返回值类型: List * */ List findAllUsers();

② UserMapper.xml

下面我们改用 resultMap 来定义查询结构集字段名 与 实体类属性名的 映射关系,从而成功读取数据。

image-20210314223244802

③ 测试

image-20210314223415104

// 使用MyBatisUtil工具类@Testpublic void test07() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); List allUsers = mapper.findAllUsers(); for (User user : allUsers) { System.out.println(user); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession);}

多条件查询_参数映射

需求

根据id和username查询user表。

在前面的案例中,我们只进行了单条件查询,而如果存在多条件查询的话,在参数设置的时候也会特殊处理一下。

而多条件查询具有两种解决方案:

方案一:将多条件查询的参数都进行传参,此时多个参数就需要设置参数映射方案二:将多条件查询的参数都封装到一个javabean的实体类 user 对象中,这样就只需要传递一个参数,那么就不需要进行参数映射

下面我们来逐个实现一下:

方案一:将多条件查询的参数都进行传参,此时多个参数就需要设置参数映射

① UserMapper接口

image-20210314230343178

/* * # 查询: 多条件查询 * 1. sql * select * from user where username = ? and sex = ? * * 2. 参数 * String , String * * 3. 返回值类型: List * * 接口和映射文件(参数映射) * 1. 如果只有一个参数,可以不用写参数映射 * 2. 如果有2个以及以上,必须要写参数映射 -> 如果没写,则会报异常:BindException * @Param("name") String name : 相当于告诉mybatis映射文件,这个属性是name * * *///方案一: 参数列举出来List findUsersByNameAndSex(@Param("name") String name, @Param("sex")String sex);

② UserMapper.xml

image-20210314230548846

③ 测试

image-20210314230949746

// 测试多条件查询@Testpublic void test08() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); List users = mapper.findUsersByNameAndSex("李小白", "男"); for (User user : users) { System.out.println(user); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession);}

在这里我们已经实现了多条件查询的操作,下面我们再来看看方案二。

方案二:将多条件查询的参数都封装到一个javabean的实体类 user 对象中,这样就只需要传递一个参数,那么就不需要进行参数映射

① UserMapper接口

image-20210314231107794

// 方案二: 把这些参数都封装一个javabean中List findUsersByNameAndSex2(User user);

② UserMapper.xml

image-20210314231947353

③ 测试

image-20210314232054423

@Testpublic void test09() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 2.1 封装查询参数到user对象 User user = new User(); user.setUsername("杜甫"); user.setSex("男"); // 2.2 传入user对象进行查询 List list = mapper.findUsersByNameAndSex2(user); for (User item : list) { System.out.println(item); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession);}

模糊查询

需求

根据username模糊查询user表。

方案一:在调用查询方法的位置直接传递 ​​%username%​​ 作为查询参数(不推荐,耦合严重)

① UserMapper接口

image-20210314235524127

/* * # 模糊查询 * sql : * select * from user where username like ? * 参数: * keyword = 白 , 拼接之后: %白% * 返回值: List * */List findUsersByKd(String keyword);

② UserMapper.xml

image-20210314235651351

③ 测试

image-20210314235911774

// 模糊查询:方案一@Testpublic void test10() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); //方案一: 耦合度太高(java程序写sql语法) List list = mapper.findUsersByKd("%白%"); for (User item : list) { System.out.println(item); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession);}

可以看到上面的示例中,我们在 java 代码里面设置关键字查询参数需要写成 ​​%白%​​ ,这样就导致 java代码 与 sql代码 之间的 耦合性比较高。

最好的方式就是 java 代码不需要写 ​​%​​ 这样的  sql 代码。

方案二:在接口映射文件拼接查询参数 ​​'%' #{keyword} '%'​​ (不推荐,mysql5.5版本之前,此拼接不支持多个单引号)

① UserMapper接口

不需要改变。

② UserMapper.xml

image-20210315000321089

③ 测试

image-20210315000528173

@Test public void test10() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); //方案二:在接口映射文件拼接查询参数 `'%' #{keyword} '%'` (不推荐,mysql5.5版本之前,此拼接不支持多个单引号) List list = mapper.findUsersByKd("白"); for (User item : list) { System.out.println(item); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession); }

方案三:在接口映射文件使用 ​​${} 字符串拼接​​ (不推荐,存在SQL注入的风险)

① UserMapper接口

不需要改变。

② UserMapper.xml

image-20210315000743411

③ 测试

image-20210315000953697

@Test public void test10() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 方案三:在接口映射文件使用 `${} 字符串拼接` (不推荐,存在SQL注入的风险) List list = mapper.findUsersByKd("白"); for (User item : list) { System.out.println("方案三: " + item); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession); }

方案四:在接口映射文件使用concat()函数拼接查询参数(推荐)

① UserMapper接口

不需要改变。

② UserMapper.xml

image-20210315001241211

③ 测试

image-20210315001322729

@Test public void test10() throws IOException { // 1. 获取 sqlSession 数据库连接会话 MyBatisUtil myBatisUtil = new MyBatisUtil(); SqlSession sqlSession = myBatisUtil.getSqlSession(); // 2. 执行查询操作 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 方案四:在接口映射文件使用concat()函数拼接查询参数(推荐) List list = mapper.findUsersByKd("白"); for (User item : list) { System.out.println("方案四: " + item); } // 3. 关闭会话 myBatisUtil.commitAndClose(sqlSession); }

${} 与 #{} 区别

​​${}​​:底层 Statement

sql与参数拼接在一起,会出现sql注入问题每次执行sql语句都会编译一次

​​#{}​​:底层 PreparedStatement

sql与参数分离,不会出现sql注入问题sql只需要编译一次

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:4. 使用Mybatis完成增删改查操作
下一篇:10. MyBatis缓存
相关文章

 发表评论

暂时没有评论,来抢沙发吧~