指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、POJO、HashMap。
1、传递简单类型根据用户ID查询用户信息:
SELECT LAST_INSERT_ID()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),
这时可以使用包装对象传递输入参数。
综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。
一般User.java类要和数据表表字段一致,最好不要在这里面添加其他字段,在mybatis的逆向工程时,会根据表结构,生成po类,
如果在po类中扩展字段,此时会被覆盖掉。
所以针对要扩展的po类,我们需要创建一个扩展类,来继承它。
public class UserExt extends User{
//这里可以定义user的一些扩展信息
}
定义POJO包装类:
public class UserQueryVO {
//用户信息
private UserExt userExt;
//商品ID集合
private List idList;
//商品信息
public List getIdList() {
return idList;
}
public void setIdList(List idList) {
this.idList = idList;
}
public UserExt getUserExt() {
return userExt;
}
public void setUserExt(UserExt userExt) {
this.userExt = userExt;
}
//订单信息
}
//通过包装类来进行复杂的用户信息综合查询
public List findUserList(UserQueryVO userQueryVO);
注意:入参的类型变为UserQueryVO、结果集的类型变为UserExt,#{}里面的参数变为UserQueryVO对象中的userExt属性的sex和username子属性。
@Test
public void findUserListTest() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//构造userQueryVO对象
UserQueryVO userQueryVO = new UserQueryVO();
// 构造UserExt对象
UserExt userExt = new UserExt();
userExt.setSex("1");
userExt.setUsername("小明");
userQueryVO.setUserExt(userExt);
// 调用mapper对象的方法
List list = userMapper.findUserList(userQueryVO);
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
}
同传递POJO对象一样,map的key相当于pojo的属性。
4.1映射文件
上边红色标注的id和username是hashmap的key。
Public void testFindUserByHashmap()throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//构造查询条件Hashmap对象
HashMap map = new HashMap();
map.put("id", 1);
map.put("username", "管理员");
//传递Hashmap对象查询用户列表
Listlist = userMapper.findUserByHashmap(map);
//关闭session
session.close();
}
异常测试:
传递的map中的key和sql中解析的key不一致。
测试结果没有报错,只是通过key获取值为空。
使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。
如果查询的列名和映射的pojo属性名全部不一致,那么映射的对象为空,不会创建pojo对象;
如果查询的列名和映射的pojo属性名有一个一致,那么映射的对象不为空,会创建pojo对象,但是只有映射正确的那一个属性才有值。
注意,对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。
当输出结果只有一列时,可以使用ResultType指定简单类型作为输出结果类型。
2.1需求综合查询用户总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。
//综合查询用户信息总数。学习:resultType输出简单类型
public int findUsersCount(UserQueryVO vo);
@Test
public void testFindUsersCount() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//构造userQueryVO对象
UserQueryVO userQueryVO = new UserQueryVO();
// 构造UserExt对象
UserExt userExt = new UserExt();
userExt.setSex("1");
userExt.setUsername("小明");
userQueryVO.setUserExt(userExt);
int count = mapper.findUsersCount(userQueryVO);
System.out.println(count); // 关闭SqlSession
sqlSession.close();
}
注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。
3.1Mapper映射文件
//根据用户名称来模糊查询用户信息
public User findUsersByName(String username);
//根据用户名称来模糊查询用户信息列表
public List findUsersByName(String username);
总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,
会根据返回值的类型,决定调用selectOne方法还是selectList方法。
resultMap可以进行高级结果映射(一对一、一对多映射)。
如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。
1、 定义resultMap
2、 使用resultMap作为statement的输出映射类型。
把下面SQL的输出结果集进行映射
SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1
定义resultMap:
定义statement:
//根据ID查询用户信息(学习resultMap)
public User findUserByIdResultMap(int id);
定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。
@Test
public void findUserByIdResultMapTest() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper对象的方法
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
// 关闭SqlSession
sqlSession.close();
}
Ø If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;
Ø Where标签:会去掉条件中的第一个and符号。
用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态SQL。
//通过包装类来进行复杂的用户信息综合查询
public List findUserList(UserQueryVO userQueryVO);
//综合查询用户总数
public int findUsersCount(UserQueryVO userQueryVO);
不传用户名:
@Test
public void testFindUserList() throws Exception{
// 创建UserMapper对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 由mybatis通过sqlsession来创建代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
QueryUserVO vo = new QueryUserVO();
User user = new User();
//此处使用动态SQL,不传username参数
user.setSex("1");
// user.setUsername("小明");
vo.setUser(user);
List list = mapper.findUserList(vo);
System.out.println(user);
sqlSession.close();
}
输出的SQL如下(也不包含用户名):
通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。
Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。
2.1定义SQL片段使用sql标签来定义一个SQL片段:
AND sex = #{userExt.sex}
AND username LIKE '%${userExt.username}%'
使用
向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。
(1)传递pojo对象中的list集合在用户查询列表和查询总数的statement中增加多个id输入查询。
SELECT * FROM user WHERE id IN (1,10,16)
package com.itheima.mybatis.po;
import java.util.List;
/**
* Title: UserQueryVO
* Description: TODO(这里用一句话描述这个类的作用)
*/
public class UserQueryVO {
//用户信息
private UserExt userExt;
//商品ID集合
private List idList;
//商品信息
public List getIdList() {
return idList;
}
public void setIdList(List idList) {
this.idList = idList;
}
public UserExt getUserExt() {
return UserExt;
}
public void setUserExt(UserExt userExt) {
this.UserExt = UserExt;
}
//订单信息
}
#{id}
//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合)
public List findUserList(UserQueryVO vo);
@Test
public void testFindUserList() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 构造QueryUserVO对象
QueryUserVO vo = new QueryUserVO();
// UserExt ext = new UserExt();
// ext.setUsername("小明");
// ext.setSex("1");
// vo.setUserExt(ext);
// 创建用户ID集合,然后设置到QueryUserVO对象中
List idList = new ArrayList();
idList.add(1);
idList.add(10);
idList.add(16);
vo.setIdList(idList);
// 调用mapper代理对象的方法
List list = mapper.findUserList(vo);
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
}
根据用户ID的集合查询用户列表
SELECT * FROM user WHERE id IN (1,10,16)
//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)
public List findUsersByIdList (List idList);
@Test
public void findUsersByIdListTest() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 构造List集合
List idList = new ArrayList();
idList.add(1);
idList.add(10);
idList.add(16);
// 调用mapper对象的方法
List list = userMapper.findUsersByIdList (idList);
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
}