MyBatis框架核心之(五)注解使用resultMap及多表查询

五、resultMap与多表查询(注解)

 

传统的mapper.xml+接口使用接口映射相对较麻烦

所以我们可以使用注解来简化开发

 

支持的注解有以下:

MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。MyBatis提供的一些基本注解如下表所示。

注解

目标

相对应的 XML

描述

@CacheNamespace

为给定的命名空间 (比如类) 配置缓存。属性:implemetation,eviction, flushInterval,size,readWrite,blocking properties

@Property

N/A

Specifies the property value or placeholder(can replace by configuration properties that defined at themybatis-config.xml). Attributes: namevalue. (Available on MyBatis 3.4.2+)

@CacheNamespaceRef

参照另外一个命名空间的缓存来使用。属性:value, name If you use this annotation, you should be specified either value or name attribute. For the value attribute specify a java type indicating the namespace(the namespace name become a FQCN of specified java type), and for the name attribute(this attribute is available since 3.4.2) specify a name indicating the namespace.

@ConstructorArgs

方法

收集一组结果传递给一个劫夺对象的构造方法。属性:value,是形式参数的数组。

@Arg

N/A

·        

·        

, ConstructorArgs 集合的一部分。属性: id,column,javaType,typeHandler id 属性是布尔值, 来标识用于比较的属,XML 元素相似。

@TypeDiscriminator

方法

一组实例值被用来决定结果映射的表现。属性: column, javaType, jdbcType, typeHandler,casescases 属性就是实例的数组。

@Case

N/A

单独实例的值和它对应的映射。属性: value,type,resultsResults 属性是结果数组,因此这个注解和实际的 ResultMap 很相似,由下面的 Results 注解指定。

@Results

方法

结果映射的列表, 包含了一个特别结果列如何被映射到属性或字段的详情。:value, idvalue 属性是 Result 注解的数组。这个id的属性是结果映射的名称。

@Result

N/A

·        

·        

在列和属性或字段之间的单独结果映射。属:id,column, property, javaType ,jdbcType ,type Handler, one,manyid 属性是一个布尔值,示了应该被用于比较(和在 XML 映射中的相似)的属性。one 属性是单, , many , 相似。它们这样命名是为了避免名称冲突。

@One

N/A

复杂类型的单独属性值映射。属性: select,已映射语句(也就是映射器方)的完全限定名,它可以加载合适类型的实例。注意:联合映射在注解 API 中是不支持的。这是因为 Java 注解的限制,不允许循环引用。 fetchType会覆盖全局的配置参数lazyLoadingEnabled

@Many

N/A

映射到复杂类型的集合属性。属性:select,已映射语句(也就是映射器方法)的全限定名,它可以加载合适类型的实例的集合,fetchType会覆盖全局的配置参数lazyLoadingEnabled 注意联合映射在注解 API中是不支持的。这是因为 Java 注解的限制,不允许循环引用

@MapKey

方法

集合映射 : select,是映射语句(也就是映射器方)的完全限定名,它可以加载合适类型的一组实例。注意:联合映射在 Java 注解中是不支持的。这是因为 Java 解的限制,不允许循环引用。

@Options

方法

映射语句的属性

这个注解提供访问交换和配置选项的宽广范围, 它们通常在映射语句上作为属性出现。而不是将每条语句注解变复,Options 注解提供连贯清晰的方式来访问它们。属性:useCache=true , flushCache=FlushCachePolicy.DEFAULT , resultSetType=FORWARD_ONLY , statementType=PREPARED , fetchSize=-1 , , timeout=-1 useGeneratedKeys=false , keyProperty=”id” , keyColumn=”” , resultSets=””理解 Java 注解是很重要的,因为没有办法来指定“null” 作为值。因此,一旦你使用了 Options 注解,语句就受所有默认值的支配。要注意什么样的默认值来避免不期望的行为。

·         @Insert

·         @Update

·         @Delete

·         @Select

方法

·        

·        

·        

·        

