一.接口代理方式实现Dao

1.1 代理开发方式介绍

​ 采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。

Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的全限定名相同

img

  1. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

img

  1. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

img

  1. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

img

总结:

接口开发的方式: 程序员只需定义接口,就可以对数据库进行操作,那么具体的对象怎么创建?

1.程序员负责定义接口

2.在操作数据库,mybatis框架根据接口,通过动态代理的方式生成代理对象,负责数据库的crud操作

3.接口代理不需要实现类

1.2.编写StudentMapper接口

img

接口代理方式-代码实现

1.删除mapper层接口的实现类。

img

2.修改映射配置文件。

<?xml version="1.0" encoding="UTF-8" ?><!--映射配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace 命名空间-->
<mapper namespace="com.itss.mapper.StudentMapper">
    <select id="selectAll" resultType="student">
        SELECT *
        FROM Student
    </select>
    <!--通过id查询信息-->
    <select id="selectById" resultType="student" parameterType="int">
        SELECT *
        FROM Student
        WHERE sid = #{sid}
    </select>
    <!--新增信息-->
    <insert id="insert" parameterType="student">
        INSERT INTO Student
        VALUES (#{sid}, #{name}, #{age}, #{birthday})
    </insert>
    <!--修改信息-->
    <update id="update" parameterType="student">
        UPDATE Student
        SET name=#{name},
            age=#{age},
            birthday=#{birthday}WHERE sid=#{sid}
    </update>
    <!--删除信息-->
    <delete id="delete" parameterType="int">
        DELETE
        FROM Student
        WHERE sid = #{sid}
    </delete>
</mapper>

3.修改service层接口的实现类,采用接口代理方式实现功能。

package com.itss.service.impl;

import com.itss.bean.Student;
import com.itss.mapper.StudentMapper;
import com.itss.service.StudentService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/*//1.加载核心配置文件
//2.获取Sq1Session工厂对象
//3.通过工厂对象获取Sq1Session对象
//4.获取StudentMapper接口的实现类对象
//5.通过实现类对象调用方法,接收结果
//6.释放资源
//7.返回结果*/
//业务层实现接口
public class StudentServiceImpl implements StudentService {
    //    查询全部
    @Override
    public List<Student> selectAll() {
        InputStream is = null;
        SqlSession sqlSession = null;
        List<Student> list = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取Sq1Session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取Sq1Session对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//动态方式获取接口实现类对象
            //5.通过实现类对象调用方法,接收结果
            list = mapper.selectAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return list;
    }

    //    根据id查询
    @Override
    public Student selectById(Integer sid) {

        InputStream is = null;
        SqlSession sqlSession = null;
        Student student = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取Sq1Session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取Sq1Session对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//动态方式获取接口实现类对象
            //5.通过实现类对象调用方法,接收结果
            student = mapper.selectById(sid);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //7.返回结果
        return student;
    }

    //    新增数据
    @Override
    public Integer insert(Student stu) {
        InputStream is = null;
        SqlSession sqlSession = null;
        Integer result = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取Sq1Session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取Sq1Session对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//动态方式获取接口实现类对象
            //5.通过实现类对象调用方法,接收结果
            result = mapper.insert(stu);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //7.返回结果
        return result;
    }

    //    修改数据
    @Override
    public Integer update(Student stu) {
        InputStream is = null;
        SqlSession sqlSession = null;
        Integer result = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取Sq1Session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取Sq1Session对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//动态方式获取接口实现类对象
            //5.通过实现类对象调用方法,接收结果
            result = mapper.update(stu);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //7.返回结果
        return result;
    }

    //    删除数据
    @Override
    public Integer delete(Integer sid) {

        InputStream is = null;
        SqlSession sqlSession = null;
        Integer result = null;
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");
            //2.获取Sq1Session工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            //3.通过工厂对象获取Sq1Session对象
            sqlSession = sqlSessionFactory.openSession(true);
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//动态方式获取接口实现类对象
            //5.通过实现类对象调用方法,接收结果
            result = mapper.delete(sid);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (sqlSession != null) {
                sqlSession.close();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //7.返回结果
        return result;
    }
}

1.4 源码分析

  • 分析动态代理对象如何生成的? 通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper() 方法最终获取到 org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。
  • 分析方法是如何执行的? 动态代理实现类对象在执行方法的时候最终调用了 mapperMethod.execute() 方法,这个方法中通过 switch 语句根据操作类型来判断是新增、修改、删除、查询操作,最后一步回到了 MyBatis 最原生的 SqlSession 方式来执行增删改查。

1.5 知识小结

接口代理方式可以让我们只编写接口即可,而实现类对象由 MyBatis 生成。

实现规则 :

\1. 映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。

\2. 映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。

\3. 映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。

\4. 映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。

\5. 获取动态代理对象

SqlSession 功能类中的 getMapper() 方法。

二. 动态sql语句

2.1 动态sql语句概述

Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

下图所示 当我们查询的条件数量不一样时就需要重写 因此没办法动态变化 就增加程序的复杂性

img

动态SQL标签


:条件判断标签。


:循环遍历标签。

2.2 动态 SQL 之

语法

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>
	查询条件拼接
</if>

实例程序

 <!--多条件查询-->
    <select id="selectCondition" resultType="student" parameterType="student">
        <!--  <include refid="select"/>-->
        SELECT *
        FROM Student
        <!--
         WHERE sid = #{sid}
         WHERE sid = #{sid}
        AND name = #{name}
        AND age = #{age}
        AND birthday = #{birthday}

        -->
        <where>
            /*判断 如果 id有值 那么 id就可以作为查询的条件*/
            <if test="sid != null">
                sid = #{sid}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
            <if test="birthday != null">
                AND birthday = #{birthday}
            </if>
        </where>
    </select>

动态 SQL 之

语法

<foreach>:循环遍历标签。适用于多个参数或者的关系。
    <foreach collection=“”open=“”close=“”item=“”separator=“”>
		获取参数
	</foreach>

属性

collection:参数容器类型, (list-集合, array-数组)。

open:开始的 SQL 语句。

close:结束的 SQL 语句。

item:参数变量名。

separator:分隔符。

代码实例

    <!--多id查询-->
    <!--用一个list集合接收返回值-->
    <select id="selectByIds" resultType="student" parameterType="list">
        SELECT *
        FROM Student <!-- WHERE sid IN (1,2,3) -->
        <where>
            <!--循环获取 id 然后查询相关id的信息 -->
            <foreach collection="list" open="sid IN (" close=")" item="sid" separator=",">
                #{sid}
            </foreach>
        </where>
    </select>

2.4 SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

语法:

img

-  <sql>:抽取 SQL 语句标签。 
-  <include>:引入 SQL 片段标签。 
   <sql id=“片段唯一标识”>抽取的 SQL 语句</sql> <include refid=“片段唯一标识”/>
 

2.5 动态SQL 知识小结

动态SQL指的就是SQL语句可以根据条件或者参数的不同进行动态的变化。


:条件标签。


:条件判断的标签。


:循环遍历的标签。


:抽取SQL片段的标签。


:引入SQL片段的标签。

代码汇总

映射文件

<?xml version="1.0" encoding="UTF-8" ?><!--映射配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace 命名空间-->
<mapper namespace="com.itss.mapper.StudentMapper">
    <!--抽取代码 SELECT * FROM Student -->
    <sql id="select">
        SELECT *
        FROM Student
    </sql>

    <select id="selectAll" resultType="student">
        <!-- 引入 抽取的标签 替换原来的语句 -->
        <!--SELECT * FROM Student-->
        <include refid="select"/>
    </select>
    <!--通过id查询信息-->
    <select id="selectById" resultType="student" parameterType="int">
        <include refid="select"/>
        WHERE sid = #{sid}
    </select>
    <!--新增信息-->
    <insert id="insert" parameterType="student">
        INSERT INTO Student
        VALUES (#{sid}, #{name}, #{age}, #{birthday})
    </insert>
    <!--修改信息-->
    <update id="update" parameterType="student">
        UPDATE Student
        SET name=#{name},
            age=#{age},
            birthday=#{birthday}WHERE sid=#{sid}
    </update>
    <!--删除信息-->
    <delete id="delete" parameterType="int">
        DELETE
        FROM Student
        WHERE sid = #{sid}
    </delete>

    <!--多条件查询-->
    <select id="selectCondition" resultType="student" parameterType="student">
        <!--  <include refid="select"/>-->
        <include refid="select"/>
        <!--
         WHERE sid = #{sid}
         WHERE sid = #{sid}
        AND name = #{name}
        AND age = #{age}
        AND birthday = #{birthday}

        -->
        <where>
            /*判断 如果 id有值 那么 id就可以作为查询的条件*/
            <if test="sid != null">
                sid = #{sid}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
            <if test="birthday != null">
                AND birthday = #{birthday}
            </if>
        </where>
    </select>
    <!--多id查询-->
    <!--用一个list集合接收返回值-->
    <select id="selectByIds" resultType="student" parameterType="list">
        <include refid="select"/> <!-- WHERE sid IN (1,2,3) -->
        <where>
            <!--循环获取 id 然后查询相关id的信息 -->
            <foreach collection="list" open="sid IN (" close=")" item="sid" separator=",">
                #{sid}
            </foreach>
        </where>
    </select>

</mapper>

持久层接口

package com.itss.mapper;

import com.itss.bean.Student;

import java.util.List;

/**
 * @author IT苏苏
 * @className StudentMapper.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 22 日 17  17:16:46
 **/
//持久层接口
public interface StudentMapper {
    //      查询全部
    public abstract List<Student> selectAll();

    //      根据id查询
    public abstract Student selectById(Integer sid);

    //      新增数据
    public abstract Integer insert(Student stu);

    //      修改数据
    public abstract Integer update(Student stu);

    //      删除数据
    public abstract Integer delete(Integer sid);

    //多条件查询
    public abstract List<Student> selectCondition(Student stu);

    //    根据多个id查询
    public abstract List<Student> selectByIds(List<Integer> sids);
}

测试类

package com.itss.dynamic;

import com.itss.bean.Student;
import com.itss.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author IT苏苏
 * @className Test01.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 23 日 19  19:35:39
 **/
public class Test01 {
    @Test
    public void selectByIds() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        ArrayList<Integer> sids = new ArrayList<>();
        sids.add(1);
        sids.add(2);
        sids.add(3);
        //5.调用实现类的方法,接收结果
        List<Student> list = mapper.selectByIds(sids);

        //6.处理结果
        for (Student student : list) {
            System.out.println("查询结果:" + student);
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }

    @Test
    public void selectCondition() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student stu = new Student();
        stu.setSid(5);
        stu.setName("新增");
        stu.setAge(17);
        Date date = null;
        String str = "2022-11-21";
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = formatter.parse(str);
            stu.setBirthday(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //5.调用实现类的方法,接收结果
        List<Student> list = mapper.selectCondition(stu);

        //6.处理结果
        for (Student student : list) {
            System.out.println("查询结果:" + student);
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }
}

三. 分页插件

3.1 分页插件介绍

img

  • 分页可以将很多条结果进行分页显示。
  • 如果当前在第一页,则没有上一页。如果当前在最后一页,则没有下一页。
  • 需要明确当前是第几页,这一页中显示多少条结果。

MyBatis分页插件总结

  1. 在企业级开发中,分页也是一种常见的技术。而目前使用的 MyBatis 是不带分页功能的,如果想实现分页的 功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的,所以手写分页 成本较高。这个时候就可以借助分页插件来帮助我们实现分页功能。
  2. PageHelper:第三方分页助手。将复杂的分页操作进行封装,从而让分页功能变得非常简单。

3.2 分页插件实现步骤

1、使用maven引入jar包。

        <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser -->
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>3.1</version>
        </dependency>

2.在核心配置文件中集成分页助手插件。

img

    <!--集成分页插件助手
    plugin指定集成第三方插件
    interceptor指定插件的全类名-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

3.在测试类中使用分页助手相关API实现分页功能。

准备数据库数据

img

测试类代码

package com.itss.paging;

import com.github.pagehelper.PageHelper;
import com.itss.bean.Student;
import com.itss.mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author IT苏苏
 * @className Test01.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 24 日 17  17:41:11
 **/
public class Test01 {
    @Test
    public void selectPaging() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        
//        通过分页助手来实现分页功能
//        第一页显示 3条数据
        PageHelper.startPage(1,3);//第一个参数表示当前的页数   第二个参数表示要显示的条数
//        第二页显示 3条数据
        PageHelper.startPage(2,3);//第一个参数表示当前的页数   第二个参数表示要显示的条数
//        第三页显示 3条数据
        PageHelper.startPage(3,3);//第一个参数表示当前的页数   第二个参数表示要显示的条数


        //5.调用实现类的方法,接收结果
        List<Student> list = mapper.selectAll();

        //6.处理结果
        for (Student student : list) {
            System.out.println("查询结果:" + student);
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }
}

3.3 分页插件的参数获取

获得分页相关的其他参数

//其他分页的数据
PageInfo<User> pageInfo = new PageInfo<User>(select);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());

分页插件相关参数

PageInfo :封装分页相关参数的功能类。

核心方法

img

img

3.4 分页插件知识小结

​ 分页:可以将很多条结果进行分页显示。

  • 分页插件 jar 包: pagehelper-5.1.10.jar jsqlparser-3.1.jar
  • :集成插件标签。

分页助手相关 API

1.PageHelper:分页助手功能类。

\2. startPage():设置分页参数

\3. PageInfo:分页相关参数功能类。

\4. getTotal():获取总条数

\5. getPages():获取总页数

\6. getPageNum():获取当前页

\7. getPageSize():获取每页显示条数

\8. getPrePage():获取上一页

\9. getNextPage():获取下一页

\10. isIsFirstPage():获取是否是第一页

\11. isIsLastPage():获取是否是最后一页

四.MyBatis的多表操作

4.1 多表模型介绍

我们之前学习的都是基于单表操作的,而实际开发中,随着业务难度的加深,肯定需要多表操作的。

  • 多表模型分类 一对一:在任意一方建立外键,关联对方的主键。
  • 一对多:在多的一方建立外键,关联一的一方的主键。
  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。

4.2 多表模型一对一操作

\1. 一对一模型: 人和身份证,一个人只有一个身份证

数据库准备

CREATE DATABASE db23;

USE db23;

CREATE TABLE person(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	age INT
);
INSERT INTO person VALUES (NULL,'张三',23);
INSERT INTO person VALUES (NULL,'李四',24);
INSERT INTO person VALUES (NULL,'王五',25);

CREATE TABLE card(
	id INT PRIMARY KEY AUTO_INCREMENT,
	number VARCHAR(30),
	pid INT,
	CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)
);
INSERT INTO card VALUES (NULL,'12345',1);
INSERT INTO card VALUES (NULL,'23456',2);
INSERT INTO card VALUES (NULL,'34567',3);

img

img

2.配置文件

<?xml version="1.0" encoding="UTF-8" ?><!--映射配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itss.table01.OneToOneMapper">
    <!--配置字段和实体对象属性的映射关系-->
    <resultMap id="oneToOne" type="card">
        <id column="cid" property="id"/>
        <result column="number" property="number"/>

        <!--配置被包含对象的映射关系
        property 被包含对象的变量名
        javaType 被包含对象的数据类型
        -->
        <association property="p" javaType="person">
            <id column="pid" property="id"/>
            <result column="name" property="name"/>
            <result column="age" property="age"/>

        </association>

    </resultMap>
    <select id="selectAll" resultMap="oneToOne">
        SELECT c.id cid, number, pid, name, age
        FROM card c,
             person p
        WHERE c.pid = p.id
    </select>
</mapper>

接口

package com.itss.table01;

import com.itss.bean.Card;

import java.util.List;


public interface OneToOneMapper {
//    查询全部
    public abstract List<Card> selectAll();
}

身份证号类

package com.itss.bean;

/**
 * @author IT苏苏
 * @className Card.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 24 日 20  20:22:58
 **/
public class Card {
    private Integer id;//主键id
    private String number;//身份证号

    private Person p;//所属人的对象

    public Card() {
    }

    public Card(Integer id, String number, Person p) {
        this.id = id;
        this.number = number;
        this.p = p;
    }

    @Override
    public String toString() {
        return "Card{" +
                "id=" + id +
                ", number='" + number + '\'' +
                ", p=" + p +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Person getP() {
        return p;
    }

    public void setP(Person p) {
        this.p = p;
    }
}

person类

package com.itss.bean;

/**
 * @author IT苏苏
 * @className Person.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 24 日 20  20:20:06
 **/
public class Person {
    private Integer id;//主键id
    private String name;//人的姓名
    private Integer age;//人的年龄

    public Person() {
    }

    public Person(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

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

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

数据库连接配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db23
username=root
password=123456

核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
    <!--    <properties> :引入数据库连接配置文件标签。
        属性  resource:数据库连接配置文件路径-->
    <properties resource="jdbc.properties"/>

    <!--配置 log4j -->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--<typeAliases>:为全类名起别名的父标签。-->
    <typeAliases>
        <!--通用方式  在bean包下所有的类一起 起别名
        别名就是类名 例如 bean包下的Card类 别名就为 card -->
        <package name="com.itss.bean"/>
    </typeAliases>

    <!--集成分页插件助手
    plugin指定集成第三方插件
    interceptor指定插件的全类名-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

    <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql"><!-- environments 要与 environment 一样  表示要使用哪一个 environment  就将environments 更改成一样-->
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dataSource数据源信息   type属性 连接池-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息  数据库连接配置文件引入后 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>

            </dataSource>
        </environment>
    </environments>
    <!-- mappers引入映射配置文件 -->
    <mappers>
        <!-- mapper 引入指定的映射配置文件   resource属性指定映射配置文件的名称 -->
        <mapper resource="OneToOneMapper.xml"/>
    </mappers>
</configuration>

日志配置文件

# Global logging configuration
# ERROR 错误信息
# WARN 警告信息
# INFO 普通信息
# DEBUG
# stdout 信息输出到控制台
log4j.rootLogger=DEBUG, stdout
# Console output...
# 输出格式
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

测试类

package com.itss.table01;

import com.itss.bean.Card;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

import java.util.List;


public class Test01 {
    @Test
    public void selectAll() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);

        //5.调用实现类的方法,接收结果
        List<Card> list = mapper.selectAll();

        //6.处理结果
        for (Card card : list) {
            System.out.println("查询结果:" + card);
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }
}

3.一对一配置总结:

<resultMap>:配置字段和对象属性的映射关系标签。
    id 属性:唯一标识
    type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
    column 属性:表中字段名称
    property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。
    property 属性:被包含对象的变量名
    javaType 属性:被包含对象的数据类型

4.3 多表模型一对多操作

\1. 一对多模型: 一对多模型:班级和学生,一个班级可以有多个学生。

\2. 代码实现

– 步骤一: sql语句准备

CREATE TABLE classes(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20)
);
INSERT INTO classes VALUES (NULL,'java一班');
INSERT INTO classes VALUES (NULL,'java二班');


CREATE TABLE student(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(30),
	age INT,
	cid INT,
	CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
);
INSERT INTO student VALUES (NULL,'张三',23,1);
INSERT INTO student VALUES (NULL,'李四',24,1);
INSERT INTO student VALUES (NULL,'王五',25,2);
INSERT INTO student VALUES (NULL,'赵六',26,2);

学生类

package com.itss.bean;


public class Student {

    private Integer id;//主键id
    private String name;//学生姓名
    private Integer age;//学生年龄

    public Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

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

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

班级类

package com.itss.bean;

import javax.rmi.CORBA.StubDelegate;
import java.util.List;

/**
 * @author IT苏苏
 * @className Classes.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 25 日 15  15:53:21
 **/
public class Classes {
    private Integer id;//主键id
    private String name;//班级名称
    private List<Student> students;//班级中所有学生对象

    public Classes() {
    }

    public Classes(Integer id, String name, List<Student> students) {
        this.id = id;
        this.name = name;
        this.students = students;
    }

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

    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<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

映射配置文件

<?xml version="1.0" encoding="UTF-8" ?><!--映射配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itss.table02.OneToManyMapper">
    <resultMap id="oneToMany" type="classes">
        <id column="cid" property="id"/>
        <result column="cname" property="name"/>
        <!--collection:配置被包含的集合对象映射关系
        property:被包含对象的变量名
        ofType:被包含对象的实际数据类型-->
        <collection property="students" ofType="student">
            <id column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="sage" property="age"/>
        </collection>
    </resultMap>
    <select id="selectAll" resultMap="oneToMany">

        SELECT c.id cid, c.name cname, s.id sid, s.name sname, s.age sage
        FROM classes c,
             student s
        WHERE c.id = s.cid
    </select>

</mapper>

核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
    <!--    <properties> :引入数据库连接配置文件标签。
        属性  resource:数据库连接配置文件路径-->
    <properties resource="jdbc.properties"/>

    <!--配置 log4j -->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--<typeAliases>:为全类名起别名的父标签。-->
    <typeAliases>
        <!--通用方式  在bean包下所有的类一起 起别名
        别名就是类名 例如 bean包下的Card类 别名就为 card -->
        <package name="com.itss.bean"/>
    </typeAliases>

    <!--集成分页插件助手
    plugin指定集成第三方插件
    interceptor指定插件的全类名-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

    <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql"><!-- environments 要与 environment 一样  表示要使用哪一个 environment  就将environments 更改成一样-->
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dataSource数据源信息   type属性 连接池-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息  数据库连接配置文件引入后 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>

            </dataSource>
        </environment>
    </environments>
    <!-- mappers引入映射配置文件 -->
    <mappers>
        <!-- mapper 引入指定的映射配置文件   resource属性指定映射配置文件的名称 -->
        <mapper resource="OneToOneMapper.xml"/>
        <mapper resource="OneToManyMapper.xml"/>

    </mappers>
</configuration>

接口

package com.itss.table02;

import com.itss.bean.Classes;

import java.util.List;

/**
 * @author IT苏苏
 * @className OneToManyMapper.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 25 日 16  16:11:26
 **/
public interface OneToManyMapper {
    //    查询全部
    public abstract List<Classes> selectAll();
}

测试类

package com.itss.table02;


import com.itss.bean.Classes;
import com.itss.bean.Student;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class Test01 {
    @Test
    public void selectAll() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);

        //5.调用实现类的方法,接收结果
        List<Classes> classes = mapper.selectAll();

        //6.处理结果
        for (Classes cls : classes) {
            System.out.println(cls.getId() + "," + cls.getName());
            List<Student> students = cls.getStudents();
            for (Student student : students
            ) {
                System.out.println("\t" + student);
            }
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }
}

3.一对多配置文件总结:

<resultMap>:配置字段和对象属性的映射关系标签。
    id 属性:唯一标识
    type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
    column 属性:表中字段名称
    property 属性: 实体对象变量名称
<collection>:配置被包含集合对象的映射关系标签。
    property 属性:被包含集合对象的变量名
    ofType 属性:集合中保存的对象数据类型

4.4 多表模型多对多操作

\1. 多对多模型:学生和课程,一个学生可以选择多门课程、一个课程也可以被多个学生所选择。

\2. 代码实现

– 步骤一: sql语句准备

CREATE TABLE course(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20)
);
INSERT INTO course VALUES (NULL,'语文');
INSERT INTO course VALUES (NULL,'数学');


CREATE TABLE stu_cr(
	id INT PRIMARY KEY AUTO_INCREMENT,
	sid INT,
	cid INT,
	CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
	CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
);
INSERT INTO stu_cr VALUES (NULL,1,1);
INSERT INTO stu_cr VALUES (NULL,1,2);
INSERT INTO stu_cr VALUES (NULL,2,1);
INSERT INTO stu_cr VALUES (NULL,2,2);

映射配置文件

<?xml version="1.0" encoding="UTF-8" ?><!--映射配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itss.table03.ManyToManyMapper">

    <resultMap id="manyToMany" type="student">
        <id column="sid" property="id"/>
        <result column="sname" property="name"/>
        <result column="sage" property="age"/>
        <collection property="courses" ofType="course">
            <id column="cid" property="id"/>
            <result column="cname" property="name"/>
        </collection>
    </resultMap>
    <select id="selectAll" resultMap="manyToMany">
        SELECT sc.sid, s.name sname, s.age sage, sc.cid, c.name cname
        FROM student s,
             course c,
             stu_cr sc
        WHERE sc.cid = s.id
          AND sc.cid = c.id

    </select>

</mapper>

添加映射文件到核心配置文件中

img

接口

package com.itss.table03;

import com.itss.bean.Student;

import java.util.List;

/**
 * @author IT苏苏
 * @className ManyToManyMapper.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 25 日 17  17:07:42
 **/
public interface ManyToManyMapper {
    //    查询全部
    public abstract List<Student> selectAll();

}

学生类

package com.itss.bean;


import java.util.List;

public class Student {

    private Integer id;//主键id
    private String name;//学生姓名
    private Integer age;//学生年龄
    private List<Course> courses;//当前学生所选择的课程名称

    public Student(Integer id, String name, Integer age, List<Course> courses) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.courses = courses;
    }

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", courses=" + courses +
                '}';
    }

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
}

课程类

package com.itss.bean;

/**
 * @author IT苏苏
 * @className Course.java
 * @Form no
 * @Description ToDo
 * @createTime 2022 年 11 月 25 日 16  16:58:47
 **/
public class Course {
    private Integer id;//主键id
    private String name;//课程名称

    public Course() {
    }

    public Course(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

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

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

测试类

package com.itss.table03;


import com.itss.bean.Classes;
import com.itss.bean.Course;
import com.itss.bean.Student;
import com.itss.table02.OneToManyMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class Test01 {
    @Test
    public void selectAll() throws IOException {
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //4.获取StudentMapper接口的实现类对象
        ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);

        //5.调用实现类的方法,接收结果
        List<Student> students = mapper.selectAll();

        //6.处理结果
        for (Student student : students) {
            System.out.println(student.getId() + "," + student.getName()+","+student.getAge());
            List<Course> courses = student.getCourses();
            for (Course course : courses
            ) {
                System.out.println("\t" + course);
            }
        }

        //7.释放资源
        sqlSession.close();
        is.close();

    }
}

3.多对多配置文件总结:

<resultMap>:配置字段和对象属性的映射关系标签。
	id 属性:唯一标识
	type 属性:实体对象类型
 <id>:配置主键映射关系标签。
 <result>:配置非主键映射关系标签。
	column 属性:表中字段名称
	property 属性: 实体对象变量名称
<collection>:配置被包含集合对象的映射关系标签。
	property 属性:被包含集合对象的变量名
	ofType 属性:集合中保存的对象数据类型

4.5 多表模型操作总结

 <resultMap>:配置字段和对象属性的映射关系标签。
    id 属性:唯一标识
    type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
	column 属性:表中字段名称
	property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。
	property 属性:被包含对象的变量名
	javaType 属性:被包含对象的数据类型
<collection>:配置被包含集合对象的映射关系标签。
	property 属性:被包含集合对象的变量名
	ofType 属性:集合中保存的对象数据类型

原文地址:http://www.cnblogs.com/sql-bk/p/16927443.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性