数据模型分析
1、 明确每张表存储的信息
2、 明确每张表中关键字段(主键、外键、非空)
3、 明确数据库中表与表之间的外键关系
4、 明确业务中表与表的关系(建立在具体的业务)
所含的表为:
用户表
订单表
订单明细表
商品表
并且在程序中进行映射时必须要有对应的JavaBean
根据上面分析的数据模型我们来讨论高级映射:所谓高级映射也就是表(JavaBean)之间关联映射 :
分为:一对一、一对多、多对多
需求:通过订单id查询用户信息(主表为订单表,从表为用户表)
因为我们使用的是resultType我们只能返回一个映射类型我们通过继承Order来创建一个OrderExt扩展类并在里面添加用户信息。注意关注JavaBean的代码
sql:SELECT orders.`id`,orders.`user_id`,orders.`number`,user.`username`, user.`sex` FROM orders,user WHERE orders.`user_id` = user.`id`
重点在于Javabean与映射文件
①编写全局配置文件SqlMapCongfig.xml文件配置与上一篇文章的配置方式一致
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 7 <properties resource="db.properties"></properties> 8 9 <!-- 自定义别名 --> 10 <typeAliases> 11 <!--批量自定义别名 --><!--<推荐>批量自定义别名 name:批量指定po类别名的包名 使用:别名即类名,且不区分大小写--> 12 <package name="com.itheima.mybatis.po.order" /> 13 <package name="com.itheima.mybatis.po.user" /> 14 </typeAliases> 15 16 17 <!-- 配置环境信息 --> 18 <environments default="development"> 19 <!-- 环境配置必须要配置事务和数据源 --> 20 <environment id="development"> 21 <!-- 配置JDBC事务控制,由mybatis控制 --> 22 <transactionManager type="JDBC"></transactionManager> 23 <!--配置数据源 这里采用的是mybatis连接池 --> 24 <dataSource type="POOLED"> 25 <property name="driver" value="${db.driver}"/> 26 <property name="url" value="${db.url}"/> 27 <property name="username" value="${db.username}"/> 28 <property name="password" value="${db.password}"/> 29 </dataSource> 30 </environment> 31 </environments> 32 <mappers> 33 <!-- 批量加载映射文件 34 指定一个路径下的所有映射文件: 35 限定要求:1.接口或类需要与映射文件名称相同 2.接口或类需要和映射文件放在同一个目录下--> 36 <package name="com.itheima.mybatis.mapper"/> 37 </mappers> 38 </configuration>
②编写Mapper接口
1 public interface OrdersMapper { 2 //OrdersExt为订单类的子类也叫做扩展类 3 public List<OrdersExt> findOrdersAndUser(); 4 public List<OrdersExt> findOrdersAndUserRstMap(); 5 public List<OrdersExt> findOrdersAndDetailRstMap(); 6 public List<User> findOrderAndItemsRstMap(); 7 }
③OrderExt扩展类编写
1 public class OrdersExt extends Orders { 2 //添加User类属性username sex 3 private String username; 4 5 private String sex; 6 7 //这里省略了getset方法 8 @Override 9 public String toString() { 10 return "OrdersExt [username=" + username + ", sex=" + sex + ", user=" + user + ", detailList=" + detailList 11 + "]"; 12 } 13 14 15 }
④Ordermapper映射文件编写
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.itheima.mybatis.mapper.OrdersMapper"> 6 <!--这里所有类都使用了别名,别名统一配置在SqlMapConfig.xml中进行配置 --> 7 <!-- 订单和用户之间一对一映射,用resultType实现 订单对于用户是一对一 --> 8 <mapper> 9 <select id="findOrdersAndUser" resultType="OrdersExt"> 10 SELECT 11 orders.`id`, 12 orders.`user_id`, 13 orders.`number`, 14 user.`username`, 15 user.`sex` 16 FROM USER,orders 17 WHERE orders.`user_id`=user.`id` 18 </select> 19 </mapper>
⑤测试代码
1 public class OrderMapperTest { 2 private SqlSessionFactory sqlSessionFactory; 3 @Before 4 public void setUp() throws Exception { 5 String resource = "SqlMapConfig.xml"; 6 InputStream inputStream =Resources.getResourceAsStream(resource); 7 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 8 } 9 10 @Test 11 public void testFindOrdersAndUser() { 12 SqlSession sqlSession =sqlSessionFactory.openSession(); 13 OrdersMapper ordersMapper =sqlSession.getMapper(OrdersMapper.class); 14 List<OrdersExt> list=ordersMapper.findOrdersAndUser(); 15 //System.out.println(list.get(0).getId()); 16 System.out.println(list); 17 sqlSession.close(); 18 } 19 }
测试结果为
resultMap是使用的更为详细的映射方式,可以进行关联查询。简单来说 例如你想查询员工信息,而员工信息里面对应着一个部门的id信息,也就是在员工表中存在一个外键来关联部门。这个时候我们希望在查询员工的时候把部门信息也查询出来这个时候我们要用到resultMap
一个订单对应一个用户所以订单对用户是一对一
修改订单PO类关联用户类
1 public class OrdersExt extends Orders {//这里是继承里订单类 2 //添加User类属性username sex 3 private String username; 4 5 private String sex; 6 7 //添加用户User类完成一对一 8 private User user; 9 //省略了getset方法 10 11 }
对应mapper接口:OrderMapper
1 public interface OrdersMapper { 2 3 public List<OrdersExt> findOrdersAndUser(); 4 public List<OrdersExt> findOrdersAndUserRstMap(); 5 public List<OrdersExt> findOrdersAndDetailRstMap(); 6 public List<User> findOrderAndItemsRstMap(); 7 }
OrderMapper.xml的一对一查询之resultMap的使用
注意一对一关联:使用<association ></association> 标签代表一对一的嵌套关联写在resultMap标签内
<!--订单和用户之间一对一映射,用resultMap实现 订单对于用户是一对一 id:定义resultMap的唯一标识 type:映射的pojo类--> <!-- 配置resultMap id标签用于设置表中唯一主键 result标签映射结果集的普通列 column:查询表的列名 property:和映射对象属性名一致--> <resultMap type="OrdersExt" id="OrdersAndUserRstMap"> <!-- 订单信息 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <!-- 用户信息(一对一)--> <!-- association 用来映射一对一关系 property关联信息查询的属性结果将要映射的扩展类中的对象属性名称--> <!-- 在关联映射中最好加上id标签,不写不会报错但是会影响性能 user_id为外键所以也是user表的主键所以这样引用 --> <association property="user" javaType="com.itheima.mybatis.po.user.User"> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> </association> </resultMap> <select id="findOrdersAndUserRstMap" resultMap="OrdersAndUserRstMap"> <!-- sql语句不变 --> SELECT orders.`id`, orders.`user_id`, orders.`number`, user.`username`, user.`sex` FROM USER,orders WHERE orders.`user_id`=user.`id` </select>
根据上面的图片分析
一个订单对应多个订单明细 所以订单对订单明细为一对多
PO类的关联改写 OrederExt
1 public class OrdersExt extends Orders { 2 //添加User类属性username sex 3 private String username; 4 5 private String sex; 6 //添加用户User类完成一对一 7 private User user; 8 //添加订单明细一对多 9 private List<Orderdetail> detailList; 10 //此处省略getset方法 11 }
mapper接口编写同上省略(OrderMpper)
mapper映射文件:
<collection property="detailList" ofType="com.itheima.mybatis.po.order.Orderdetail"></collection >用来表示一对多
注意这里我们使用了一个继承属性extends可以重用上一个resultMap中的信息extends=“上一个resultMap的id名称”
1 <resultMap type="OrdersExt" id="OrdersAndDetailRstMap" extends="OrdersAndUserRstMap"> 2 <!-- 订单信息 上面已经配置过订单信息用户信息 我们可以继承--> 3 <!-- 用户信息 --> 4 5 <!-- 订单明细 property:对象的属性名 ofType映射的对象类型 --> 6 <collection property="detailList" ofType="com.itheima.mybatis.po.order.Orderdetail"> 7 <id column="detailId" property="id"/> 8 <result column="items_id" property="itemsId"/> 9 <result column="items_num" property="itemsNum"/> 10 </collection> 11 </resultMap> 12 <!--订单对订单明细的一对多关联查询 orderAndDetailRstMap --> 13 <select id="findOrdersAndDetailRstMap" resultMap="OrdersAndDetailRstMap"> 14 SELECT 15 orders.`id`, 16 orders.`user_id`, 17 orders.`number`, 18 user.`username`, 19 user.`sex`, 20 orderdetail.`id` detailId, 21 orderdetail.`items_id`, 22 orderdetail.`items_num` 23 FROM USER,orders,orderdetail 24 WHERE orders.`user_id`=user.`id` 25 AND orderdetail.`orders_id`=orders.`id`; 26 </select>
订单和商品是属于多对多关系,但是关联查询中表示多对多关联需要间接去表示 这里order为主表Order为主类
订单对明细是一对多,明细对商品是一对一这样我们可以间接嵌套表示出商品的信息
order-->orderdetail
1 public class Orders { 2 private Integer id; 3 4 private Integer userId; 5 6 private String number; 7 8 private Date createtime; 9 10 private String note; 11 12 private List<Orderdetail> detailList; 13 //省略getset方法和toString方法 14 15 }
orderdetial-->Item
1 public class Orderdetail { 2 private Integer id; 3 4 private Integer ordersId; 5 6 private Integer itemsId; 7 8 private Integer itemsNum; 9 10 11 //商品信息 订单明细对应商品信息是一对一 12 private Items items; 13 //省略getset方法和toString方法 14 15 }
mapper接口为OrderMapper接口同上
mapper映射文件OrderMapper.xml
1 <!-- 这里的需求发生变化 需求: 查询用户所买的商品 2 分析:用户和商品之间没有直接关联,但是有着多对多关系,通过订单到明细最后再到具体商品 3 主信息为用户User所以这里映射的是User类 当映射种类发生变化后就不能继承上面的其他resultMap隐射 --> 4 <resultMap type="com.itheima.mybatis.po.user.User" id="OrderAndItemsRstMap"> 5 <!-- 用户信息--> 6 <id column="user_id" property="id" /> 7 <result column="username" property="username"/> 8 <result column="sex" property="sex"/> 9 <!-- 订单信息 (用户对订单是一对多) 10 collection标签描述一对多 property表示User对象中关联的多方的属性名也就是ordersList ofType表示所要映射的对象类型 --> 11 <collection property="ordersList" ofType="com.itheima.mybatis.po.order.Orders"> 12 <id column="id" property="id"/> 13 <id column="user_id" property="userId"/> 14 <id column="number" property="number"/> 15 <!-- 订单明细(订单对订单明细也是一对多) --> 16 <collection property="detailList" ofType="com.itheima.mybatis.po.order.Orderdetail"> 17 <id column="detailId" property="id"/> 18 <id column="items_id" property="itemsId"/> 19 <id column="items_num" property="itemsNum"/> 20 <!-- 商品信息 (订单明细对商品信息是一对一) 21 association用来描述一对一添加该标签后记得在po类中进行相应的修改javaType用来映射指定的java类型--> 22 <association property="items" javaType="com.itheima.mybatis.po.item.Items" > 23 <id column="items_id" property="id"/> 24 <id column="name" property="name"/> 25 <id column="price" property="price"/> 26 </association> 27 </collection> 28 </collection> 29 30 31 32 </resultMap> 33 <!-- 订单对商品信息 的多对多关联查询OrderAndItemsRstMap--> 34 <select id="findOrderAndItemsRstMap" resultMap="OrderAndItemsRstMap"> 35 SELECT 36 orders.`id`, 37 orders.`user_id`, 38 orders.`number`, 39 user.`username`, 40 user.`sex`, 41 orderdetail.`id` detailId, 42 orderdetail.`items_id`, 43 orderdetail.`items_num`, 44 items.`name`, 45 items.`price` 46 FROM USER,orders,orderdetail,items 47 WHERE orders.`user_id`=user.`id` 48 AND orderdetail.`orders_id`=orders.`id` 49 AND orderdetail.`items_id`=items.`id` 50 </select> 51
测试代码
延迟加载在关联查询的时候可以体现出来
原文:https://www.cnblogs.com/zwxbky/p/12329458.html