这些注解中的每一个代表了执行的真 SQL它们每一个都使用字符串数组 (或单独的字符串)。如果传递的是字符串数组, 它们由每个分隔它们的单独空间串联起来。这就当用 Java 代码构 SQL 时避免了丢失空间的问题。然而,如果你喜欢,也欢迎你串联单独的字符串。属性:value,这是字符串数组用来组成单独的 SQL 语句。

·         @InsertProvider

·         @UpdateProvider

·         @DeleteProvider

·         @SelectProvider

方法

·        

·        

·        

·        

这些可选的 SQL 注解允许你指定一个类名和一个方法在执行时来返回运行允许创建动态 SQL基于执行的映射语句, MyBatis 会实例化这个类,然后执行由 provider 指定的方法. You can pass objects that passed to arguments of a mapper method, "Mapper interface type" and "Mapper method" via theProviderContext(available since MyBatis 3.4.5 or later) as method argument. (In MyBatis 3.4 or later, it's allow multiple parameters) 属性: type,methodtype 属性是类。method 属性是方法名。注意: 这节之后是对类的讨论,它可以帮助你以干净,容于阅读的方式来构建动态 SQL

@Param

Parameter

N/A

如果你的映射器的方法需要多个参数, 这个注解可以被应用于映射器的方法参数来给每个参数一个名字。否则,参数将会以它们的顺序位置来被命名 (不包括任何 RowBounds 参数) 比如。 #{param1} , #{param2} , 使 @Param(“person”),参数应该被命名为 #{person}

@SelectKey

方法

该注解复制了的功能,用在注解了@Insert@InsertProvider@Update or@UpdateProvider的方法上。在其他方法上将被忽略。如果你指定了一个@SelectKey注解,然后Mybatis将忽略任何生成的key属性通过设置@Options,或者配置属性。属性: statement是要执行的sql语句的字符串数组,keyProperty是需要更新为新值的参数对象属性, before可以是true或者false分别代表sql语句应该在执行insert之前或者之后, resultTypekeyPropertyJava类型, statementType是语句的类型,取StatementPreparedStatementCallableStatement对应的STATEMENTPREPARED或者CALLABLE其中一个,默认是PREPARED

@ResultMap

方法

N/A

这个注解给@Select或者@SelectProvider提供在XML映射中的id这使得注解的select可以复用那些定义在XML中的ResultMap如果同一select注解中还存在@Results或者@ConstructorArgs,那么这两个注解将被此注解覆盖。

@ResultType

Method

N/A

当使用结果处理器时启用此注解。这种情况下,返回类型为void,所以Mybatis必须有一种方式决定对象的类型,用于构造每行数据。如果有XML的结果映射,使用@ResultMap注解。如果结果类型在XML

@Flush

方法

N/A

如果这个注解使用了,它将调用定义在Mapper接口中的SqlSession#flushStatements()方法。(Mybatis 3.3或者以上)

本文简单介绍一下@Results、@Result、@One和@Many的用法,该注解主要是代替标签和其子标签

一、resultMap简介

MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了,而resultMap就是结果集映射的配置标签了。

 

1.SQL查询结果到领域模型实体                  

  在深入ResultMap标签前,我们需要了解从SQL查询结果集到JavaBeanPOJO实体的过程。

  1. 通过JDBC查询得到ResultSet对象

  2. 遍历ResultSet对象并将每行数据暂存到HashMap实例中,以结果集的字段名或字段别名为键,以字段值为值

  3. 根据ResultMap标签的type属性通过反射实例化领域模型

  4. 根据ResultMap标签的type属性和idresult等标签信息将HashMap中的键值对,填充到领域模型实例中并返回

 

2.使用场景

       在项目的实际开发中,有可能会遇到这样两种情况。

1.   实体类中的属性名与列名不相同,不能改但。导致不能自动装配值

2.   多表查询的返回值中可能需要其他对象,或者数组(一对一和一对多)

 

二、对应的注解

注解及代替的标签介绍

1.@Results注解

代替的是标签 

该注解中可以使用单个@Result注解,也可以使用@Result集合

@Results({@Result(),@Result()})或@Results(@Result())

注意:使用注解是若报出org.apache.ibatis.binding.BindingException:Invalid bound statement (not found):接口全类名.方法名

可能是使用@Results注解时忘记使用@Select注解

2.@Resutl注解

代替了 标签和标签

       @Result 中 属性介绍:

column 数据库的列名

Property需要装配的属性名

one  需要使用的@One注解(@Resultone=@One)()))

