mybatis专栏 https://blog.csdn.net/worn_xiao/category_6530299.html?spm=1001.2014.3001.5482
一Mybaties之输入映射
parameterType:可以是别名或者全限定名,他接受简单类型pojo,hashmap。
1.1 简单类型。
select id="findUserById" parameterType="int"resultType="User">
SELECT * FROM USER WHERE id =#{id}
</select>
1.2 传递pojo包装对象。
(当一个查询的查询条件来自多个对象时,可能要对查询条件做封装)做为最终的查询条件
1.2.1 Vo
publicclass UserExt extends User{
}
publicClass UserQueryVo{
private UserExt userext;
public UserExt getUserext(){
return this.userext;
}
public void setUserext(UserExt userext){
this.userext=userext;
}
}
1.2.2 接口
//通过包装类来进行复杂的用户信息综合查询
public List<UserExt> findUserList(UserQueryVOuserQueryVO);
1.2.3 配置文件
<!-- 通过包装类来进行复杂的用户信息综合查询 -->
<select id="findUserList"parameterType="userQueryVO" resultType="userExt">
SELECT * FROM USER WHERE sex=#{userExt.sex} AND usernameLIKE '%${userExt.username}%'
</select>
1.2.4 测试
@Test
publicvoid findUserListTest() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVO userQueryVO = new UserQueryVO();
UserExt userExt= new UserExt();
userExt.setSex("1");
userExt.setUsername("小明");
userQueryVO.setUserExt(userExt);
List<UserExt> list = userMapper.findUserList(userQueryVO);
System.out.println(list);
sqlSession.close();
}
1.3 传递hashmap。
同传递POJO对象一样,map的key相当于pojo的属性。
1.3.1 映射文件
<!-- 传递hashmap综合查询用户信息 -->
<selectid="findUserByHashmap" parameterType="hashmap" resultType="user">
select * from user where id=#{id} and username like '%${username}%'
</select>
1.3.2 测试代码
Public void testFindUserByHashmap()throwsException{
SqlSessionsession = sqlSessionFactory.openSession();
UserMapperuserMapper = session.getMapper(UserMapper.class);
HashMap<String,Object> map = newHashMap<String, Object>();
map.put("id", 1);
map.put("username", "管理员");
List<User>list= userMapper.findUserByHashmap(map);
session.close();
}
二Mybaties之输出映射
Resultype映射:查询出的列名与pojo完全一致,才能映射成功
如果查询出的列名与pojo完全不一致,则不会创建pojo
只要查询出的列名有一列与pojo一致,就会创建pojo对象
2.1 输出简单类型
当输出结果只有一列时,可以使用resultType指定简单类型,作为输出类型
2.1.1 xml
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount"parameterType="UserQueryVO"
resultType="int">
SELECT count(1) FROM USER WHEREsex = #{userExt.sex} AND username LIKE'%${userExt.username}%'
</select>
2.1.2 mapper接口
public int findUsersCount(UserQueryVO vo);
2.1.3 测试类
@Test
publicvoidtestFindUsersCount() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVO userQueryVO = new UserQueryVO();
UserExt userExt= new UserExt();
userExt.setSex("1");
userExt.setUsername("小明");
userQueryVO.setUserExt(userExt);
int count = mapper.findUsersCount(userQueryVO);
System.out.println(count); // 关闭SqlSession
sqlSession.close();
}
2.2 输出pojo类型
注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。
2.2.1 xml文件
<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
2.2.2 mapper接口
2.2.2.1 输出单个pojo对象
//根据用户名称来模糊查询用户信息
public UserfindUsersByName(String username);
2.2.2.2 输出pojo列表
//根据用户名称来模糊查询用户信息列表
public List<User> findUsersByName(String username);
总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,会根据返回值的类型,决定调用selectOne方法还是selectList方法。
2.3 输出resultMap类型
进行高级结果映射时作为输出,如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。
1、 定义resultMap
2、 使用resultMap作为statement的输出映射类型。
2.3.1 xml文件的定义
<!-- 定义resultMap -->
<!--
[id]:定义resultMap的唯一标识
[type]:定义该resultMap最终映射的pojo对象
[id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签
[result标签]:映射结果集的普通列
[column]:SQL查询的列名,如果列有别名,则该处填写别名
[property]:pojo对象的属性名
-->
<resultMap type="user"id="userResultMap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="sex_" property="sex"/>
</resultMap>
<!-- 根据ID查询用户信息(学习resultMap) -->
<select id="findUserByIdResultMap"parameterType="int" resultMap="userResultMap">
SELECT id id_,usernameusername_,sex sex_ FROM USER WHERE id = #{id}
</select>
2.3.2 定义接口
//根据ID查询用户信息(学习resultMap)
public User findUserByIdResultMap(int id);
定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。
2.3.3 测试代码
@Test
publicvoid findUserByIdResultMapTest() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
sqlSession.close();
}
三Mybaties之动态SQL
通过Mybatis提供的各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach;
3.1 if标签与where
做为入参的判断条件来用的,如果符合条件则拼接上
where标签,会去除条件中的and符号
3.1.1. xml文件
<selectid="findUsersByQueryVO" parameterType="cn.itcast.mybatis.po.QueryUserVO"
resultType="User">
SELECT * FROM USER
<where>
<if test="userExt !=null">
<if test="userExt.sex !=null and userExt.sex != ''">
AND sex = #{userExt.sex}
</if>
<if test="userExt.username!= null and userExt.username != ''">
AND username LIKE '%${userExt.username}%'
</if>
</if>
</where>
</select>
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount"parameterType="QueryUserVO" resultType="int">
SELECT count(1) FROM USER
<!--where标签:默认去掉后面第一个AND,如果没有参数,则把自己干掉 -->
<where>
<if test="userExt !=null">
<if test="userExt.sex !=null and userExt.sex != ''">
AND sex = #{userExt.sex}
</if>
<if test="userExt.username!= null and userExt.username != ''">
AND username LIKE '%${userExt.username}%'
</if>
</if>
</where>
</select>
3.1.2 mapper接口的特点
//通过包装类来进行复杂的用户信息综合查询
public List<UserExt> findUserList(UserQueryVOuserQueryVO);
//综合查询用户总数
public int findUsersCount(UserQueryVO userQueryVO);
@Test
publicvoid testFindUserList() throwsException {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserQueryVO vo = new UserQueryVO();
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(10);
vo.setIdList(idList);
List<User> list = mapper.findUserList(vo);
intcount = mapper.findUserCount(vo);
System.out.println(list);
System.out.println(count);
sqlSession.close();
}
3.2 sql片段,可以去除重复的sql的编写
<!-- 定义sql片段 -->
<!-- sql片段内,可以定义sql语句中任何部分-->
<!-- sql片段内,最好不用将where和select关键字声明在内-->
<sql id=" select_user_where ">
<!-- if标签:可以对输入的参数进行判断 -->
<!-- test:指定判断表达式-->
<if test=" userExt!= null">
<if test=" userExt .username != nulland userExt .username != ''">
AND username LIKE '%${username}%'
</if>
<if test=" userExt .sex != null and userExt.sex!= ''">
AND sex = #{user.sex}
</if>
</if>
<if test="idList != null">
<!-- AND id IN(#{id},#{id},#{id}) -->
<!--collection:表示pojo中集合属性的属性名称 -->
<!-- item:为遍历出的结果声明一个变量名称 -->
<!-- open:遍历开始时,需要拼接的字符串 -->
<!-- close:遍历结束时,需要拼接的字符串 -->
<!-- separator:遍历中间需要拼接的连接符-->
AND id IN
<foreach collection="idList"item="id" open="("close=")"
separator=",">
#{id}
</foreach>
</if>
</sql>
使用<includerefid=’’ /> 来引用SQL片段:
<!-- 根据用户id来查询用户信息(使用SQL片段) -->
<!--
[include标签]:引用已经定义好的SQL片段
[refid]:引用的SQL片段id
-->
<select id="findUserList"parameterType="userQueryVO" resultType="userExt">
SELECT * FROM USER
<where>
<include refid="select_user_where"/>
</where>
</select>
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findUsersCount"parameterType="QueryUserVO"
resultType="int">
SELECT count(1) FROM USER
<where>
<include refid="select_user_where"/>
</where>
</select>
3.3 Foreach
向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。
需求:根据用户id列表查询用户
SELECT * FROM user WHERE id IN (1,10,16)
3.3.1 Vo对象
public Class UserQueryVo{
privateUserExt userext;
List<Integer>idList;
publicvoid setIdList(List<Integer> idList){
this.idList=idList;
}
publicList<Integer> getIdList(){
returnthis.idList;
}
publicUserExt getUserext(){
return this.userext;
}
publicvoid setUserext(UserExt userext){
this.userext=userext;
}
}
3.3.2 Xml映射文件
<!-- [foreach标签]:表示一个foreach循环 -->
<!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 -->
<!-- [item]:每次遍历出来的对象 -->
<!-- [open]:开始遍历时拼接的串 --> 一般来说防止(括号
<!-- [close]:结束遍历时拼接的串 -->一般来说防止)括号
<!--[separator]:遍历出的每个对象之间需要拼接的字符 -->
<if test="idList != nulland idList.size > 0">
<foreach collection="idList" item="id"open="AND id IN (" close=")" separator=",">
#{id}
</foreach>
</if>
3.3.3 Mapper接口
//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合)
public List<UserExt> findUserList(UserQueryVO vo);
3.3.4 测试类
@Test
publicvoid testFindUserList() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 构造QueryUserVO对象
QueryUserVO vo = newQueryUserVO();
// 创建用户ID集合,然后设置到QueryUserVO对象中
List<Integer> idList = newArrayList<Integer>();
idList.add(1);
idList.add(10);
idList.add(16);
vo.setIdList(idList);
// 调用mapper代理对象的方法
List<UserExt> list = mapper.findUserList(vo);
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
3.3.5直接传递List
如果还直接传递List集合的固定写法如下
如果是直接传入集合参数,则参数名称只能填写[list]
<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) -->
<!--
[foreach标签]:表示一个foreach循环
[collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。
[item]:定义遍历集合之后的参数名称
[open]:开始遍历之前需要拼接的SQL串
[close]:结束遍历之后需要拼接的SQL串
[separator]:遍历出的每个对象之间需要拼接的字符
-->
<select id="findUsersByIdList"parameterType="java.util.List"resultType="user">
SELECT * FROM USER
<where>
<if test="list != null and list.size > 0">
<foreach collection="list" item="id"open="AND id IN (" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
3.3.6 mapper接口:
用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)
public List<User> findUsersByIdList (List<Integer>idList);
3.3.7 测试类
@Test
publicvoid findUsersByIdListTest(){
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 构造List<Integer>集合
List<Integer> idList = new ArrayList<Integer>();
idList.add(1);
idList.add(10);
idList.add(16);
// 调用mapper对象的方法
List<User> list = userMapper.findUsersByIdList (idList);
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
}