MyBatis合集

概述

Mybatis是基于java的持久层框架,采用ORM思想(对象关系映射)去解决实体和数据的映射关系。内部封装了jdbc功能省略了jdbc一些接口的操作,只需要操作配置文件
注意:实体类中的属性和数据库中的需要保持一致

#利用框架开发三种方式:
1、xml文件配置(映射)
2、注解
3、注解结合xml
注意:如果sql语句复杂用xml配置映射

maven的安装与配置

压缩包解压到D盘的根目录下
1、配置MAVEN_HOME路径
在这里插入图片描述
2、配置path路径
在这里插入图片描述
3、查看安装结果,成功则显示版本号和上一步配置的路径
cmd命令行输入mvn -v
在这里插入图片描述
4、搭载本地仓库

找到maven下的conf文件夹中的settings.xml
在这里插入图片描述

国外网站的jar包下载很慢,需要使用阿里云的镜像
需要在 mirrors 标签中添加以下代码

<mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
</mirror>

找到settings标签中添加这段代码
D:/ repository
注意:在D:/下新建repository文件夹

在idea中配置路径
在这里插入图片描述

开始干活!
创建web项目骨架maven工程:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
pom.xml文件添加依赖
在这里插入图片描述
测试代码
在这里插入图片描述

把工程部署到Tomcat服务器上

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样便可在tomcat服务器上运行成功

创建工程

在这里插入图片描述
在这里插入图片描述
打印输入是否成功
在这里插入图片描述
小功能:右键点击Generate可自动生成set/get方法
在这里插入图片描述
在这里插入图片描述

基于MyBatis搭载框架工程

首先展示xml配置实现
是通过配置文件 pom.xml(依赖坐标),核心配置文件xml,映射文件xml。

实际开发中要求:mybatis下一般不写dao层接口的实现类

实现查询

(一)MyBatis搭建工程(利用xml文件方式)

1、新建maven项目
本次演示不创建骨架
在百度搜索MyBatis官方文档找到搭建所需要的依赖
2、pom.xml文件导入依赖

   <!--依赖的坐标-->
<dependencies>
    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>

    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.30</version>
    </dependency>

    <!--日志文件(必加的)-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

    <!--测试 (必加的)-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>

</dependencies>

3、创建实体类
需要继承于序列化接口 封装私有属性 get/set方法等
在这里插入图片描述
4、用户持久层接口
在源码目录下(java)创建接口,路径包名com.neuedu.dao.UserDao

public interface UserDao {
/查询所有用户信息/
List findAll();
}

5、填写配置文件SqlMappingConfig.xml
resources配置目录下创建文件:SqlMappingConfig.xml
xml文件约束配置 添加以下代码

<?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>
    <environments default="mysql">
        <!--配置mysql的环境 default和id内容需一致-->
        <environment id="mysql">
            <!--配置的事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--详细数据的基本信息(所连接数据库的信息) 4个-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/student"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--找这个里面的配置文件,与该类形成映射关系 从而联系整个mybatis工程-->
        <mapper resource="com/neuedu/dao/UserDao.xml"/>
    </mappers>
</configuration>

6、设置Mapper代理方式的配置文件(xml)
resources路径下,写一个UserDao.xml的映射配置文件
要求要与对应Mapper的dao层接口包路径一致,只不过在resources下
在这里插入图片描述

添加协议和mapper映射

<?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.neuedu.dao.UserDao">
    <!--配置sql语句 查询所有用户信息-->
    <select id="findAll" resultType="com.neuedu.domain.User">
        select * from users
    </select>
</mapper>

7、编写测试类具体实现过程
在这里插入图片描述

package com.neuedu.test;

import com.neuedu.dao.UserDao;
import com.neuedu.domain.User;
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;

public class MyBatisTest {
    public static void main(String[] ages) throws IOException {
        //1、读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMappingConfig.xml");

        //2、创建SqlSessionFactory工厂(工厂模式)*/
        //创建工厂的过程 mybatis使用构建者模式(将对象细节隐藏,使用时直接调用方法就可以拿到对象)

        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);