many  需要使用的@Many注解(@Resultmany=@many()))

 

     

3.@One注解(一对一)

代替了标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。

@One注解属性介绍:

select  指定用来多表查询的sqlmapper

fetchType会覆盖全局的配置参数lazyLoadingEnabled

使用格式:

@Result(column=" ",property="",one=@One(select=""))

 

4.@Many注解(多对一)

           代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。

注意:聚集元素用来处理一对多的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义;

使用格式:

@Result(property="",column="",many=@Many(select=""))

三、各注解使用

1.@Results与 @Result的使用

       @Result是最简单的映射,指定@Resul将基本数据库表字段,装配到实体类属性的映射。

column是数据库表的列名

property实体的字段

(在注解中返回,是根据方法的返回类型来定的。)

实体字段                    表的列名     

sid                            stuid

sname                      stuname

gid                            gid

grade                       grade  

对应的接口映射

@Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})

@Select("select * from student where gid=#{0}")

public List queryStudentByGid();

(如:该方法中表中数据的返回类型就是根据list中的Student来决定的)

id、result语句属性配置细节:

 

属性

描述

 

property

需要映射到JavaBean 的属性名称。

 

column

数据表的列名或者标签别名。

 

javaType

一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。

 

jdbcType

数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。

 

typeHandler

使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。

 

 

支持的JDBC类型
       为了将来的引用,MyBatis支持下列JDBC 类型,通过JdbcType 枚举:
BIT,FLOAT,CHAR,TIMESTAMP,OTHER,UNDEFINED,TINYINT,REAL,VARCHAR,BINARY,BLOB,NVARCHAR,SMALLINT,DOUBLE,LONGVARCHAR,VARBINARY,CLOB,NCHAR,INTEGER,NUMERIC,DATE,LONGVARBINARY,BOOLEAN,NCLOB,BIGINT,DECIMAL,TIME,NULL,CURSOR

 

2.@One(association联合)

联合元素用来处理“一对一”的关系

       两个属性:

1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
2. fetchType会覆盖全局的配置参数lazyLoadingEnabled

 

 

 

    注意:select=指定查询语句,如果查询语句在其他的namespace中,则需要写全namespace.方法id

 

例如:在获取某个学生的信息的同时又想获取所属班级的所有信息

学生实体中的字段

package cn.et.fuqiang.resultMap.entity;

 

public class Student {

     private Integer sid;//学生id

     private String sname; //学生姓名

     private Integer gid; //班级id

 

     private Grade grade; //所属班级的所有信息

}

 

班级实体的字段

package cn.et.fuqiang.resultMap.entity;

 

import java.util.List;

 

public class Grade {

    private Integer id;//班级id

    private String gname;//班级名称

       public Grade() {

       super();

       // TODO Auto-generated constructor stub

    }

   

}

 

 

在Student的字段中,Grade班级实体,需要查询班级表才能获取,学生表中没有该列(所以需要使用多表查询中,一对一关系,的 @Result中的one属性 和@One注解)

 

@Results({

@Result(column="stuid",property="sid"),

@Result(column="stuname",property="sname"),

@Result(column="gid",property="grade",one=@One(select="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent"))})

   @Select("select * from student")

   public List queryAllStudent();

解析:

因为表中的字段与实体中的不同,所以使用了这两个注解,将表的列与实体的属

@Result(column="stuid",property="sid"),

@Result(column="stuname",property="sname"),

因为实体中还有一个班级实体属性,但表中没有该字段,所以就要用多表查询

@Result(column="gid",property="grade",one=@One(select="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent"))

