当前位置:   article > 正文

Mybatis对象关系映射_mybatis映射对象

mybatis映射对象

1、什么是Mybatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

2、Mybaits的工作原理

Mybatis通过SqlSessionFactoryBuilder来读取mybatis-config.xml配置文件从而创建SqlSessionFactory工厂类,SqlSessionFactory通过openSession方法来获取sqlSession,然后sqlSession通过getMapper来获取接口中的所有执行sql语句的方法。

image-20211220164159345

3、Mybatis优缺点

优点:

  • 简单、易上手
  • sql语句都写在xml文件里,便于统一管理
  • 提供xml标签,支持编写动态sql

缺点:

  • 多张表进行查询的话,很考验程序员的sql能力
  • 对sql语句依赖程序很高,移植到其他数据库很麻烦
  • 拼接sql语句复杂,代码灵活性不高

Mybatis多对一、一对多处理

在数据库中可能会存在多对一的关系,比如说多个学生是一个班级、多个标签对一篇博客、多个学生对一个班主任等等。我们通常情况下创建的实体类中的属性是跟数据库里面的字段相对应,在一对多的环境下,实体类中的一个属性可以指向一个对象,然后通过Mybatis的ResultMap结果集映射,将相关联的表中的数据查找到后赋值给该属性,从而实现多对一的效果。

搭建环境

  • 首先创建一个学生类和一个班级类,学生类里面有id、姓名、班级信息属性,班级类里面有班级id、班级名称、年级属性。