        //3、使用工厂生产SqlSession对象
        SqlSession session = factory.openSession();

        //4、利用该对象SqlSession 可以创建Dao接口的代理对象(代理模式,不需要new对象)
        UserDao userDao = session.getMapper(UserDao.class);

        //5、使用代理对象调用执行方法
        List<User> users = userDao.findAll();
        for (User user : users){
            System.out.println(user);
        }

        //6、释放资源
        session.close();
        in.close();
    }
}

(二)MyBatis搭建工程(利用注解方式)

注解的特点:
annotation 注解(原理就是通过class类实现的),不需要配置xml文件了。
注解的实现使代码又一次减少了 不需要创建和配置映射文件的xml(userdao. xml文件)如图所示
在这里插入图片描述

使用@select注解通过class直接指向接口并调用其中方法
在这里插入图片描述

以上利用配置xml方式和注解两种方式演示了查询
以下演示方式为配置xml文件,实际开发中我们主要利用xml配置。

实现插入

1、parameterType属性:代表了接口传参(对象)的类型
2、sql语句中使用#{}字符格式:它代表占位符,相当于jdbc中的?
在实体类中取出来的属性。
3、#{user.username}是ognl表达式,apache提供的一种表达式语言。

注意:数据库中插入是DML语句,属于事务。在关闭资源之前需要手动提交 session.commit()

在这里插入图片描述
在这里插入图片描述

<!--新增用户操作-->
    <insert id="insertUser" parameterType="com.neuedu.domain.User">
        insert into users(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{Address})
    </insert>

测试方法
整合测试代码:
测试方法不使用main方法,以后使用测试方法 @Test
@Test 代表测试方法,一个类中可以有多个
@Before 在测试方法运行之前先执行这个方法
@After 在测试之后执行
如:
在这里插入图片描述

package com.neuedu.test;

import com.neuedu.dao.UserDao;
import com.neuedu.domain.User;
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.After;
import org.junit.Before;
import org.junit.Test;

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

public class MyBatisTest {

    private InputStream in;
    private SqlSession session;
    private UserDao userDao;

    @Before//在测试方法之前执行
    public void init() throws IOException {
        //1、读取配置文件
        in = Resources.getResourceAsStream("SqlMappingConfig.xml");

        //2、创建SqlSessionFactory工厂(工厂模式)*/
        //创建工厂的过程 mybatis使用构建者模式(将对象细节隐藏,使用时直接调用方法就可以拿到对象)

        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);

        //3、使用工厂生产SqlSession对象
        session = factory.openSession();

        //4、利用该对象SqlSession 可以创建Dao接口的代理对象(代理模式,不需要new对象)
        userDao = session.getMapper(UserDao.class);
    }

    @After//在测试方法指向后执行
    public void destory() throws IOException {
        //提交事务
        session.commit();

        //6、释放资源
        session.close();
        in.close();
    }

    @Test
    public void testSelectAll(){
        List<User> users = userDao.findAll();
        for (User user : users){
            System.out.println(user);
        }
    }

    @Test
    public void testInsert(){
        //模拟的用户数据
        User user = new User();
        user.setUsername("haha");
        user.setSex("男");
        user.setBrithday(new Date());
        user.setAddress("沈阳浑南区");

        //执行插入用户的方法
        userDao.insertUser(user);
    }
}

实现更新(Update)

在这里插入图片描述
在这里插入图片描述

修改方法


    <!--更新用户信息-->
    <update id="updateUser" parameterType="com.neuedu.domain.User">
        update users set username=#{username}, birthday=#{birthday},
        sex=#{sex},address=#{Address} where id=#{id}
    </update>

在这里插入图片描述

实现删除(delete)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

模糊查询(like)

方式一:(提倡)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方式二

在这里插入图片描述

在这里插入图片描述