(这里的property是实体中的字段,而column=gid就相当于关联的条件了

而select就是该关联条件对应的查询方法)

 

namespace="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface下的方法

@Results(@Result(property="id",column="gid"))

@Select("select * from grade where gid=#{0}")

public Grade gradeInStudent();

 

因为注解中已经指定了多表查询所以当调用指定了该注解的方法时多表查询的值会自动装配到对应的要返回实体属性中

 

 

以上代码写为转换为普通的sql语句

select  s.*,g.*from student s inner join grade g ons.gid=g.gid

 

 

3. @Many注解( collection聚集)

    两个属性:

1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
2. fetchType会覆盖全局的配置参数lazyLoadingEnabled

 

例如,一个班级有多个学生。

 

学生实体中的字段

package cn.et.fuqiang.resultMap.entity;

 

public class Student {

     private Integer sid;//学生id

     private String sname; //学生姓名

     private Integer gid; //班级id

}

 

班级实体的字段

package cn.et.fuqiang.resultMap.entity;

 

import java.util.List;

 

public class Grade {

    private Integer id;//班级id

    private String gname;//班级名称

      private List students;//该班级下所有的学生

    public Grade() {

       super();

       // TODO Auto-generated constructor stub

    }

   

}

 

 

在Grade实体中有个List students属性,需要查询学生表才能获取,班级表中没有该信息(所以要使用多表查询一对多关系的, @Result中的many属性 和@Many注解)

 

@Results({

@Result(property="id",column="gid"),

@Result(property="students",column="gid",many=@Many(select="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface.queryStudentByGid"))})

    @Select("select * from grade")

    public List queryAllGrade();

解析:

因为表中的字段与实体中的不同,所以使用了这个注解,将表的列与实体的属性对应

@Result(property="id",column="gid")

因为实体中还有一个学生List实体属性,但表中没有该字段,所以就要用多表查询来填充其中的值

@Result(property="students",column="gid",many=@Many(select="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface.queryStudentByGid"))

 

namespace="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface"下的查询语句和类型

 

@Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})

@Select("select * from student where gid=#{0}")

public List queryStudentByGid();

(这里的property是实体中的字段,而column=gid就相当于关联的条件了

而select就是该关联条件对应的查询方法)

 

 

(这里的property是实体中的字段,而column=gid就相当于关联的条件了

而select就是该关联条件对应的查询方法)

 

 

 

所有代码实现

Jdbc连接四要素配置

url=jdbc:oracle:thin:@localhost:1521:orcl

user=mybatis

password=mybatis

driverClass=oracle.jdbc.OracleDriver

 

mybatis配置

xml version="1.0" encoding="UTF-8"?>

   

    resource="cn/et/fuqiang/resultMap/jdbc.properties">

   

   

   

        name="cn.et.fuqiang.resultMap.entity"/>

   

   

    default="development">

        id="development">

            type="JDBC" />

           

            type="POOLED">

                name="driver" value="${driverClass}" />

                name="url" value="${url}" />

                name="username" value="${user}" />

                name="password" value="${password}" />

           

       

   

   

   

   

       

        class="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface"/>

        class="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface"/>

   

 

 

 

两个接口映射代码

StudentAnnotationInterface.java

package cn.et.fuqiang.resultMap.annotation;

 

import java.util.List;

 

import org.apache.ibatis.annotations.One;

import org.apache.ibatis.annotations.Result;

import org.apache.ibatis.annotations.Results;

import org.apache.ibatis.annotations.Select;

 

import cn.et.fuqiang.resultMap.entity.Grade;

import cn.et.fuqiang.resultMap.entity.Student;

/**

 *使用注解应用resultMap

 *@author Administrator

 *

 */

public interface StudentAnnotationInterface {

   

