Mybatis框架映射---代码实现(XML配置以及注解形式)

目录

一. 映射关系 1 对 1-映射方式

1.通过xml文件实现映射的一对一关系

总结 :

2.通过注解的方式来实现下面的 1 对 1 的映射关系,实现级联查询

总结:

二. 映射关系多对一

1.通过xml文件实现映射的多对一关系

2.通过注解的方式来实现下面的 多对一 的映射关系,实现级联查询


XML与注解的形式本质都是以XML的形式进行的,只不过注解对XML进行可一个封装。 

映射关系就是你在查询一个表的时候,其中的某个属性对应另外一个表的一条记录,或者多条记录。比如你在查询教师表中的某个教师的信息,同时根据这个教师的工号,你可以查到这个教师所教的班级,以及班级的学生等信息。


一. 映射关系 1 1-映射方式

  映射方式
1. 通过配置 XxxMapper.xml 实现 1 1 [ 配置方式 ]
2. 通过注解的方式实现 1 1 [ 注解方式 ]

1.通过xml文件实现映射的一对一关系

通过配置 XxxMapper.xml 的方式来实现下面的 1 1 的映射关系,实现
联查询 , 通过 person 可以获取到对应的 idencard 信息 

1. 创建 person 表和 idencard 表

CREATE TABLE person
(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32) NOT NULL DEFAULT '',
card_id INT ,
FOREIGN KEY (card_id) REFERENCES idencard(id)
)CHARSET utf8;

2. 创建 mybatis_idencard 表
CREATE TABLE idencard
(
id INT PRIMARY KEY AUTO_INCREMENT,
card_sn VARCHAR(32) NOT NULL DEFAULT ''
)CHARSET utf8 ;
INSERT INTO idencard VALUES(1,'5002262001121212');
INSERT INTO person VALUES(1,'长离',1);
SELECT * FROM person;
SELECT * FROM idencard

 3.创建IdenCard类

package com.sn.entity;

/**
 * @author sn
 */
public class IdenCard {
    private Integer id;
    private String card_sn;
    public IdenCard() {
    }
    public IdenCard(Integer id, String card_sn) {
        this.id = id;
        this.card_sn = card_sn;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCard_sn() {
        return card_sn;
    }

    public void setCard_sn(String card_sn) {
        this.card_sn = card_sn;
    }

    @Override
    public String toString() {
        return "IdenCard{" +
                "id=" + id +
                ", card_sn='" + card_sn + '\'' +
                '}';
    }
}

4.创建Person类

package com.sn.entity;

/**
 * @author sn
 */
public class Person {
    private Integer id;
    private String name;
    private IdenCard card;
    public Person() {
    }
    public Person(Integer id, String name, IdenCard card) {
        this.id = id;
        this.name = name;
        this.card = card;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public IdenCard getCard() {
        return card;
    }

    public void setCard(IdenCard card) {
        this.card = card;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", card=" + card +
                '}';
    }
}

5.创建IdenCardMapper接口

package com.sn.mapper;

import com.sn.entity.IdenCard;

/**
 * @author sn
 */
public interface IdenCardMapper {
    //根据 id 获取到身份证
    public IdenCard getIdenCardById(Integer id);
}

6.创建IdenCardMapper.xml映射文件

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sn.mapper.IdenCardMapper">
    <!-- 实现 getIdenCardById -->
    <select id="getIdenCardById" resultType="IdenCard" parameterType="Integer">
        SELECT * FROM idencard
        WHERE id=#{id}
    </select>
</mapper>

7.创建PersonMapper接口

package com.sn.mapper;

import com.sn.entity.Person;

/**
 * @author sn
 */
public interface PersonMapper {
    //通过 Person 的 id 获取到 Person,包括这个 Person 关联的 IdenCard 对象
    public Person getPersonById(Integer id);
}

8.创建PersonMapper.xml文件

1.写xml用association的第一种方式

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sn.mapper.PersonMapper">
    <!-- 实现 getPersonById [方式 1] -->
    <!-- 定义一个 resultMap 来映射返回的结果 -->
    <resultMap type="Person" id="personResultMap">
        <!-- id: 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能, 通常指定主
        键
        property="id" 表示 person 对象的哪个属性代表主键
        column="id" 表示对应的表的字段 -->
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!-- association: 一个复杂类型的关联 -->
<!--     javaType:返回的java的类型
-->
        <association property="card" javaType="com.sn.entity.IdenCard">
            <!-- 将关联的 card 对象哪些属性放入到这个 resultMap -->
            <result property="id" column="id"/>
            <result property="card_sn" column="card_sn"/>
        </association>
    </resultMap>
    <select id="getPersonById" parameterType="Integer" resultMap="personResultMap">
        select * from person , idencard WHERE person.id=#{id}
                                          AND person.card_id = idencard.id;
    </select>
</mapper>

2.用xml中association的第二种方式 

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sn.mapper.PersonMapper">
    <!-- 实现 getPersonById [方式 2] -->
    <!-- 定义一个 resultMap 来映射返回的结果 -->

