一、输入映射和输出映射
1.1、parameterType(输入类型)
1.1.1、传递简单类型
使用#{}占位符,或者${}进行sql拼接。
1.1.2、传递pojo对象
参考Mybatis基础系列(一)
Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。
1.1.3、传递pojo包装对象
包装对象:Pojo类中的一个属性是另外一个pojo。
需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。
编写QueryVo:
public class QueryVo {
// 包含其他的pojo
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Mapper.xml文件:
在UserMapper.xml中配置sql:
<!-- 根据用户名模糊查询 -->
<select id="findUserByQueryVo" parameterType="QueryVo" resultType="com.long.pojo.User">
select * from user where username like "%"#{user.username}"%"
</select>
Mapper接口:
在UserMapper接口中添加方法:
public interface UserMapper {
//遵循四个原则
//接口 方法名 == UserMapper.xml 中 id 名
//返回值类型 与 UserMapper.xml文件中返回值类型要一致
//方法的入参类型 与 UserMapper.xml中入参的类型要一致
//命名空间 绑定此接口
public List<User> findUserByQueryVo(QueryVo vo);
}
创建测试文件:
@Test
public void testQueryUserByQueryVo() {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行查询,使用包装对象
QueryVo queryVo = new QueryVo();
// 设置user条件
User user = new User();
user.setUsername("张");
// 设置到包装对象中
queryVo.setUser(user);
// 执行查询
List<User> list = userMapper.queryUserByQueryVo(queryVo);
for (User u : list) {
System.out.println(u);
}
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}
1.2、resultType(输出类型)
1.2.1、输出简单类型
需求:查询用户表数据条数:
在UserMapper.xml中配置sql:
<select id="countUser" resultType="Integer">
select count(1) from user
</select>
在UserMapper添加方法:
public interface UserMapper {
//查询数据条数
public Integer countUser();
}
测试:
@Test
public void testQueryUserCount() {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行查询用户数据条数
int count = userMapper.queryUserCount();
System.out.println(count);
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}
1.2.2、输出pojo对象
输出pojo对象可以参考上篇博客。
1.2.3、输出resultMap对象
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
需求:查询订单表order的所有数据:
数据库如下:
Order对象:
public class Order {
// 订单id
private int id;
// 用户id
private Integer userId; //名字和数据库字段不一样
// 订单号
private String number;
// 订单创建时间
private Date createtime;
// 备注
private String note;
get/set。。。
}
创建OrderMapper.xml配置文件:
<resultMap type="Orders" id="orders">
<result column="user_id" property="userId"/>
</resultMap>
<select id="selectOrdersList" resultMap="orders">
<SELECT id, user_id, number, createtime, note FROM orders
</select>
Mapper接口:
public interface OrderMapper {
// 查询订单表order的所有数据
public List<Orders> selectOrdersList();
}
测试程序:
//查询订单表order的所有数据
@Test
public void testOrderList() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<Orders> ordersList = mapper.selectOrdersList();
for (Orders orders : ordersList) {
System.out.println(orders);
}
}
二、动态SQL
通过mybatis提供的各种标签方法实现动态拼接sql。
2.1、动态SQL之if标签
需求:根据性别和名字查询用户
UserMapper接口:
public interface UserMapper {
// 根据性别和名字查询用户
public List<User> selectUserBySexAndUsername(User user);
}
UserMapper.xml配置sql:
<!-- 根据性别和名字查询用户 where 可以去掉第一个前ANd -->
<select id="selectUserBySexAndUsername" parameterType="User" resultType="User">
select * from user
<where>
<if test="sex != null and sex != ''">
sex = #{sex}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</where>
</select>
测试:
// 根据性别和名字查询用户
@Test
public void testfindUserBySexAndUsername() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setSex("1");
user.setUsername("张小明");
List<User> users = userMapper.selectUserBySexAndUsername(user);
for (User user2 : users) {
System.out.println(user2);
}
}
2.2、动态SQL之SQL片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
将select * from user提取出来:
<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
<sql id="selector">
select * from user
</sql>
<!-- 根据性别和名字查询用户 where 可以去掉第一个前ANd -->
<select id="selectUserBySexAndUsername" parameterType="User" resultType="User">
<include refid="selector"/>
<where>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</where>
</select>
</mapper>
2.3、动态SQL之foreach标签
根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)
接口:
public interface UserMapper {
//根据多个id查询用户信息
// public List<User> selectUserByIds(Integer[] ids);
// public List<User> selectUserByIds(List<Integer> ids);
public List<User> selectUserByIds(QueryVo vo);
}
QueryVO:
public class QueryVo implements Serializable {
private static final long serialVersionUID = 1L;
private User user;
List<Integer> idsList;
//Integer[] ids;
public List<Integer> getIdsList() {
return idsList;
}
public void setIdsList(List<Integer> idsList) {
this.idsList = idsList;
}
public Integer[] getIds() {
return ids;
}
public void setIds(Integer[] ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
如果用的是QueryVO,那么UserMapper.xml:
<select id="selectUserByIds" parameterType="QueryVo" resultType="User">
<include refid="selector"/>
<where>
<foreach collection="idsList" item="id" separator="," open="id in (" close=")">
#{id}
</foreach>
</where>
</select>
测试:
//多个ID
@Test
public void testfindUserIDs() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(16);
ids.add(22);
ids.add(24);
QueryVo vo = new QueryVo();
vo.setIdsList(ids);
List<User> users = userMapper.selectUserByIds(ids);
for (User user2 : users) {
System.out.println(user2);
}
}
如果用的是数组,那么接口:
public List<User> selectUserByIds(Integer[] ids);
UserMapper.xml:
<!-- 多个ID (1,2,3)-->
<select id="selectUserByIds" parameterType="QueryVo" resultType="User">
<include refid="selector"/>
<where>
<foreach collection="array" item="id" separator="," open="id in (" close=")">
#{id}
</foreach>
</where>
</select>
测试:
@Test
public void testfindUserIDs() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Integer[] ids = new Integer[3];
ids[0] = 16;
ids[2] = 22;
ids[1] = 24;
List<User> users = userMapper.selectUserByIds(ids);
for (User user2 : users) {
System.out.println(user2);
}
}
三、关联查询
3.1、一对一查询
因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。
3.1.1、方法一:使用resultType
使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息,这样返回对象的时候,mybatis自动把用户信息也注入进来了。
OrderUser类继承Order类后OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可:
public calss OrderUser extends Order{
private String username;
private String address;
}
Mapper.xml:
<!--
//一对一关联 查询 以订单为中心 关联用户
public List<Orders> selectOrders();
-->
<resultMap type="Orders" id="order">
<result column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<!-- 一对一 -->
<association property="user" javaType="User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
</association>
</resultMap>
<select id="queryOrderUser" resultType="orderUser">
SELECT
o.id,
o.user_id
userId,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
</select>
Mapper接口:
List<OrderUser> queryOrderUser();
测试:
@Test
public void testQueryOrderUser() {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行根据条件查询用户
List<OrderUser> list = userMapper.queryOrderUser();
for (OrderUser ou : list) {
System.out.println(ou);
}
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}
运行结果:
3.1.2、方法二:使用resultMap
使用resultMap,定义专门的resultMap用于映射一对一查询结果。
改造pojo类:
public class Orders implements Serializable{
private static final long serialVersionUID = 1L;
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//附加对象 用户对象
private User user;
}
接口:
public interface OrderMapper {
//一对一关联 查询 以订单为中心 关联用户
public List<Orders> selectOrders();
}
OrderMapper.xml:
<!--
//一对一关联 查询 以订单为中心 关联用户
public List<Orders> selectOrders();
-->
<resultMap type="Orders" id="order">
<result column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<!-- 一对一 -->
<association property="user" javaType="User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
</association>
</resultMap>
<select id="selectOrders" resultMap="order">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
u.username
FROM orders o
left join user u
on o.user_id = u.id
</select>
测试:
@Test
public void testOrderList() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSEssion帮我生成一个实现类 (给接口)
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
List<Orders> selectOrdersList = orderMapper.selectOrders();
for (Orders orders : selectOrdersList) {
System.out.println(orders);
}
}
3.2、一对多查询
改造pojo类:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
//附加对象List
private List<Orders> ordersList;
}
接口:
public interface OrderMapper {
//一对多关联
public List<User> selectUserList();
}
Mapper.xml:
<!--
//一对多关联
public List<User> selectUserList();
-->
<resultMap type="User" id="user">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<!-- 一对多 -->
<collection property="ordersList" ofType="Orders">
<id column="id" property="id"/>
<result column="number" property="number"/>
</collection>
</resultMap>
<select id="selectUserList" resultMap="user">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
u.username
FROM user u
left join orders o
on o.user_id = u.id
</select>
测试:
@Test
public void testUserList() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSEssion帮我生成一个实现类 (给接口)
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
List<User> users = orderMapper.selectUserList();
for (User user : users) {
System.out.println(user);
}
}
转载请标明出处,原文地址:https://blog.csdn.net/weixin_41835916 总结整理不容易,如果觉得本文对您有帮助,请点击顶支持一下,您的支持是我写作最大的动力,谢谢。