现在有以下场景:一个身份证对应一个人。具体场景和下面文章场景一致:

先编写pojo实体类:
            
            
              java
              
              
            
          
          public class IdCard {
    private Integer id;
    private String code;
    //....
}
        
            
            
              java
              
              
            
          
          public class Person {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private IdCard card;
    //.....
}
        然后编写dao层的Mapper接口文件
            
            
              java
              
              
            
          
          public interface IdCardMapper {
    @Select("select * from t_idcard where id = #{param01}")
    IdCard selectIdCardById(@Param("param01") Integer id);//因为是接口,所以不能实现具体函数。
}
        
            
            
              java
              
              
            
          
          public interface PersonMapper {
    @Select("select * from t_person where id = #{param01}")
    @Results({
            @Result(column = "card_id",property = "card",one = @One(select = "com.cupk.dao.IdCardMapper.selectIdCardById"))
    })
    //这里的column = "card_id"表示从上面的@Select语句中查询出来的结果中提取card_id,作为参数传入到这个@One里面的参数。而这个property = "card"表示下面的语句查询出的结果对应
    Person selectPersonById(@Param("param01") Integer id);
}
        接着测试
            
            
              java
              
              
            
          
              //基于注解的,一对一查关联查询
    @Test
    public void selectPersonByTest(){
        SqlSession session = MybatisUtils.getSession();
        PersonMapper mapper = session.getMapper(PersonMapper.class);
        Person person = mapper.selectPersonById(2);
        System.out.println(person);
        session.close();
    }
        @Select注解
@Select 注解
@Select 是 MyBatis 提供的一个注解,用于直接在 Mapper 接口方法上 编写 SQL 查询语句。通过 @Select 注解,你可以避免编写 XML 形式的 SQL 映射文件,使代码更加简洁。@Select 注解通常与 @Results 注解结合使用,以定义查询结果的映射关系。
基本用法
            
            
              java
              
              
            
          
          @Select("SELECT * FROM t_person WHERE id = #{id}")
Person selectPersonById(@Param("id") Integer id);
        在这个示例中,@Select 注解直接定义了一条 SQL 查询语句。#{id} 是一个参数占位符,用于接收方法参数 id。@Param 注解用于指定参数的名称,这样在 SQL 语句中就可以通过 #{id} 来引用这个参数。
传递参数:#{param01}
在 MyBatis 中,#{param01} 是一种参数占位符,用于在 SQL 语句中引用传递的参数。param01 是默认的参数名称,当在 Mapper 方法中没有使用 @Param 注解时,MyBatis 会自动为参数分配名称 param1, param2, param3 等等。如果使用了 @Param 注解,那么就可以通过 @Param 注解指定的名称来引用参数。
示例
            
            
              java
              
              
            
          
          @Select("SELECT * FROM t_person WHERE id = #{param1} AND name = #{param2}")
Person selectPersonByIdAndName(@Param("param1") Integer id, @Param("param2") String name);
        在这个示例中,#{param1} 和 #{param2} 分别引用了方法参数 id 和 name。@Param 注解用于指定参数的名称,这样在 SQL 语句中就可以通过 #{param1} 和 #{param2} 来引用这些参数。
使用 #{param01} 传递参数
如果没有使用 @Param 注解,MyBatis 会自动为参数分配名称 param1, param2 等等。例如:
            
            
              java
              
              
            
          
          @Select("SELECT * FROM t_person WHERE id = #{param1} AND name = #{param2}")
Person selectPersonByIdAndName(Integer id, String name);
        在这个示例中,MyBatis 会自动将第一个参数 id 命名为 param1,将第二个参数 name 命名为 param2。因此,在 SQL 语句中可以使用 #{param1} 和 #{param2} 来引用这些参数。
多个参数传递
当方法有多个参数时,MyBatis 会按照参数的顺序自动分配名称 param1, param2 等等。如果想明确指定参数的名称,可以使用 @Param 注解。
示例
            
            
              java
              
              
            
          
          @Select("SELECT * FROM t_person WHERE id = #{id} AND age = #{age}")
Person selectPersonByIdAndAge(@Param("id") Integer id, @Param("age") Integer age);
        在这个示例中,@Param 注解用于指定参数的名称,这样在 SQL 语句中就可以通过 #{id} 和 #{age} 来引用这些参数。
复杂参数传递
有时可能需要传递一个对象作为参数,例如一个 Person 对象。在这种情况下,可以直接在 SQL 语句中引用对象的属性。
示例
            
            
              java
              
              
            
          
          @Select("SELECT * FROM t_person WHERE id = #{person.id} AND name = #{person.name}")
Person selectPersonByPerson(@Param("person") Person person);
        在这个示例中,#{person.id} 和 #{person.name} 引用了 Person 对象的 id 和 name 属性。
关联查询
一对一
假设我们有两个表:Person 和 Address。一个 Person 关联一个 Address,即每个 Person 对应一个 Address。
表结构
- 
Person表id(主键)nameaddress_id(外键,指向 Address 表)
 - 
Address表id(主键)streetcity
 
实体类
            
            
              java
              
              
            
          
          public class Person {
    private Integer id;
    private String name;
    private Address address;
    // getter 和 setter 方法
}
public class Address {
    private Integer id;
    private String street;
    private String city;
    // getter 和 setter 方法
}
        Mapper 接口
            
            
              java
              
              
            
          
          import org.apache.ibatis.annotations.*;
public interface PersonMapper {
    