    <resultMap type="Person" id="personResultMap2">
        <!-- id: 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能, 通常指定主
        键
        property="id" 表示 person 对象的哪个属性代表主键
        column="id" 表示对应的表的字段 -->
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!-- association: 一个复杂类型的关联 -->
        <association property="card" column="card_id"
                     select="com.sn.mapper.IdenCardMapper.getIdenCardById"/>

    </resultMap>
    <select id="getPersonById2" parameterType="Integer" resultMap="personResultMap2">
select * from person where id = #{id}
    </select>
</mapper>

测试结果:

查询的结果:: 

总结 :

上面上述案例就是:多表查询,就是当我们查询一个表的一条记录的时候,其中的某个属性是另外一个表的主键(也就是可以标识一条记录的属性)。也就是外键约束!

当我们实现一对一的映射的时候,想要使返回的结果如上图所示,就必须用resultMap进行结果的映射。

 当我们在XML文件进行方法的实现的时候,mybatis框架会根据方法中的结果映射,返回出你所想要的结果。这里的一对一的映射,就是平常大学老师教的方法,同时这里涉及到了级联查询(也就是所说的多表查询)


2.通过注解的方式来实现下面的 1 1 的映射关系,实现级联查询

 1.创建IdenCardMapperAnnotaion

package com.sn.mapper;

import com.sn.entity.IdenCard;
import org.apache.ibatis.annotations.Select;

/**
 * @author sn
 */
public interface IdenCardMapperAnnotaion {
    //根据 id 获取到身份证
//这个方法不需要返回任何级联对象
    @Select("SELECT * FROM idencard WHERE id=#{id}")
    public IdenCard getIdenCardById(Integer id);
}

2.创建 PersonMapperAnnotatio

package com.sn.mapper;

import com.sn.entity.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

/**
 * @author sn
 */
public interface PersonMapperAnnotation {
    //通过 Person 的 id 获取到 Person,包括这个 Person 关联的 IdenCard 对象
//想:你到底返回什么结果,然后你想办法给他
/*
* private Integer id;
private String name;
private IdenCard card;
*/
    @Select("select * from person WHERE id=#{id}")
    @Results({
            @Result(id = true, property = "id", column = "id"), 
            @Result(property = "name", column = "name"), 
            @Result(property = "card", column = "card_id", 
            one = @One(select =
            "com.sn.mapper.IdenCardMapperAnnotaion.getIdenCardById"))
    })
    public Person getPersonById(Integer id);
}

查询的结果:: 

 

运行的结果也和之前是一样的,用动态代理的方式 

总结:

1. 表是否设置外键 , MyBatis 进行对象 / 级联映射没有影响
也就是无论是否有外键约束,在mybatis中依然可以查到相关联的身份证号所带来的消息。

 

2.  去掉 person 表的外键 , 进行测试 , 依然可以获取相应的级联对象
通过注解的方法和XML的方法其实本质是一致的,更推荐使用XML的形式来进行解耦!
另外还有一点column中的属性值是你查询过后的表的字段名,如果你的SQL语句给表的字段取别名了那么这个column是别名的名字

二. 映射关系多对一

1. 项目中多对 1 的关系是一个基本的映射关系 , 多对 1, 也可以理解成是 1 对多 .
User --- Pet : 一个用户可以养多只宠物
Dep ---Emp : 一个部门可以有多个员工
目的就是:
通过 User 可以查询到对应的 Pet, 反过
来,通过 Pet 也可以级联查询到对应的 User 信息 .实现双向的多对一的映射。

1.通过xml文件实现映射的多对一关系

1. 创建 mybatis_user 和 mybatis_pet 表

CREATE TABLE mybatis_user
(id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32) NOT NULL DEFAULT '' )CHARSET=utf8 ;

CREATE TABLE mybatis_pet
(id INT PRIMARY KEY AUTO_INCREMENT,
nickname VARCHAR(32) NOT NULL DEFAULT '',
user_id INT ,
FOREIGN KEY (user_id) REFERENCES mybatis_user(id)
)CHARSET=utf8 ;

INSERT INTO mybatis_user
VALUES(NULL,'宋江'),(NULL,'张飞');


INSERT INTO mybatis_pet
VALUES(1,'黑背',1),(2,'小哈',1);


INSERT INTO mybatis_pet
VALUES(3,'波斯猫',2),(4,'贵妃猫',2);

SELECT * FROM mybatis_user;
SELECT * FROM mybatis_pet;