   /**

    * 简单的使用resultMap 

    *     @Results注解相当于  mapper.xml文件中     resultMap标签

    *     其中可以包括多个@Result注解 

    *     如果只有一个的话可直接写

    *     多个的话必须用{@Result(),@Result()}  中间用","号隔开

    *     注意:@Select注解不能忘记  如果忘记会报出

    *    org.apache.ibatis.binding.BindingException: Invalid bound statement (notfound):接口全类名.方法名

    *    

    * @param id

    * @return

    */

   @Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})

   @Select("select * from student wherestuid=#{0}")

   public Student queryStudentById(Integer sid);

   

   /**

    * 使用resultMap实现多表查询

    * @Result注解中可以使用多表查询    

    *

    * 有两个  属性  many(一对多)  one(一对一)

    *

    * 一对一的使用

    *@Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname"),@Result(column="gid",property="grade",one=@One(select="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent"))})

       property=实体类中的属性名 

       column=是通过那个列关联 

       one=@one(select=namespace.方法名   指定查询的方法  ,如果在其他接口中必须指定   全类名.方法名)

 

 

              对应查询的的方法

       如果表名与字段名不符必须先声明如果相同可以不设置

       @Results(@Result(property="id",column="gid"))

       查询语句相当于关联查询  ,传入的值是指定的关联的列传入的  column 所以方法中不用传

       @Select("select * from grade where gid=#{0}")

       public Grade gradeInStudent();

       

    * @return 一对多返回指定的对象类型

    */

   @Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname"),@Result(column="gid",property="grade",one=@One(select="cn.et.fuqiang.resultMap.annotation.GradeAnnotationInterface.gradeInStudent"))})

   @Select("select * from student")

   public List<Student> queryAllStudent();

   

   @Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})

   @Select("select * from student wheregid=#{0}")

   public List<Student> queryStudentByGid();

}

 

GradeAnnotationInterface.java

package cn.et.fuqiang.resultMap.annotation;

 

import java.util.List;

 

import org.apache.ibatis.annotations.Many;

import org.apache.ibatis.annotations.Result;

import org.apache.ibatis.annotations.Results;

import org.apache.ibatis.annotations.Select;

import org.apache.ibatis.annotations.SelectProvider;

 

import cn.et.fuqiang.resultMap.entity.Grade;

import cn.et.fuqiang.resultMap.entity.Student;

 

public interface GradeAnnotationInterface {

   /**

    * 简单的使用resultMap 

    *     @Results注解相当于  mapper.xml文件中     resultMap标签

    *     其中可以包括多个@Result注解 

    *     如果只有一个的话可直接写

    *     多个的话必须用{@Result(),@Result()}  中间用","号隔开

    *     注意:@Select注解不能忘记  如果忘记会报出

    *    org.apache.ibatis.binding.BindingException: Invalid bound statement (notfound):接口全类名.方法名

    *    

    * @param id

    * @return

    */

   @Results(@Result(property="id",column="gid"))

   @Select("select * from grade wheregid=#{0}")

   public Grade queryGradeById(Integer id);

   

   

   @Results(@Result(property="id",column="gid"))

   @Select("select * from grade wheregid=#{0}")

   public Grade gradeInStudent();

   

   /**

    * 使用resultMap实现多表查询

    * @Result注解中可以使用多表查询    

    *

    * 有两个  属性  many(一对多)  one(一对一)

    *

    * 一对多的使用

    *@Result(property="students",column="gid",many=@Many(select="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface.queryStudentByGid"))

       property=实体类中的属性名 

       column=是通过那个列关联 

       many=@Many(select=namespace.方法名   指定查询的方法  ,如果在其他接口中必须指定   全类名.方法名)

 

              对应查询的的方法

       如果表名与字段名不符必须先声明如果相同可以不设置

       @Results({@Result(column="stuid",property="sid"),@Result(column="stuname",property="sname")})

       查询语句相当于关联查询  ,传入的值是指定的关联的列传入的  column 所以方法中不用传

       @Select("select * from student where gid=#{0}")

       public List queryStudentByGid();

    * @return 一对多返回的集合类型

    */

   @Results({@Result(property="id",column="gid"),@Result(property="students",column="gid",many=@Many(select="cn.et.fuqiang.resultMap.annotation.StudentAnnotationInterface.queryStudentByGid"))})