方式1:
因为配置文件中没有%,所以要求我们在传入参数时,需要给模糊查询%的标识
配置文件中#{username} 也只是一个占位符,在sql语句中显示?

    <!--模糊查询-->
    <select id="findByName" resultType="com.neuedu.domain.User">
        select * from users where username like #{username}
    </select>

方式2<!--模糊查询-->
    <select id="findByName" parameterType="java.lang.String" resultType="com.neuedu.domain.User">
        select * from users where username like '%${value}%'
    </select>

注意:原有的#{}占位符,改成了value {value}写法是固定的,不能写成其他的名字

分组查询
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

扩展:新增用户时id的返回

keyColumn 对应表中的列
keyProperty 对应实体类中属性
resultType 结果集的类型
order 插入前/后获取结果集 后的话属性值就填AFTER(after)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

问题:#{}${} 区别?

1、#{}表示的是一个占位符号
通过#{}可以实现preparedStatement中的占位符的值的设置
#{}可以有效的防治注入漏洞
2、${}表示拼接sql语句
${}无法防止注入漏洞

参数核心配置文件及其映射文件参数

指这两个文件:
1、SqlMappingConfig.xml配置
2、mapper映射文件(userDao.xml)

parameter属性

用作指明dao层接口参数的数据类型,指向实体类。

接口的参数的形式:
1、传入基本数据类型,会自动转换包装类可不用全限定类型(类名+包名)
2、传入字符串类型,指明全限定类名
3、传入pojo(简单的java实体类)对象,指明全限定类名

例子:
根据用户名查询用户信息,一个类中存的另一个类的对象作为属性,再当作查询条件使用。

public class QueryVo{  //pojo类
   private User user;
   private A a;
   private int age; 

   setXX
   getXX	

}

在这里插入图片描述

在这里插入图片描述

userDao.xml文件中
在这里插入图片描述
在这里插入图片描述

resultMap 结果类型(含有映射关系的)

作用:将表中的列和实体类中属性建立映射关系
如这种情况:命名不一致时,表中username----实体类中userName。

修改原有的配置文件
建立User实体类与数据库表的映射关系

UserDao.xml
改造前
在这里插入图片描述

利用resultMap后
在这里插入图片描述

<!--建立User实体类与数据库表的映射关系
    id:给一个唯一的标识,给查询select标签引用的
    type:指定实体类的全限定类名
    -->
    <resultMap id="userMap" type="com.neuedu.domain.User">
        <!--id 用于主键字段 需要单独描述出来
        column:表中的列
        property:实体类中的属性
        -->
        <id column="id" property="id"></id>
        <result column="username" property="userName"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
    </resultMap>


    <select id="findAll" resultMap="userMap">
        select * from users
    </select>

总结:resultMap实际应用就是为了解决表的列名和实体类中属性名不一致的问题。后续多表查询的时候也会应用。

核心配置文件内标签简介(SqlMappingConfig.xml)

configuration标签中的内容和书写顺序:

properties  属性
   propety
settings 设置全局配置参数
   setting
typeAliases 类型别名
   typeAlias
...

environments 环境变量
   environment 
       transactionManager 事务管理
       dataSource 数据库源

mappers 映射器:起到的作用就是将核心配置文件和映射文件进行有效的关联

在这里插入图片描述

properties 属性,主要针对数据库的配置

两种方式可以配置
方式1:

<properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydata"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </properties>

方式2:(常用)
建立一个db.propertis文件放在resources下,就识别为配置文件。
文件中配置数据库jdbc的连接信息

在这里插入图片描述

<!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置详细的数据的基本信息  4个基本信息-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>

在这里插入图片描述

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

typeAliases 类型的别名

MyBatis默认支持别名,实际开发中我们会采用自定义别名的方式来开发
但是注意:如果名字弄乱了,一堆错误。

<typeAliases>
        <!--单个别名定义-->
        <typeAlias alias="user" type="com.neuedu.domain.User"></typeAlias>

        <!--当有多个实体类需要别名的时候
        指定了该实体类的包路径后,该包下面所有的实体类都会有自己的注册别名
        别名就是我们的类名
        -->
        <package name="com.neuedu.domain"/>
    </typeAliases>