( 这里偷个懒,用lombok插件,添加依赖,通过注解添加构造器的方法 )

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
    private int sid;
    private String name;
    private Class studentClass;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Class {
    private int cid;
    private String cname;
    private String grade;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 接着我们创建一个db.properties配置文件来配置数据库连接信息 ( 数据库换成自己对应的数据库,密码不同也需要修改 )
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&&characterEncoding=UTF-8&&useSSL=false&&serverTimezone=UTC
username=root
password=12345678
  • 1
  • 2
  • 3
  • 4
  • 创建Mybatis-config.xml配置文件,添加我们需要的配置 ( 这边没有添加log4j的依赖,所以注释掉了 )
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
    <!--
        properties:加载对应的配置文件
        settings:配置Mybatis的一些设置,如:log4j日志信息等
        typeAliases:扫描对应包下面的实体类,在xml文件中用小写表示就好
        environments:配置数据库环境,可以配置多个,最后生效的为default
        transactionManager:声明事物管理器
        mappers:扫描对应包下面的mapper.xml文件
    -->
    <properties resource="db.properties" />

<!--    <settings>-->
<!--        <setting name="logImpl" value="LOG4J"/>-->
<!--        <setting name="cacheEnabled" value="true"/>-->
<!--    </settings>-->

    <typeAliases>
        <package name="com.zhu.pojo" />
    </typeAliases>

    <!--环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="com.zhu.mapper" />
    </mappers>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 创建MybatisUtils工具类,用于返回所需的SqlSession对象
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resources = "mybatis-config.xml";
            InputStream in = Resources.getResourceAsStream(resources);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 创建StudentMapper和ClassMapper接口,因为Mybatis提供面向接口编程,所以我们可以通过方法将查询到的数据返回出来
public interface StudentMapper {

    //查找所有学生信息
    List<Student> getStudent();
}
  • 1
  • 2
  • 3
  • 4
  • 5
public interface ClassMapper {

    //查询所有班级信息
    List<Class> getStudentClass(@Param("cid") int cid);
}
  • 1
  • 2
  • 3
  • 4
  • 5

实现Mybatis多对一

  • 创建StudentMapper.xml文件,用来实现接口的方法

方法一: 按照查询嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<!--映射到对应的接口上-->
<mapper namespace="com.zhu.mapper.StudentMapper">

    <select id="getStudent" resultMap="getSClass">
        select * from student;
    </select>

    <select id="getStudentClass" resultType="class">
        select * from class where cid = #{cid}
    </select>
    
    <!--
    property指的是实体类里面的属性名
    column指的是要查询的字段
    javaType表示实体类中属性的类型
    select表示查询的方法
	association:表示实体类对象,常用于多对一
    这句话的意思就是根据学生的cid来查询对应的班级信息
	-->
    <resultMap id="getSClass" type="student">
        <association property="studentClass" column="cid" javaType="Class" select="getStudentClass" />
    </resultMap>
            
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

方法二: 按照结果嵌套处理

<mapper namespace="com.zhu.mapper.StudentMapper">

    <select id="getStudent" resultMap="getSClass">
        select a.*,b.* from student a,class b where a.cid=b.cid
    </select>

    <resultMap id="getSClass" type="student">
        <result property="sid" column="sid" />
        <result property="name" column="name" />
        <association property="studentClass" javaType="class">
            <result property="cid" column="cid" />
            <result property="cname" column="cname" />
            <result property="grade" column="grade" />
        </association>
    </resultMap>
            
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

测试代码:

public class TestMapper {
    public static void main(String[] args) {
        //通过工具类获取SqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.getStudent();
        for (Student student:students){
            System.out.println(student);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

测试结果:

image-20211220201910000

实现Mybatis一对多

将刚刚的实体类反过来一下,意思是一个班级对应多个学生、一个博客对应多个标签,一个班主任对应多个学生等等,将学生看作是一个集合,每个老师都有对应学生集合,也是通过Mybatis的ResultMap结果集映射,从而实现一对多的效果。

  • 更改之前的学生类和班级类,学生类有id、姓名、班级id属性,班级类有班级id,班级名称、年级、学生列表属性
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
    private int sid;
    private String name;
    private int cid;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Class {
    private int cid;
    private String cname;
    private String grade;
    private List<Student> students;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 更改之前的Mapper接口文件中的方法,并且创建一个ClassMapper.xml配置文件,用来实现ClassMapper接口中的方法
public interface StudentMapper {

    //查找所有学生信息
    List<Student> getStudent(@Param("cid") int cid);
}
  • 1
  • 2
  • 3
  • 4
  • 5
public interface ClassMapper {

    //查询所有班级信息
    List<Class> getStudentClass();
}
  • 1
  • 2
  • 3
  • 4
  • 5

方法一: 按照查询嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<mapper namespace="com.zhu.mapper.ClassMapper">

        <select id="getStudent" resultType="student">
            select * from student where cid = #{cid}
        </select>

        <select id="getStudentClass" resultMap="StudentClass">
            select * from class
        </select>

        <!--
            collection:表示集合类对象,常用于一对多
            ofType:表示返回的集合里面的泛型
            这段sql语句的意思是通过查询出来的cid来查找对应班级的学生信息
        -->
        <resultMap id="StudentClass" type="class">
            <collection property="students" javaType="ArrayList" ofType="student" column="cid" select="getStudent" />
        </resultMap>
            
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

方法二: 按照结果嵌套查询

<mapper namespace="com.zhu.mapper.ClassMapper">

    <select id="getStudentClass" resultMap="StudentClass">
        select a.*,b.* from student a,class b where a.cid=b.cid;
    </select>

    <resultMap id="StudentClass" type="class">
        <result property="cid" column="cid" />
        <result property="cname" column="cname" />
        <result property="grade" column="grade" />
        <collection property="students" ofType="student">
            <result property="sid" column="sid" />
            <result property="name" column="name" />
            <result property="cid" column="cid" />
        </collection>
    </resultMap>
            
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

将测试类里面的getMapper里面的参数变成ClassMapper.class,然后修改返回值,运行代码

测试结果:

image-20211220204604859

多对多的处理其实也跟上面类似,可以看作是两个一对多,分别再两个实体类里面创建对应的集合或者实体类用于指向对方,然后分别再自己的Mapper.xml配置文件中实现两个一对多的处理即可,快结合上面的应用去实现一下吧!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/625618
推荐阅读
相关标签
  

闽ICP备14008679号