   @Select("select * from grade")

   public List<Grade> queryAllGrade();

}

 

两个实体类

Grade

package cn.et.fuqiang.resultMap.entity;

 

import java.util.List;

 

public class Grade {

   private Integer id;//班级

   private String gname;//班级名称

   private List<Student> students;//该班级下所有的学生

   public Grade() {

       super();

       // TODOAuto-generated constructor stub

   }

   public Grade(Integer id, String gname) {

       super();

       this.id = id;

       this.gname = gname;

   }

   

   public String getGname() {

       return gname;

   }

   public void setGname(String gname) {

       this.gname = gname;

   }

   public Integer getId() {

       return id;

   }

   public void setId(Integer id) {

       this.id = id;

   }

   public List<Student> getStudents() {

       return students;

   }

   public void setStudents(List<Student> students) {

       this.students = students;

   }

   

}

 

 

Student

package cn.et.fuqiang.resultMap.entity;

 

public class Student {

   private Integer sid;//学生id

   private String sname;//学生姓名

   private Integer gid;//班级id

   private Grade grade;//所属班级的所有信息

   public Student() {

       super();

       // TODOAuto-generated constructor stub

   }

   public Student(Integer sid, String sname, Integer gid, Grade grade) {

       super();

       this.sid = sid;

       this.sname = sname;

       this.gid = gid;

       this.grade = grade;

   }

   public Integer getSid() {

       return sid;

   }

   public void setSid(Integer sid) {

       this.sid = sid;

   }

   public String getSname() {

       return sname;

   }

   public void setSname(String sname) {

       this.sname = sname;

   }

   public Integer getGid() {

       return gid;

   }

   public void setGid(Integer gid) {

       this.gid = gid;

   }

   public Grade getGrade() {

       return grade;

   }

   public void setGrade(Grade grade) {

       this.grade = grade;

   }

}

 

 

Test实体类

package cn.et.fuqiang.resultMap.annotation;

 

import java.io.InputStream;

import java.util.List;

 

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.Test;

 

import cn.et.fuqiang.resultMap.entity.Grade;

import cn.et.fuqiang.resultMap.entity.Student;

 

public class ResultMapAnnotationTest {

   private static SqlSession session;

   private static GradeAnnotationInterface gradeInter=null;

   private static StudentAnnotationInterfacestudentInter=null;

   static{

       //mybatis的配置文件

       String resource = "mybatis.xml";

       //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)

       InputStream is =ResultMapAnnotationTest.class.getResourceAsStream(resource);

       //构建sqlSession的工厂

       SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);

       //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)

       //Readerreader = Resources.getResourceAsReader(resource);

       //构建sqlSession的工厂

       //SqlSessionFactorysessionFactory = new SqlSessionFactoryBuilder().build(reader);

       //创建能执行映射文件中sqlsqlSession

       session = sessionFactory.openSession();

       gradeInter=session.getMapper(GradeAnnotationInterface.class);

       studentInter=session.getMapper(StudentAnnotationInterface.class);

   }

   //@Test

   public void queryGradeTest(){

       Grade grade=gradeInter.queryGradeById(1);

       System.out.println(grade.getId()+"------"+grade.getGname());

   }

   

   //@Test

   public void queryStudentTest(){

       Student student=studentInter.queryStudentById(1);

       System.out.println(student.getSid()+"------"+student.getSname());

   }

   @Test

   public void queryGradeInStudent(){

       List<Student> students=studentInter.queryAllStudent();

       for (Student stu : students) {

            System.out.println(stu.getSid()+"------"+stu.getSname()+"-------"+stu.getGrade().getGname());

       }

       

   }

   //@Test

   public void queryStudentInGrade(){

       List<Grade> students=gradeInter.queryAllGrade();

       for (Grade grade : students) {

            System.out.println(grade.getGname()+""+grade.getStudents().size()+"");

       }

   }

}

 

你可能感兴趣的:(MyBatis)