MyBatis参数处理和查询语句专题
- 一、MyBatis参数处理
- 1.单个简单类型参数
- 2.单个Map参数
- 3.单个实体类参数
- 4.多参数
- 5.@Param注解(命名参数)
- 二、MyBatis查询语句专题
- 1.结果映射
- (1)as 给列起别名
- (2)使⽤resultMap进⾏结果映射
- (3)是否开启驼峰命名⾃动映射(配置settings)
- 2.返回实体类
- 3.返回List
- 4.返回Map
- 5.返回List<Map>
- 6. 返回Map<String,Map>
- 7.返回总记录条数
一、MyBatis参数处理
1.单个简单类型参数
- 简单类型包括:
- byte short int long float double char
- Byte Short Integer Long Float Double Character
- java.lang.String
- java.util.Date
- java.sql.Date
- 通过测试得知,简单类型对于 mybatis 来说都是可以⾃动类型识别的:
- 也就是说对于 mybatis 来说,它是可以⾃动推断出 ps.setXxxx() ⽅法的。ps.setString() 还是 ps.setInt()。它可以⾃动推断。
- 其实SQL映射⽂件中的配置⽐较完整的写法是:
<select id="selectByName" resultType="student" parameterType="java.lang.String"> select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR} </select>
- 其中 sql 语句中的 javaType,jdbcType,以及 select 标签中的 parameterType 属性,都是⽤来帮助 mybatis 进⾏类型确定的。不过这些配置多数是可以省略的。因为 mybatis 它有强⼤的⾃动类型推断机制。
- javaType:可以省略
- jdbcType:可以省略
- parameterType:可以省略
- 如果参数只有⼀个的话,#{} ⾥⾯的内容就随便写了。对于 ${} 来说,注意加单引号。
- Mybatis 内置的一些别名:参考官方手册 ===> https://mybatis.net.cn/configuration.html#typeAliases
2.单个Map参数
- 这种⽅式是⼿动封装 Map 集合,将每个条件以 key 和 value 的形式存放到集合中。然后在使⽤的时候通过 #{map集合的key} 来取值。
3.单个实体类参数
- 这⾥需要注意的是:#{} ⾥⾯写的是属性名字。这个属性名其本质上是:set/get ⽅法名去掉 set/get 之后的名字。
4.多参数
<select id="selectByNameAndSex" resultType="student">
<!--select * from t_student where name = #{name} and sex = #{sex}-->
<!--select * from t_student where name = #{arg0} and sex = #{arg1}-->
<!--select * from t_student where name = #{param1} and sex = #{param2}-->
select * from t_student where name = #{arg0} and sex = #{param2}
</select>
- arg0 是第⼀个参数、param1是第⼀个参数、arg1 是第⼆个参数、param2是第⼆个参数
- 实现原理:实际上在mybatis底层会创建⼀个map集合,以arg0/param1为key,以⽅法上的参数为value,例如以下代码:
Map<String,Object> map = new HashMap<>(); map.put("arg0", name); map.put("arg1", sex); map.put("param1", name); map.put("param2", sex); // 所以可以这样取值:#{arg0} #{arg1} #{param1} #{param2} // 其本质就是#{map集合的key}
- 注意:使⽤ mybatis3.4.2 之前的版本时:要⽤#{0}和#{1}这种形式。
5.@Param注解(命名参数)
- 可以不⽤ arg0 arg1 param1 param2,这个 map 集合的 key 我们可以使⽤ @Param 注解自定义。这样可以增强可读性。
- 核⼼:@Param(“这⾥填写的其实就是map集合的key”)。
<!-- ArticleMapper.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.gdb.mybatis.param.mapper.ArticleMapper">
<select id="selectForUserIdAndTitle" resultType="Article">
select * from article where user_id = #{userId} and title = #{title}
</select>
</mapper>
//ArticleMapper接口
package com.gdb.mybatis.param.mapper;
import com.gdb.mybatis.param.pojo.Article;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ArticleMapper {
List<Article> selectForUserIdAndTitle(@Param("userId") Integer userId, @Param("title") String title);
}
//测试代码
package com.gdb.mybatis.param.test;
import com.gdb.mybatis.param.mapper.ArticleMapper;
import com.gdb.mybatis.param.pojo.Article;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.util.List;
public class TestParam {
@Test
public void testParamAnnotation() throws Exception{
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"), "development");
SqlSession sqlSession = sqlSessionFactory.openSession();
ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
List<Article> articles = mapper.selectForUserIdAndTitle(9874, "JavaWeb");
System.out.println(articles);
sqlSession.close();
}
}
- 这里可以看到有部分属性为 null,这个问题可以看第二部分 MyBatis查询语句专题。
二、MyBatis查询语句专题
1.结果映射
(1)as 给列起别名
<select id="selectArticleForId" resultType="Article">
select id,
user_id as userId,
title,
summary,
read_count as readCount,
create_time as createTime,
update_time as updateTime
from article
where id = #{id};
</select>
(2)使⽤resultMap进⾏结果映射
<!--
resultMap:
id:这个结果映射的标识,作为select标签的resultMap属性的值。
type:结果集要映射的类。可以使⽤别名。
-->
<resultMap id="ArticleResultMap" type="Article">
<!--对象的唯⼀标识,官⽅解释是:为了提⾼mybatis的性能。建议写上。-->
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<!--当属性名和数据库列名⼀致时,可以省略。但建议都写上。-->
<!--javaType⽤来指定属性类型。jdbcType⽤来指定列类型。⼀般可以省略。-->
<result property="title" column="title" javaType="string" jdbcType="VARCHAR"/>
<result property="summary" column="summary"/>
<result property="readCount" column="read_count"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<!--resultMap属性的值必须和resultMap标签中id属性值⼀致。-->
<select id="selectAllByResultMap" resultMap="ArticleResultMap">
select * from article
</select>
(3)是否开启驼峰命名⾃动映射(配置settings)
- 使⽤这种⽅式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
- Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。
- SQL命名规范:全部⼩写,单词之间采⽤下划线分割。
<!--放在properties标签后⾯-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
2.返回实体类
-
查询结果是⼀条的话可以使⽤List集合接收。
-
启用驼峰命名方式,完成数据库表字段到Java类属性的映射。
<select id="SelectArticleForIdRetPojo" resultType="Article"> select * from article where id = #{id} </select>
-
ArticleMapper.java
- 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
Article SelectArticleForIdRetPojo(Integer id);
-
测试程序
@Test public void SelectArticleForIdRetPojo() throws IOException { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development"); SqlSession sqlSession = sqlSessionFactory.openSession(); ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class); Article article = mapper.SelectArticleForIdRetPojo(1); System.out.println(article); sqlSession.close(); }
3.返回List
- 当查询的记录条数是多条的时候,必须使⽤集合接收。如果使⽤单个实体类接收会出现异常。
4.返回Map
- 当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收。字段名做key,字段值做value。
- 查询如果可以保证只有⼀条数据,则返回⼀个Map集合即可。(如果返回结果不是一条记录,使用一个 Map 集合来接收会出现异常。)
5.返回List
-
查询结果条数⼤于等于1条数据,则可以返回⼀个存储 Map 集合的 List 集合 List<Map>。
-
ArticleMapper.xml
<select id="selectAllRetListMap" resultType="map"> select * from article </select>
-
ArticleMapper.java
- 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
List<Map<String,Object>> selectAllRetListMap();
-
测试程序
@Test public void selectAllRetListMap() throws IOException { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development"); SqlSession sqlSession = sqlSessionFactory.openSession(); ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class); List<Map<String, Object>> list = mapper.selectAllRetListMap(); System.out.println(list); sqlSession.close(); }
6. 返回Map<String,Map>
-
拿 Article 的 id 做 key,以后取出对应的 Map 集合时更⽅便。
-
ArticleMapper.xml
<select id="selectAllArticleRetBigMap" resultType="map"> select * from article </select>
-
ArticleMapper.java
- 注意:这里要使用 MapKey 注解来指定大 Map 的 key。
@MapKey("id") Map<String, Map<String, String>> selectAllArticleRetBigMap();
-
测试程序
@Test public void selectAllArticleRetBigMap() throws IOException { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development"); SqlSession sqlSession = sqlSessionFactory.openSession(); ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class); Map<String, Map<String, String>> stringMapMap = mapper.selectAllArticleRetBigMap(); System.out.println(stringMapMap); sqlSession.close(); }
7.返回总记录条数
-
ArticleMapper.xml
<select id="selectForRowCount" resultType="_int"> select count(*) from article; </select>
-
ArticleMapper.java
public interface ArticleMapper { int selectForRowCount(); }
-
测试程序
@Test public void testQueryAllRow() throws IOException { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"), "development"); SqlSession sqlSession = sqlSessionFactory.openSession(); ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class); int count = mapper.selectForRowCount(); System.out.println("count = " + count); sqlSession.close(); }
-
结果展示