欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

信天翁高级版(一对一绘制关系图)

最编程 2024-05-02 22:44:43
...

文章目录

    • 1.基本介绍
        • 1.基本说明
        • 2.映射方式
    • 2.配置xml方式(多表联查)
        • 1.数据库表设计
        • 2.新建子模块
          • 1.创建子模块
          • 2.创建基本结构
        • 3.MyBatisUtils.java和jdbc.properties和mybatis-config.xml与原来的一致
        • 4.IdenCard.java
        • 5.Person.java
        • 6.IdenCardMapper.java
        • 7.IdenCardMapper.xml(名字需要与前面的接口名相同!!!)
        • 8.IdenCardMapperTest.java测试
        • 9.PersonMapper.java
        • 10.PersonMapper.xml(一对一关系体现)
        • 11.测试PersonMapperTest.java
        • 12.查询优化
        • 13.对一对一关系的理解
          • 1.对IdenCard和Person属性的分析
            • 1.IdenCard
            • 2.Person
          • 2.查询出来的结果
    • 3.配置xml方式(多表联查分解为单表操作)
        • 1.PersonMapper.java添加方法
        • 2.PersonMapper.xml添加查询
        • 3.测试
    • 4.注解方式
        • 1.基本介绍
        • 2.代码实现
        • 1.IdenCardMapperAnnotation.java
        • 2.PersonMapperAnnotation.java
        • 3.PersonMapperAnnotationTest.java测试
    • 5.注意事项和细节
        • 1.表是否设置外键,对MyBatis级联映射没有影响
        • 2.关于ResultMap
    • 6.课后练习
        • 1.IdenCard.java添加属性Person用来关联person表
        • 2.IdenCardMapper.java添加方法
        • 3.IdenCardMapper.xml添加实现类
        • 4.PersonMapper.java根据card_id查询
        • 5.PersonMapper.xml添加实现类
        • 6.测试IdenCardMapperTest.java
    • 7.一对一映射总结(idencard和person)
        • 1.设计表
          • idencard表字段
          • person表字段
          • 分析映射关系(person -> idencard)
        • 2.设计bean(person -> idencard)
          • Idencard
          • Person
        • 3.设计查询
          • 根据person的id查询时级联查询idencard,返回一个Person对象
        • 4.映射(idencard -> person)
          • 1.设计bean
          • 2.设计查询
            • 根据idencard的id查询时级联查询person,返回一个Idencard对象

1.基本介绍

1.基本说明

image-20240305184650313

2.映射方式

image-20240305184825137

2.配置xml方式(多表联查)

image-20240305185156581

1.数据库表设计
-- 记录身份证的表
CREATE TABLE idencard(
id INT PRIMARY KEY auto_increment,
card_sn VARCHAR(32) NOT NULL DEFAULT ''
);
INSERT INTO idencard VALUES(1, '111111000');

-- 记录个人信息的表
CREATE TABLE person(
id INT PRIMARY KEY auto_increment,
name VARCHAR(32) NOT NULL,
card_id INT,
FOREIGN KEY (card_id) REFERENCES idencard(id)
);
INSERT INTO person VALUES(1, '牛魔王', 1);

2.新建子模块
1.创建子模块

image-20240305191310416

2.创建基本结构

image-20240305195323326

3.MyBatisUtils.java和jdbc.properties和mybatis-config.xml与原来的一致
4.IdenCard.java
package com.sun.entity;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class IdenCard {
    private Integer id;
    private String card_sn;

    public IdenCard() {
    }

    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 + '\'' +
                '}';
    }
}

5.Person.java
package com.sun.entity;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class Person {
    private Integer id;
    private String name;
    private IdenCard card; //这个名称随意,因为后面是要通过映射

    public Person() {
    }

    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 +
                '}';
    }
}

6.IdenCardMapper.java
package com.sun.mapper;

import com.sun.entity.IdenCard;

/**
 * @author 孙显圣
 * @version 1.0
 */
public interface IdenCardMapper {
    public IdenCard getIdenCardById(Integer id);
}

7.IdenCardMapper.xml(名字需要与前面的接口名相同!!!)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.IdenCardMapper">
    <!--public IdenCard getIdenCardById(Integer id);-->
    <select id="getIdenCardById" resultType="IdenCard" parameterType="Integer">
        SELECT *
        FROM idencard
        WHERE id = #{id}
    </select>
</mapper>
8.IdenCardMapperTest.java测试
import com.sun.entity.IdenCard;
import com.sun.mapper.IdenCardMapper;