核心配置文件中的<mappers>

mapper下
resource属性,相当于resource路径下的文件:识别xml这样的资源文件
“com/neuedu/dao/UserDao.xml”
在这里插入图片描述

class属性:类路径 按照包的形式写
com.neuedu.dao.UserDao

接口不一定只有一个接口,同样映射文件也不一定只有一个映射文件
当有多个的时候,我们使用package标签(重要)
<package name=""/>
注册指定包下的所有mapper接口(就是指定包下的映射xml文件都放在这里比如userDao.xml)
注意:要求mapper接口名和mapper映射文件名字要相同,且放在同一个目录中

<?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">

<!--mybatis核心配置-->
<configuration>
    <!--指定用于properties配制文件的位置,要求配置文件必须在类的路径下-->
    <properties resource="db.propertis">

    </properties>

    <!--别名设置 所用的别名就是我们真实的类名-->
    <typeAliases>
        <package name="com.neuedu.domain"/>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境 default和id内容一致的-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置详细的数据的基本信息  4个基本信息-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.neuedu.dao"/>
    </mappers>

</configuration>

动态sql——实际应用就是在条件查询上

动态sql语句实际应用:就是为了解决复杂的sql语句的业务逻辑,场景是在应用于业务逻辑比较复杂的时候。

例如:查询用户信息,如果名字不为空则按照具体的名字查询;如果性别不为空还可以根据性别查询;如果名字和性别都不为空,按照名字和性别查询。

在这里插入图片描述

1、if标签

在这里插入图片描述

<resultMap id="userMap" type="User">
        <!--id 用于主键字段
        column:表中的列
        property:实体类中的属性
        -->
        <id column="id" property="id"></id>
        <result column="username" property="userName"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
    </resultMap>

    <!--根据条件查询-->
    <select id="findUserByCondition" resultMap="userMap" parameterType="User">
        select * from users where 1=1
        <if test="userName != null">
            and username = #{userName}
        </if>

        <if test="sex != null">
            and sex = #{sex}
        </if>
    </select>

在这里插入图片描述

2、where标签

where标签可以简化if标签的操作
在这里插入图片描述

<select id="findUserByCondition" resultMap="userMap" parameterType="User">
        select * from users
        <where>
            <if test="userName != null">
                and username = #{userName}
            </if>

            <if test="sex != null">
                and sex = #{sex}
            </if>
        </where>
    </select>

3、foreach标签

API:
foreach 用于遍历集合
collection 代表了要遍历的集合元素
open 代表了语句的开始部分
close 代表语句结束部分
注意:开始指的是遍历集合数据

item 代表了遍历集合中的每个元素,生成的变量名
separator 分隔符

注意:
1、封装pojo类 封装了用户对象和存储id的集合对象
2、foreach标签的sql的拼接形式

例如
有一个需求:
传入多个id查询用户信息,将id存放的信息当做一个集合,传入集合对集合中的数据遍历使用就可以了。
在这里插入图片描述

在这里插入图片描述

<!--根据QueryVo 中提供的id集合,查询用户信息-->
    <select id="findUserByInIds" resultMap="userMap" parameterType="QueryVo">
        select * from users
        <where>
            <if test="ids != null and ids.size() > 0">
                <foreach collection="ids" open="and id in(" close=")" item="uid" separator=",">
                    #{uid}
                </foreach>
            </if>
        </where>

    </select>

在这里插入图片描述

多表查询 (重点)

概述:
mybatis下 实体关系
1)一对一关系 两张表他们之间没有中间表的
2)一对多关系 可能有中间表也可能没有
3)多对多的关系 双向的一对多关系 有中间表

表结构 需要合理建立对应的表并设置外键联系
主要操作还是框架中的配置 xml 标签

(一)多对多关系(双向一对多):

两个实体类,其中一个含有另一个对象的集合。
注意: 是以一对多形式为例,进行实现双向一对多,本质就是多对多关系。
第一张表跟中间表连,第一次连接后的结果再跟另一张表第二次连接,
两个实体类,其中一个含有另一个对象的集合。

