MyBatis:多对一表关系详解
1,如果涉及到多表查询,必须用resultMap方式。如果用resultType方式,那么获取的信息只能放到一个类里面,而像Customer和Order这种关系,我们希望查出Customer的同时查出多个他里面的orderList集合,也就是要查询不止一种对象,就必须使用resultMap映射的方式,才能将关联到的那个类的信息拿到。
2,如果把配置文件中的查询语句改为 select id,user_name fromcustomer,同时把数据库中的customer表的name字段改为user_name字段,Customer实体类中的name属性名不变,再执行查询,会发现name查不出来。因为查询结果是根据实体类的属性和返回结果集的列字段名对应的,如果不一致,则无法使用set方法注入值。
这种问题也可以通过resultMap的方式解决,用resultMap映射一下就可以了。
例如:定义查询sql语句是:
<sql id="allColumn"> id,user_name,password </sql> <select id="findUserById" parameterType="int" resultType="cn.domain.User"> select <include refid="allColumn"/> from user where id=#{id} </select>
也就是select id,user_name,password fromuser where id=#{id}
而实体类User中的属性名是username,将数据库中的列名也修改成user_name,返回结果username为null。
修改:通过resultMap方式
<sql id="allColumn"> id,user_name,password </sql> <resultMap type="cn.domain.User" id="findUserById"> <id property="id" column="id" /> <!-- 映射成user_name,就可以将user_name列的字段值设置到username中了 --> <result property="username" column="user_name"/> <result property="password" column="password" /> </resultMap> <!-- 配置成resultMap的返回类型,进行映射处理 --> <select id="findUserById" parameterType="int" resultMap="findUserById"> select <include refid="allColumn"/> from user where id=#{id} </select>
3,建立多对一关系---案例一
(1)表和实体类都是用刚才创建的,只需要修改一下我们的mapper配置文件和测试用例即可。
(2)编写OrderMapper.xml文件,查询所有Order。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.test1.domain"> <!-- 配置多对一映射关系 --> <resultMap type="cn.test1.domain.Order" id="orderTest"> <id property="id" column="o_id" /> <result property="name" column="o_name" /> <!-- 建立多对一,通过association建立 --> <association property="customer" javaType="cn.test1.domain.Customer"> <id property="id" column="id" /> <result property="name" column="name" /> </association> </resultMap> <select id="getOrderinfo" parameterType="int" resultMap="orderTest"> select c.*,o.id as o_id,o.name as o_name from customer c,`order` o where c.id = o.customer_id </select> </mapper>
(3)编写测试用例,TestOrder.java。
public class TestOrder { private SqlSessionFactory sessionFactory; @Before public void init() throws IOException { //初始化方法 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testSelect() { //获取session SqlSession session = sessionFactory.openSession(); //查询order. Order order = session.selectOne("cn.test1.domain.getOrderinfo"); System.out.println(order); session.close(); } }
(4)结果:报错:
太多的结果异常,原本期望获取一个,但是获取了多个。
原因:
查询所有的时候,因为数据库有两条记录,所以查询结果不止一条,但是我们使用的查询方式是通过selectOne方法查找,这个方法期望返回一个结果,如果返回了多个,就报异常。返回一个还是多个不是根据数据库查询记录数来定的,而是根据产生的对象数量来定的。
解决:
将使用的方法改成selectList方法,就可以了:
@Test public void testSelect() { //获取session SqlSession session = sessionFactory.openSession(); //查询order. List<Order> orderList = session.selectList("cn.test1.domain.getOrderinfo"); System.out.println(orderList); session.close(); }
返回结果:
[Order[id=1, name=Iphone, customer=Customer [id=1, name=小强]orderList:[]],
Order [id=2, name=Imac, customer=Customer[id=1, name=小强]orderList:[]]]
3,建立多对一关系---案例二
如果使用selectOne的方法,可以查询唯一结果,比如根据id查询。例如:
OrderMapper.xml配置文件:
<mapper namespace="cn.itcast.test1.domain"> <!-- 配置多对一映射关系 --> <resultMap type="cn.test1.domain.Order" id="orderTest"> <id property="id" column="o_id" /> <result property="name" column="o_name" /> <!-- 建立多对一,通过association建立 --> <association property="customer" javaType="cn.test1.domain.Customer"> <id property="id" column="id" /> <result property="name" column="name" /> </association> </resultMap> <select id="getOrderinfo" parameterType="int" resultMap="orderTest"> select c.*,o.id as o_id,o.name as o_name from customer c,`order` o where c.id = o.customer_id and o.id=#{id} //添加根据id查询条件 </select> </mapper>
测试用例:
@Test public void testSelect() { //获取session SqlSession session = sessionFactory.openSession(); //查询order. Order order = session.selectOne("cn.itcast.test1.domain.getOrderinfo",1); System.out.println(order); session.close(); }
这时就可以得到根据id查询出的唯一结果。
返回结果字段的匹配方式跟一对多是一样的。
本文来自博客园,作者:King-DA,转载请注明原文链接:https://www.cnblogs.com/qingmuchuanqi48/p/13800057.html