import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class IdenCardMapperTest {
    //两个属性
    private SqlSession sqlSession; //相当于连接
    private IdenCardMapper idenCardMapper;

    //编写方法完成初始化
    @Before //标注了Before之后表示了在执行目标测试方法前会执行该方法
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //获取到MonsterMapper对象
        idenCardMapper = sqlSession.getMapper(IdenCardMapper.class);
        System.out.println(idenCardMapper.getClass());
    }
    @Test
    public void getIdenCardById() {
        IdenCard idenCardById = idenCardMapper.getIdenCardById(1);
        System.out.println(idenCardById);

        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

image-20240305195715472

9.PersonMapper.java
package com.sun.mapper;

import com.sun.entity.Person;

/**
 * @author 孙显圣
 * @version 1.0
 */
public interface PersonMapper {
    public Person getPersonById(Integer id);
}

10.PersonMapper.xml(一对一关系体现)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.PersonMapper">
    <!--返回结果集
        将查询到的结果封装到Person对象里,在Person对象的属性有
            private Integer id; person表的id
            private String name; person表的name
            private IdenCard card; person表的card_id
            一个card_id就可以找到一个IdenCard对象,也就是一个idencard表的一条记录,
            所以就使用了这个IdenCard对象来替换原来的card_id,如果将结果封装到这个Person对象中
            则应该显示的表字段为:id(person表的id) name(person表的name) id(idencard表的id) card_sn(idencard表的card_sn)
            这样就舍弃掉了原来person表的card_id字段,可以认为这两个表中person表是主表
    -->
    <resultMap id="getPersonByIdResult" type="Person">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="card" javaType="IdenCard">
            <result property="id" column="id"/>
            <result property="card_sn" column="card_sn"/>
        </association>
    </resultMap>
    <!--public Person getPersonById(Integer id);-->
    <select id="getPersonById" parameterType="Integer" resultMap="getPersonByIdResult">
        SELECT *
        FROM person,
             idencard
        WHERE person.card_id = idencard.id
          AND person.id = #{id}
    </select>

</mapper>

11.测试PersonMapperTest.java
import com.sun.entity.Person;
import com.sun.mapper.IdenCardMapper;
import com.sun.mapper.PersonMapper;
import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class PersonMapperTest {
    //两个属性
    private SqlSession sqlSession; //相当于连接
    private PersonMapper personMapper;

    //编写方法完成初始化
    @Before //标注了Before之后表示了在执行目标测试方法前会执行该方法
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //获取到MonsterMapper对象
        personMapper = sqlSession.getMapper(PersonMapper.class);
        System.out.println(personMapper.getClass());
    }
    @Test
    public void getPersonById() {
        Person personById = personMapper.getPersonById(1);
        System.out.println(personById);
    }
}

image-20240305210043758

12.查询优化

image-20240305211114063

13.对一对一关系的理解
1.对IdenCard和Person属性的分析
1.IdenCard
  • id属性对应表的id字段
  • card_sn属性对应表的card_sn字段

image-20240305210408972

2.Person
  • id属性对应表的id字段
  • name属性对应表的name字段
  • **card属性:**原本的person表应该是一个card_id字段,但是这个card_id字段是可以映射到idencard表的一条记录即在java中的IdenCard对象,所以使用这个对象来替代了原来的card_id字段

image-20240305210318752

2.查询出来的结果

image-20240305210837571

  • 可以看出这个上面的结果只有四个字段,也就是删除了person表中原有的card_id字段!

image-20240305210212573

3.配置xml方式(多表联查分解为单表操作)

1.PersonMapper.java添加方法
    public Person getPersonById2(Integer id);
2.PersonMapper.xml添加查询
    <!--2.获取到了查询到的值Columns: id, name, card_id(外键)-->
    <resultMap id="getPersonByIdResult2" type="Person">
        <!--3.将查询到的id值调用Person对象的setId方法赋值-->
        <id property="id" column="id"/>
        <!--4.将查询到的name值调用Person对象的setName方法赋值-->
        <result property="name" column="name"/>
        <!--5.将查询到的card_id值作为参数,传给select语句调用的方法-->
        <!--6.select语句将返回的Card对象封装到card属性中-->
        <association property="card" column="card_id" select="com.sun.mapper.IdenCardMapper.getIdenCardById"/>
    </resultMap>
    <!--1.可以理解为这里将查询到的值给了id为getPersonByIdResult2的resultMap-->
    <select id="getPersonById2" parameterType="Integer" resultMap="getPersonByIdResult2">
        select * from person where id = #{id}
    </select>
3.测试

image-20240305220418082

4.注解方式

1.基本介绍

image-20240306085032938

2.代码实现
1.IdenCardMapperAnnotation.java
package com.sun.mapper;

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

/**
 * @author 孙显圣
 * @version 1.0
 */
public interface IdenCardMapperAnnotation {
    @Select("select * from `idencard` where `id` = #{id}")
    public IdenCard getIdenCardById(Integer id);
}


2.PersonMapperAnnotation.java
package com.sun.mapper;

import com.sun.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 孙显圣
 * @version 1.0
 */
public interface PersonMapperAnnotation {
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "name", column = "name"),
            //将查询到的card_id作为入参传给getIdenCardById方法,最后返回一个Card对象,然后调用setter方法封装到card
            @Result(property = "card", column = "card_id", one = @One(select = "com.sun.mapper.IdenCardMapperAnnotation.getIdenCardById"))
    }
    )
    //根据id查询Person表
    @Select("select * from `person` where id = #{id}")
    public Person getPersonById(Integer id);
}

3.PersonMapperAnnotationTest.java测试
import com.sun.entity.Person;
import com.sun.mapper.PersonMapper;
import com.sun.mapper.PersonMapperAnnotation;
import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class PersonMapperAnnotationTest {
    //两个属性
    private SqlSession sqlSession; //相当于连接
    private PersonMapperAnnotation personMapperAnnotation;

    //编写方法完成初始化
    @Before //标注了Before之后表示了在执行目标测试方法前会执行该方法
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //获取到MonsterMapper对象
        personMapperAnnotation = sqlSession.getMapper(PersonMapperAnnotation.class);
        System.out.println(personMapperAnnotation.getClass());
    }
    @Test
    public void PersonMapperAnnotation() {
        Person personById = personMapperAnnotation.getPersonById(1);
        System.out.println(personById);
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

}

image-20240306092007450

5.注意事项和细节

1.表是否设置外键,对MyBatis级联映射没有影响
2.关于ResultMap
  • MyBatis默认机制是调用查询到的列名的setter方法给返回的类型对象的属性赋值,但是如果列名与属性名不对应就只能使用ResultMap来进行映射
  • ResultMap中的column属性实际上指的是查询到的结果的列名,如果有别名则这个列就应该对应这个别名
  • 如果有select属性,则指的是将这个column的值传给select属性对应的方法并得到返回值,然后调用property属性的setter方法为其赋值

image-20240306092330326

6.课后练习

image-20240306111556037

1.IdenCard.java添