发布网友 发布时间:2024-10-24 15:00
共1个回答
热心网友 时间:2024-10-26 10:43
在使用Mybatis框架时,业务层会根据实际业务需求给Dao层传入参数,Dao层在根据传入的参数做了相关增删改查操作后会返回给业务层数据(从表中查询出的数据等)。不管是接收参数还是返回结果集,Mybatis框架为了迎合多变的业务场景都给出了多种应对方案,下面将重点阐述这些方案。
方式一通过实体对象接收参数:在前几节的内容中,大部分的示例采用的都是这种方式,下面进行一个示例回顾。Dao层接口UserMapper增加selectByPojo方法。可以发现Dao层的selectByPojo的参数类型是User类型,也就是通过实体对象接收参数。映射文件UserMapper.xml中增加select标签用parameterType接收该实体对象并在SQL语句中采用#{对象属性值}的方式即#{id}、#{username}、#{password}读取user对象中的属性值。这种方式是比较常见的参数接收方式,其可以将SQL语句所需的多个参数通过一个对象全部接收。
方式二通过多个参数接收:如果我是分别通过多个参数传入Dao层,Mybatis该如何获取参数呢?此时需要借助注解@Param,将Dao层接口UserMapper中selectByPararms每个参数都配有该注解就能正常执行。@Param()这个注解其实起到了类似于取别名的作用,这样mybatis就能根据这个注解将参数实现一一对应,不会出现多个参数但是值对应不上的情况。
方式三通过Map接收:Dao层接口UserMapper增加selectByMap方法。映射文件UserMapper.xml中增加select标签,直接采用#{id}、#{username}、#{password}方式取出map中对应的值参与sql。这种方式通过Map来传递参数,灵活度高,适用于参数不确定的情况。
方式四#与$的区别:在上述示例中我们都采用#{属性名称}的方式获取变量值,除此之外也可以将#替换成$。使用$取值时其仅仅是采用字符串拼接的形式,这也是和#不同之处,#采用占位符的形式。$取值还有个特殊的用处,如果sql语句中表名是变化的,只能用$取值。另外还要强调一点的是,$取值可以用来处理字段名等无法使用占位符的情况,使用${}形式。
Mybatis如何返回结果集?
方式一利用resultType结果集返回List集合:Dao层接口UserMapper增加findAll方法。映射文件UserMapper.xml中增加select标签使用结果集元素resultType时,将其值设为User类的全限定类名即可,那么查询出的所有数据都会被封装到该集合中。
方式二利用resultType结果集返回Map集合:Dao层接口UserMapper增加selectUsersByMap方法。映射文件UserMapper.xml中增加select标签使用结果集元素resultType时,将其值设为User类的全限定类名,测试结果如下:返回的结果集Map集合中key是每个User对象的id值,value是User对象。当然key的值可以通过Dao层接口UserMapper对应方法的 @MapKey("")注解进行自定义,选取对象中的某个字段作为key就将这个字段的属性名放入注解即可。
方式三利用resultMap完成基本属性值封装:上述介绍了使用resultType将数据库中的结果自动封装到Java实体对象中,但是有些时候这种自动封装不能满足很多现实场景的需要。比如数据库字段和Java实体类中的字段对应不上,因此值也就封装不起来,比如数据库的字段是user_name,而Java实体类中的属性名是username。这个时候就需要借助resultMap,具体代码示例如下。Dao层接口UserMapper增加selectUserByResultMap方法。映射文件UserMapper.xml中增加resultMap标签,id(一般设置主键字段)及result对应的是数据库查询出的字段名,而property对应的是java实体对象中的属性名称。在上述完成了一一对应后,将对应规则赋给select标签的resultMap即可。
方式四resultMap完成一对一封装:所谓高级映射就是在java实体类中包含另一个实体类,在这种情况下myabtis是如何借助resultMap完成结果集封装的呢?为了介绍此种情况,需要增加新的实体类Department。并且将该实体类也作为User类的属性元素即private Department department。在select标签里依然用resultMap指定封装结果集的方式。由于返回结果集是User类型的,而在User类型中有个引用数据类型Department,可以采用department.id、department.departmentName这种级联的方式将数据库中对应的字段值赋给Department的属性。除了上述级联的方式外,还可以采用子标签association来完成这一封装。
方式五一对多查询:所谓一对多查询就是在一个实体对象中包含集合属性,假设在部门实体类中加入属性private List userList,即模拟一个部门中可以有很多员工。这样可以满足需求在查询部门时将其所有员工悉数封装到属性userList中,那么具体在封装过程中,mybatis框架是如何实现的呢?答案还是使用resultMap。Dao层接口DepartmentMapper增加方法getDeptByIdPlus。在select标签中采用表连接的方式分别查出user表(用户表)和tbl_dept(部门表)的相关信息,业务需求则是通过部门id查出此部门的全部员工。在resultMap中部门实体类中的id属性和departmentName属性可以实现简单的封装即可。但是属性userList是集合类型,因此需要借助collection子标签,其中property对应的就是该属性名,而ofType对应的是集合中实体对象的全限定类名,这里对应的是User类。在collection标签中完成User对象的属性值封装即可。