需求:
查询订单信息,关联查询创建订单的用户信息。
记住:用Mybatis开发的顺序就是
1.写sql语句
2.创建pojo类来完成映射
3.写Mapper.xml
4.写Mapper.java接口
---------------------------------------------------------------------------------------------------------------------------------------------------
我们知道Mybatis中mapper.xml中分为resultType和resultMap两种,这两种我们都讲:
一:先讲resultMap:
先给出案例结构:
cn.itcast.mybatis.po包下面的类(items,orderdetail,Orders,User)都是根据数据库的4张表创建的实体类。
1.我们先来分析一下怎么写sql语句:
写sql语句时要先根据需求确定查询的主表和查询的关联表:
根据“查询订单信息,关联查询创建订单的用户信息” 很明显,查询的主表是订单表,查询的关联是用户表。
关联查询使用内链接?还是外链接?由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接。
sql如下:
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id = user.id
2.根据select(orders.*,USER.username,USER.sex,USER.address)语句 创建Pojo类
我们创建的pojo类要满足orders.*,USER.username,USER.sex,USER.address这些映射,很明显单纯依靠数据库的映射(Orders.java和User.java)不能满足,所以要新写一个类OrdersCustom.java。
如下:
package cn.itcast.mybatis.po;import java.util.Date;public class OrdersCustom extends Orders{ private String username; private String sex; private String address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
为什么这个类要继承Orders而不是继承User.java因为根据orders.*,USER.username,USER.sex,USER.address,很明显,要映射的数据是order表中的全部数据以及user
表中的username,sex,address这些数据,直接继承Order类的话就可以少定义一些属性,只要定义username,sex,address。就可以了。
3.写Mapper.xml和Mapper.java接口(放在同一个包下面,用接口的方式去加载)
OrderMapperCustom.xml的代码如下:
OrdersMapperCustom.java代码如下:
package cn.itcast.mybatis.mapper;import java.util.List;import cn.itcast.mybatis.po.OrdersCustom;public interface OrdersMapperCustom { public ListfindOrdersUser();}
同时不要忘了在SqlMapConfig.xml。
4.编写测试代码Mybatis_mappertest.java:
package cn.itcast.mybatis.test;import java.io.IOException;import java.io.InputStream;import java.util.Date;import java.util.List;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.Before;import org.junit.Test;import cn.itcast.mybatis.mapper.OrdersMapperCustom;import cn.itcast.mybatis.mapper.userMapper;import cn.itcast.mybatis.po.User;import cn.itcast.mybatis.po.UserCustom;import cn.itcast.mybatis.po.UserQueryVo;public class Mybatis_mappertest { private SqlSessionFactory sqlSessionFactory; @Before public void setup() throws IOException { String resource="SqlMapConfig.xml"; InputStream inputStream= Resources.getResourceAsStream(resource); //主要是生成SqlsessionFactory。 this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testMaper() { SqlSession sqlSession=null; sqlSession=sqlSessionFactory.openSession(); //生成代理类 OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class); orderMapper.findOrdersUser(); }}
运行结果:一切正常。
二:再讲resultMap(重点):
resultMap映射的思想:
使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。也就是说查出来的user信息都要映射在orders中新开的一个user属性中。
还是按照第一sql语句,第二pojo类,第三mapper.xml,mapper.java接口这种顺序来写。
1.sql语句:和之前的resulrType的sql语句一样:
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id = user.id
2.写pojo类:在原来的Orders.java中新增一个User属性:
User类:
package cn.itcast.mybatis.po;import java.util.Date;//对应数据库中的user表public class User {private int id;//对应数据库中主键private String username;//对应数据库中用户的名称private Date birthday;//对应数据库中的生日private String sex;//性别private String address;//地址public int getId() { return id;}public void setId(int id) { this.id = id;}public String getUsername() { return username;}public void setUsername(String username) { this.username = username;}public Date getBirthday() { return birthday;}public void setBirthday(Date birthday) { this.birthday = birthday;}public String getSex() { return sex;}public void setSex(String sex) { this.sex = sex;}public String getAddress() { return address;}public void setAddress(String address) { this.address = address;}}
Orders.java类:
package cn.itcast.mybatis.po;import java.util.Date;public class Orders {private Integer id;private Integer user_id;private String number;private Date createtime;private String note;//新增了一个User属性,为了保存查询得到的关联的User表的信息private User user;public User getUser() { return user;}public void setUser(User user) { this.user = user;}public Integer getId() { return id;}public void setId(Integer id) { this.id = id;}public Integer getUser_id() { return user_id;}public void setUser_id(Integer user_id) { this.user_id = user_id;}public String getNumber() { return number;}public void setNumber(String number) { this.number = number;}public Date getCreatetime() { return createtime;}public void setCreatetime(Date createtime) { this.createtime = createtime;}public String getNote() { return note;}public void setNote(String note) { this.note = note;}}
3.写mapper.xml和mapper.java接口
OrdersMapperCustom.xml:
OrdersMapperCustom.java接口
package cn.itcast.mybatis.mapper;import java.util.List;import cn.itcast.mybatis.po.Orders;import cn.itcast.mybatis.po.OrdersCustom;public interface OrdersMapperCustom {//这里的的函数名字要和OrdersMapperCustom.xml中的id一模一样 public ListfindOrdersUser(); public List findOrdersUseResultMap();}
Junit测试代码:
package cn.itcast.mybatis.test;import java.io.IOException;import java.io.InputStream;import java.util.Date;import java.util.List;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.Before;import org.junit.Test;import cn.itcast.mybatis.mapper.OrdersMapperCustom;import cn.itcast.mybatis.mapper.userMapper;import cn.itcast.mybatis.po.Orders;import cn.itcast.mybatis.po.User;import cn.itcast.mybatis.po.UserCustom;import cn.itcast.mybatis.po.UserQueryVo;public class Mybatis_mappertest { private SqlSessionFactory sqlSessionFactory; @Before public void setup() throws IOException { String resource="SqlMapConfig.xml"; InputStream inputStream= Resources.getResourceAsStream(resource); //主要是生成SqlsessionFactory。 this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testMaper() { SqlSession sqlSession=null; sqlSession=sqlSessionFactory.openSession(); //生成代理类 OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class); //创建包装对象,设置查询条件 //orderMapper.findOrdersUser(); @SuppressWarnings("unused") Listlist=orderMapper.findOrdersUseResultMap(); }}
运行结果:一切正常。
resultType和resultMap实现一对一查询小结
实现一对一查询:
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果没有查询结果的特殊要求建议使用resultType。
resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。