模拟一个场景:用户和角色的关系模型
需求:查询角色的时候把角色所对应的所有用户信息查出来

because:
(一个用户可以有多个角色)
(一个角色可以赋予多个用户)
so:
当查询用户时,可以同时得到用户所包含的角色信息
当查询角色时,可以同时得到角色所赋予的用户信息

xml文件中的标签说明:

<collection property="users" ofType="user">

collection标签:就是实现一对多的映射关系
property属性:指向实体类中一个对象集合(用户类的对象)作为的属性
ofType属性:集合中储存元素的类型,另一张表在数据库中的映射关系

操作步骤:
1、建立两张表
用户表(id 用户名 性别 出生日期 地址)
角色表(id 角色名称 角色描述)
额外增加一张表:中间表(作用就是为了实现两张表的的多对多对应关系)
中间表:包含两张表的主键,在中间表是外键
用户编号 角色编号
2、根据表结构建立两个实体类
用户类
角色类
3、建立两个映射的配置文件
用户的映射文件
角色的映射文件
4、实现配置查询
当查询用户时,可以同时得到用户所包含的角色信息
当查询角色时,可以同时得到角色所赋予的用户信息

首先从实体类中下手
需要在Role实体类中实现一个角色对应多个用户
在这里插入图片描述

//一个角色对应多个用户
    private List<User> users;

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

在这里插入图片描述

在这里插入图片描述

查询所有角色,同时获取角色对应的用户。并书写role表中的resultMap
在这里插入图片描述

<resultMap id="roleMap" type="Role">
        <id property="roleId" column="ID"></id>
        <result property="roleName" column="ROLE_NAME"></result>
        <result property="roleDesc" column="ROLE_DESC"></result>

        <collection property="users" ofType="user">
            <id column="id" property="id"></id>
            <result column="username" property="userName"></result>
            <result column="birthday" property="birthday"></result>
            <result column="sex" property="sex"></result>
            <result column="address" property="address"></result>
        </collection>

</resultMap>

<select id="findAll" resultMap="roleMap">
      select u.*,r.id as rid,r.role_name,r.role_desc from role r
      left join user_role ur on r.id = ur.rid
      left join user u on u.id = ur.uid
    </select>

注意:如果sql语句中给表中某一列改列名时,resultMap中的映射关系也要对应
在这里插入图片描述

另张表的信息也要查出来所以另张表的xml文件也要配置
在这里插入图片描述
在这里插入图片描述

(二)一对一关系

两个实体类,其中一个含有另一个对象。
指的是一个账户只有一个用户的信息。

场景:银行系统中的账户和用户
需求:查询银行账户的时候把它唯一对应的用户信息查出来。
比如银行系统中一个账号对应一个用户(使用者),(一多一)
但是一个用户可以有多个银行账号,(一对多)
如下两个表中有对应的关系,这时多表查询时,不需要中间表。

标签说明:

<association property="user" column="UID" javaType="User">

association标签:说明一个银行账号跟一个用户的一对一的映射关系。
property属性:另一张表中的一个对象(一条数据)。
column:和另张表的连接条件(表结构中的列)。
javaType:实体类中属性(就是连接的另张表)的数据类型,property属性对应对象的数据类型。

数据库中表的关系
账户表
在这里插入图片描述
用户信息表在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

<!--查询所有的信息-->
    <select id="findAll" resultMap="accountUserMap">
        select u.*, a.id as aid, a.uid, a.money
        from account a, user u
        where u.id = a.uid
    </select>

<!--定义account和resultMap的形式-->
    <resultMap id="accountUserMap" type="Account">
        <id property="id" column="ID"></id>
        <result property="uid" column="UID"></result>
        <result property="money" column="MONEY"></result>

        <!--一对一关系的映射-->
        <association property="user" column="UID" javaType="User">
            <id column="id" property="userId"></id>
            <result column="username" property="userName"></result>
            <result column="birthday" property="userBirthday"></result>
            <result column="sex" property="userSex"></result>
            <result column="address" property="userAddress"></result>
        </association>

    </resultMap>

