本文共 9586 字,大约阅读时间需要 31 分钟。
如:通过订单id查询订单的时候,将订单关联的用户信息也返回。
首先建库建表:
新建实体类:@Builder@ToString@NoArgsConstructor@AllArgsConstructor@Datapublic class OrderModel { private Integer id; private Integer userId; private Long createTime; private Long upTime; private UserModel userModel;}@Data@NoArgsConstructor@AllArgsConstructor@Builder@ToStringpublic class UserModel { private Long id; private String name; private Integer age; private Double salary; private Integer sex;}
mybatis全局配置:
pom.xml:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.example demomybatis 0.0.1-SNAPSHOT demomybatis Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.0 mysql mysql-connector-java runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test junit junit test junit junit org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok src/main/java **/*.xml false
@Mapperpublic interface OrderMapper { OrderModel getById(int id); OrderModel getById1(int id);}
OrderMapper.xml:
运行启动类:
@Slf4jpublic class Demo3Test { private SqlSessionFactory sqlSessionFactory; @Before public void before() throws IOException { //指定mybatis全局配置文件 String resource = "mybatis-config.xml";//读取全局配置文件 InputStream inputStream =Resources.getResourceAsStream(resource);//构建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); this.sqlSessionFactory = sqlSessionFactory; } @Test public void test() { try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderModel orderModel = mapper.getById1(1); log.info("{}", orderModel); } }}
结果:
方式2
这次我们需要使用mapper xml中另外一个元素association ,这个元素可以配置关联对象的映射关系添加接口:
OrderModel getById2(int id);
测试类修改:
OrderModel orderModel = mapper.getById2(1);
运行:
先按照订单id查询订单数据,然后在通过订单中user_id 去用户表查询用户数据,通过两次查询,组合成目标结果,mybatis已经内置了这种操作
我们先定义一个通过用户id查询用户信息的select元素,如下UserModel getById(int id);
OrderMapper.xml
运行:
方式3中给第二个查询传递了一个参数,如果需要给第二个查询传递多个参数怎么办呢?可以这么写
这种相当于给子查询传递了一个map,子查询中 需要用过map的key获取对应的条件,:
OrderMapper.xml:
OrderModel getById4(int id);
UserMapper.xml
UserModel getById1(int id);
结果:
传过来的是第一个查询的user_id和create_time关于resultmap resulttype:
resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致。
如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中根据订单id查询出订单信息,并且查询出订单明细列表。
一对多关系:collection标签这个sql中使用到了t_order和t_order_detail 连接查询,这个查询会返回多条结果,但是最后结果按照orderModelMap1 进行映射,最后只会返回一个OrderModel 对象,关键在于collection 元素,这个元素用来定义集合中元素的映射关系,有2个属性需要注意
property:对应的属性名称 ofType:集合中元素的类型,此处是OrderDetailModel 注意这个:查询出来的结果会按照这个配置中指定的column 进行分组,即按照订单id 进行分组,每个订单对应多个订单明细,订单明细会按照collection 的配置映射为ofType元素指定的对象。
实际resultMap元素中的id元素可以使用result 元素代替,只是用id 可以提升性能,mybatis可以通过id元素配置的列的值判断唯一一条记录,如果我们使用result 元素,那么判断是否是同一条记录的时候,需要通过所有列去判断了,所以通过id 可以提升性能,使用id元素在一对多中可以提升性能,在单表查询中使用id元素还是result元素,性能都是一样的。OrderModel getById1(Integer id);
@Builder@ToString@NoArgsConstructor@AllArgsConstructor@Datapublic class OrderDetailModel { private Integer id; private Integer goodsId; private Integer num; private Integer orderId; private Double totalPrice;}
@Test public void test() { try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); Integer id = 1; OrderModel orderModel = mapper.getById1(id); log.info("{}", orderModel); }
结果:
20:13:12.153 [main] DEBUG
com.example.demomybatis.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time, b.id orderDetailId, b.order_id, b.goods_id, b.num, b.total_price FROM t_order a, t_order_detail b WHERE a.id = b.order_id AND a.id = ? 20:13:12.181 [main] DEBUG com.example.demomybatis.mapper.OrderMapper.getById1 - > Parameters: 1(Integer) 20:13:12.205 [main] DEBUG com.example.demomybatis.mapper.OrderMapper.getById1 - < Total: 2 20:13:12.205 [main] INFO com.example.demomybatis.Demo3Test - OrderModel(id=1, userId=1, createTime=1624088102, upTime=1624088102, userModel=null, orderDetailModelList=[OrderDetailModel(id=1, goodsId=1, num=2, orderId=1, totalPrice=17.76), OrderDetailModel(id=2, goodsId=1, num=1, orderId=1, totalPrice=16.66)])
通过2次查询,然后对结果进行分装,先通过订单id查询订单信息,然后通过订单id查询订单明细列表,
然后封装结果。mybatis中默认支持这样,还是通过collection 元素来实现的。 OrderDetailMapper.xmlOrdermapper.xml
重点:
表示orderDetailModelList 属性的值通过select 属性指定的查询获取,查询参数是通过column 属性指定的,此处使用getById2 sql中的id 作为条件,即订单id
转载地址:http://sxten.baihongyu.com/