MyBatis多表操作 一对一查询模型 以用户-订单模型为例,假定用户与订单之间是一一对应的关系,建立如下数据库
订单表中的userId表示标识用户的ID信息,若直接通过sql语句进行一对一查询,则可写作select * from orders o ,user u where o.userId=u.id
,得到如下查询结果
可在mybatis中进行查询时,其并不知道各个数据段对应的参数,所以需要我们手动通过map进行对应
首先定义order类,注意这里通过User对象来储存的用户信息,而不是数据库中的userId
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class Order { private Long id; private String orderName; private int orderAmount; private User user; public Long getId () { return id; } public void setId (Long id) { this .id = id; } public String getOrderName () { return orderName; } public void setOrderName (String orderName) { this .orderName = orderName; } public int getOrderAmount () { return orderAmount; } public void setOrderAmount (int orderAmount) { this .orderAmount = orderAmount; } public User getUser () { return user; } public void setUser (User user) { this .user = user; } @Override public String toString () { return "Order{" + "id=" + id + ", orderName='" + orderName + '\'' + ", orderAmount=" + orderAmount + ", user=" + user + '}' ; } }
实现mapper接口类
1 2 3 public interface OrderMapper { public List<Order> findAll () ; }
映射文件,可以看到这里通过resultMap配置数据段(column)和类属性(property)的映射关系(注意,这里在sql语句中对order中的id使用了别名为oid,这是为了防止两表都有的id数据段造成混淆)
这里的column代表的数据段不单纯是user或order任一表的数据段,而是经过查询后得到的新表的数据段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <mapper namespace ="cn.ywrby.mapper.OrderMapper" > <resultMap id ="orderMap" type ="order" > <id column ="oid" property ="id" /> <result column ="orderName" property ="orderName" /> <result column ="orderAmount" property ="orderAmount" /> <result column ="userId" property ="user.id" /> <result column ="username" property ="user.username" /> <result column ="password" property ="user.password" /> </resultMap > <select id ="findAll" resultMap ="orderMap" > select *,o.id oid from orders o ,user u where o.userId=u.id </select > </mapper >
这里的resultMap还有第二种配置方式,对于order中的user属性的所有值进行单独封装
1 2 3 4 5 6 7 8 9 10 11 <resultMap id ="orderMap" type ="order" > <id column ="id" property ="id" /> <result column ="orderName" property ="orderName" /> <result column ="orderAmount" property ="orderAmount" /> <association property ="user" javaType ="user" > <id column ="userId" property ="id" /> <result column ="username" property ="username" /> <result column ="password" property ="password" /> </association > </resultMap >
然后需要在核心配置文件中配置这个新的映射文件并指定别名order
测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void test () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = factory.openSession(); OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); List<Order> orderList=mapper.findAll(); for (Order order: orderList) { System.out.println(order); } sqlSession.close(); }
一对多查询模型 现在假设一个用户可能拥有多个订单的情况,此时通过数据库直接用sql语句查询的方式如下select *,o.id oid from user u ,orders o where o.userId=u.id
,可以看到一个用户出现对应多个订单的情况,此时在用户的属性中加入List<Order> orderList
用于存储订单集合
这种情况下MyBatis的查询方式如下,collection标签就是用于处理集合类型数据,ofType属性表示集合中存储的数据类型(这里用了别名)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <mapper namespace ="cn.ywrby.mapper.UserMapper" > <resultMap id ="userMap" type ="user" > <id column ="id" property ="id" /> <result column ="username" property ="username" /> <result column ="password" property ="password" /> <collection property ="orderList" ofType ="order" > <id column ="oid" property ="id" /> <result column ="orderName" property ="orderName" /> <result column ="orderAmount" property ="orderAmount" /> </collection > </resultMap > <select id ="findAll" resultMap ="userMap" > select *,o.id oid from user u ,orders o where o.userId=u.id </select > </mapper >
测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void test () throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml" ); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = factory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList=mapper.findAll(); for (User user: userList) { System.out.println(user); } sqlSession.close(); }
至于多对多模型的查询,其基本原理跟一对多没有区别,只要注意合理使用中间表以及正确的映射关系即可