    @Select("SELECT * FROM person WHERE id = #{id}")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "address", column = "address_id",
                one = @One(select = "selectAddressById"))
    })
    Person selectPersonById(Integer id);
    @Select("SELECT * FROM address WHERE id = #{id}")
    Address selectAddressById(Integer id);
}
        解释
- 
@Select注解 用于定义 SQL 查询。selectPersonById方法通过SELECT * FROM person WHERE id = #{id}查询Person表。 - 
@Results注解用于将查询结果映射到实体类字段。@Result注解包含三个主要属性:property:实体类中的属性名。column:数据库表中的列名。one:定义一对一的关联查询。
 - 
@One注解 用于定义一对一映射,指定用于获取关联对象的查询方法。在这里,我们调用了selectAddressById方法来获取Address对象。 
解释@One
在 MyBatis 中,@Result 注解的 column 属性并不是直接赋值给 address_id,而是用来指定一个查询结果列名,然后将该列的值用作参数传递给 selectAddressById 方法。
具体流程
- 
主查询 :
selectPersonById方法被调用时,它执行SELECT * FROM person WHERE id = #{id}查询,假设返回以下结果(根据id查询得到):id name address_id 1 张三 101  - 
映射配置:
@Result(property = "id", column = "id"):将查询结果中的id列值(1)存入Person对象的id属性。@Result(property = "name", column = "name"):将查询结果中的name列值(张三)存入Person对象的name属性。@Result(property = "address", column = "address_id", one = @One(select = "selectAddressById")):column = "address_id":从查询结果中获得这一列的值(101)。one = @One(select = "selectAddressById"):column = "address_id"确定了要获取的列值是 101。- 将这个值(101)作为参数传递给 
selectAddressById方法。 
 - 
关联查询 :调用
selectAddressById(101)方法,这会执行SELECT * FROM address WHERE id = #{id}查询。- 
假设返回结果为:
id street city 101 中山路 100 号 北京  
 - 
 - 
子查询结果的映射:
- 获得的 
Address对象如下:id: 101street: 中山路 100 号city: 北京
 
 - 获得的 
 - 
对象填充 :将整个
Address对象映射到Person对象的address属性中。 
另一种方法
            
            
              java
              
              
            
          
          import org.apache.ibatis.annotations.*;
public interface PersonMapper {
    
    @Select("SELECT p.id AS person_id, p.name, a.id AS address_id, a.street, a.city " +
            "FROM person p " +
            "JOIN address a ON p.address_id = a.id " +
            "WHERE p.id = #{id}")
    @Results({
        @Result(property = "id", column = "person_id"),
        @Result(property = "name", column = "name"),
        @Result(property = "address.id", column = "address_id"),
        @Result(property = "address.street", column = "street"),
        @Result(property = "address.city", column = "city")
    })
    Person selectPersonByIdWithoutOne(Integer id);
}
        一对多
假设我们有两个表:Author 和 Book。
- 
Author表id(主键)name
 - 
Book表id(主键)titleauthor_id(外键,指向 Author 表)
 
实体类
            
            
              java
              
              
            
          
          import java.util.List;
public class Author {
    private Integer id;
    private String name;
    private List<Book> books; // 一个作者有多本书
    // getter 和 setter 方法
}
public class Book {
    private Integer id;
    private String title;
    private Integer authorId;
    // getter 和 setter 方法
}
        Mapper 接口
            
            
              java
              
              
            
          
          import org.apache.ibatis.annotations.*;
import java.util.List;
public interface AuthorMapper {
    @Select("SELECT * FROM author WHERE id = #{id}")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "books", column = "id", 
                many = @Many(select = "selectBooksByAuthorId"))
    })
    Author selectAuthorById(Integer id);
    @Select("SELECT * FROM book WHERE author_id = #{authorId}")
    List<Book> selectBooksByAuthorId(Integer authorId);
}
        解释
- 
@Select注解:用于定义 SQL 查询。这种方式直接在 Mapper 接口的方法上定义 SQL 查询。 - 
@Results和@Result注解:用于定义查询结果的映射。property:实体类中的属性名。column:数据库表中的列名,作为关联查询的外键。
 - 
@Many注解 :用于定义一对多关系,指定当列对应的值为参数时调用的方法。在这里,它用于获取Author的所有Book 
具体流程
- 
主查询 :调用
selectAuthorById方法时,执行SELECT * FROM author WHERE id = #{id},假设返回以下结果:id name 1 王小波  - 
映射配置:
@Result(property = "id", column = "id"):将查询结果中的id列值(1)存入Author对象的id属性。@Result(property = "name", column = "name"):将查询结果中的name列值(王小波)存入Author对象的name属性。@Result(property = "books", column = "id", many = @Many(select = "selectBooksByAuthorId")):column = "id":从查询结果中获得这一列的值(1)。many = @Many(select = "selectBooksByAuthorId"):- 将这个值(1)作为参数传递给 
selectBooksByAuthorId方法。 
- 将这个值(1)作为参数传递给 
 
 - 
关联查询 :执行
selectBooksByAuthorId(1),这会执行 SQL 查询SELECT * FROM book WHERE author_id = #{authorId}。- 
假设返回结果为:
id title author_id 101 黄金时代 1 102 白银时代 1  
 - 
 - 
子查询结果的映射:
- 获得的 
Book对象列表 如下:Book 1:{id: 101, title: "黄金时代", authorId: 1}Book 2:{id: 102, title: "白银时代", authorId: 1}
 
 - 获得的 
 - 
对象填充 :将整个
Book对象列表映射到Author对象的books属性中。