 2.创建User类

package com.sn.entity;

import java.util.List;

/**
 * @author sn
 */
public class User {
    private Integer id;
    private String name;
    //一个用户可以对应多个宠物
    private List<Pet> pets;
    public User() {
    }
    public User(Integer id, String name, List<Pet> pets) {
        this.id = id;
        this.name = name;
        this.pets = pets;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Pet> getPets() {
        return pets;
    }
    public void setPets(List<Pet> pets) {
        this.pets = pets;
    }
}

3创建Pet类

package com.sn.entity;

/**
 * @author sn
 */
public class Pet {
    private Integer id;
    private String nickname;
    //一个宠物只能对应一个主人 User
    private User user;
    public Pet() {
    }
    public Pet(Integer id, String nickname, User user) {
        this.id = id;
        this.nickname = nickname;
        this.user = user;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "Pet{" +
                "id=" + id +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

 

3. 创建 PetMapper.java 和 UserMapper.java
public interface PetMapper {
// 通过 User id 来获取 pet 对象,可能有多个,因此使用 List 接收
public List < Pet > getPetByUserId ( Integer userId);
// 通过 pet id 获取 Pet 对象
public Pet getPetById ( Integer id);
}
public interface UserMapper {
// 通过 id 获取 User 对象
public User getUserById ( Integer id);
}

 

4. 创建 UserMapper.xml 

 <!DOCTYPE mapper
                PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sn.mapper.UserMapper">
<resultMap type="com.sn.entity.Pet" id="PetResultMap">
    <id property="id" column="id"/>
    <result property="nickname" column="nickname"/>
    <association property="user" column="user_id" select="com.sn.mapper.PetMapper.getUserById"></association>
</resultMap>
<!-- :
1. user_id=#{userId} userId 就是调用 getPetByUserId 传入的用户 id
2. userId 名称,由程序员来确定,比如你写成 id,uId 等都可以-->
<select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap">
    select * from mybatis_pet where user_id=#{userId}
</select>
<select id="getPetById" parameterType="Integer" resultMap="PetResultMap">
    select * from mybatis_pet where id=#{id}
</select>
</mapper>

 

5. 创建 PetMapper.xm
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sn.mapper.PetMapper">
    <!-- collection : 一对多关联查询, 表示一个用户可能对应多个 pet 对象
    ofType: 集合中元素对象的类型 -->
    <resultMap type="com.sn.entity.User" id="UserResultMap">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!-- column="id" 就是当前 User 表的主键字段名,通过这个 user 的 id,
        去查询对应的 pet 有哪些 -->
        <collection property="pets" ofType="com.sn.entity.Pet" column="id"
                    select="com.sn.mapper.UserMapper.getPetByUserId"></collection>
    </resultMap>
    <select id="getUserById" parameterType="Integer" resultMap="UserResultMap">
        select * from mybatis_user where id=#{id};
    </select>
</mapper>

  那么问题来了?有人会问那如果这个方法的参数有多个怎么办呢?

: 在数据库库中表和表的联系可以通过外键约束进行,也就是一个表的非主属性,对应的是另外一个表的主键,而表的主键只有一个(主键就是可以唯一标识一条记录的属性字段)。所以为啥只有一个参数了。

2.通过注解的方式来实现下面的 多对一 的映射关系,实现级联查询

1.UserMapperAnnotation 接口

package com.sn.mapper;

import com.sn.entity.User;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

/**
 * @author sn
 */
public interface UserMapperAnnotation {
    //通过 user 的 id 号,返回该用户的方法
    @Select("select * from mybatis_user where id=#{id}")
    @Results({
            @Result(id=true,property="id",column="id"),
            @Result(property="name",column="name"),
            @Result(property="pets",column="id",
            many=@Many(select="com.sn.mapper.PetMapperAnnotation.getPetByUserId"))
    })
    public User getUserById(Integer id);
}

 

 2.PetMapperAnnotation接口

package com.sn.mapper;

import com.sn.entity.Pet;
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 java.util.List;

/**
 * @author sn
 */
public interface PetMapperAnnotation {
    //通过 User 的 id 来获取 pet 对象,可能有多个,因此使用 List 接收
    @Select("select * from mybatis_pet where user_id=#{userId}")
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "nickname", column = "nickname")
    })
    public List<Pet> getPetByUserId(Integer userId);
//通过 pet 的 id 获取 Pet 对象
    @Select("select id AS tnId,nickname AS tnNickname, user_id AS tnUser_id from mybatis_pet where id=#{id}")
            @Results({
                    @Result(id = true, property = "id", column = "tnId"),
                    @Result(property = "nickname", column = "tnNickname"),
                    @Result(property = "user", column = "tnUser_id",
                            one = @One(select =
                    "com.sn.mapper.UserMapperAnnotation.getUserById"))
            })
            public Pet getPetById(Integer id);
}

XML与注解的形式本质都是以XML的形式进行的,只不过注解对XML进行可一个封装。

映射关系就是你在查询一个表的时候,其中的某个属性对应另外一个表的一条记录,或者多条记录。比如你在查询教师表中的某个教师的信息,同时根据这个教师的工号,你可以查到这个教师所教的班级,以及班级的学生等信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值