在这里插入图片描述

resultMap和resultType的区别?

自己总结是当数据库中的列和实体类中的属性有对应时使用resultMap

MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,将数据库中列数据复制到对象的相应属性上,可以用于复制查询,两者不能同时用

延迟加载

概述:
先查询一张表,如果查出来的信息不够使用通过映射文件设置select属性连接其他的方法。
针对关联查询
实际开发中,我们并不需要总是加载用户信息

加载分类:
1)延迟加载(懒加载):在真正使用数据时才发起查询,不用的时候不查询
2)立即加载:不管用不用,都需要调用方法发起查询

延迟加载 好处:
弊端是多表查询,所有信息都查询出来。
先查询单表,如果单表满足不了需求,再去做多表查询

在加载情况下表的实体关系:
一对一 一对多 多对一 多对多
1)一对多 多对多 采用延迟加载
2)多对一 一对一 采用立即加载

mybatis默认的是立即加载

在这里插入图片描述
需求:
1)查询账户信息和用户信息(这个需求需要多表)
如果先查账户信息可以满足要求,那么就查询单表,如果满足不了要求,那就关联用户信息表查询——延迟加载

通过association 、collection实现延迟加载书写

通过association实现延迟加载:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<!--一对一关系的映射:配置封装User内容
            select:查询用户的唯一标识
            column:用户根据id查询时,所需要的参数
        -->
        <association property="user" column="UID" javaType="User" select="com.neuedu.dao.UserDao.findById">

        </association>

在这里插入图片描述

开启延迟加载 核心配置文件中设置

在这里插入图片描述

<!--配置参数-->
    <settings>
        <!--开启MyBatis的延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
</settings>

通过collection实现延迟加载

需求:
1)查询用户信息和它所对应的账户信息
在这里插入图片描述

<!-- 配置user对象中accounts集合的映射 -->
        <collection property="accounts" ofType="account" select="com.neuedu.dao.AccountDao.findByUid" column="id">
        </collection>

在这里插入图片描述
在这里插入图片描述

延时加载使用场景:

延迟加载是一种MyBatis的机制,这种机制就为了合理的使用资源,能单表查的不要多表查,如果单表查不到,关联到多表查询
做关联查询时
1、确定需求需要多表那就做多表连接
2、不确定是否多表连接,可以有时候需要单表,有时候需要多表 就做延迟加载

缓存

概述:

针对于查询,存在于内存中的临时数据,第一次查询缓存到内存中,下一次相同的操作直接使用内存中的缓存,减少了对数据库的操作次数

作用:为了减少查询数据库的次数,从而提高性能
MyBatis缓存分为一级缓存和二级缓存

一级缓存:SqlSession对象的缓存(了解。在二级缓存的结构基础之上)
二级缓存:SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存

一级缓存使用步骤(了解)

一级缓存 SqlSession 不需要手动开启,只要针对该对象没有close或者flush 缓存就存在,
关闭一级缓存
clearCache() 清除缓存
close flush

二级缓存使用步骤

1、框架支持二级缓存 核心配置文件中设置
在这里插入图片描述

<settings>
        <setting name="cacheEnabled" value="true"/>
</settings>

2、让当前的映射文件支持二级缓存
在这里插入图片描述

<!--开启二级缓存的支持 针对mapper文件-->
<cache></cache><cache/>都可以

3、让当前操作支持二级缓存 select
在这里插入图片描述

<!-- 根据id查询所有 -->
    <select id="findById" resultType="User" parameterType="Integer" useCache="true">
        select * from user where id = #{uid}
    </select>
useCache="true" 开启映射文件的二级缓存

注意:如果不使用二级缓存,那么针对每次查询都需要从数据获取的最新数据(useCache=“false”)

问题:二级缓存对象不一致?
解决:存在二级缓存时,所缓存的类要求一定要实现Serializable接口 网络通讯序列化方式保存对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值