Mybatis

目录

ORM思想

常规JDBC的弊端

Mybatis

Mybatis特点

Mybatis入门案例

导入jar包

编辑POJO对象

编写xml形式的核心配置文件

编写持久层mapper的接口

编写接口实现类的xml形式的映射文件

核心配置文件中配置mybatis关联的映射文件

编写测试类进行测试

Mybatis调用流程

根据ID查询数据

编写业务接口

编辑xml映射文件

编辑测试API

mybatis入门操作

简化Mybatis操作

@BeforeEach注解说明

mybatis参数封装说明

报错说明:

常见封装策略

测试案例:

参数知识点总结:

#号和$符用法

规则说明

案例实现

Mybatis 常规CURD操作

新增、删除、更改操作

编写测试方法

编写业务接口

编写xml文件

总结

Mybatis中的转义标签

xml转义语法

编写测试方法

编写业务接口

编写xml文件

Mybatis集合用法--批量

需求分析

封装方式

编写测试方法

编写业务接口

编写xml文件

总结:

模糊查询说明

Mybatis的优化设置

Mybatis的核心配置文件是有顺序的

Mybatis的简化---别名

Mybatis的简化---SQL标签

Mybatis优化之开启驼峰映射规则

Mybatis之动态sql

IF-WHERE用法

动态sql----SET标签

动态Sql-choose when otherwise

resultType和resultMap用法

标签说明

编辑测试类

编辑接口

编辑xml映射文件

resultType的返回类型

对象类型

简单类型

Map类型

关联关系

常见的关联关系

一对一

一对多

Mybatis的缓存机制

什么是缓存机制

一级缓存

二级缓存


ORM思想

对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换

  • 概括: 用对象的方式操作数据库

  • 衍生:

    1. 对象应该与数据库中的表一一映射.

    2. 对象中的属性应该与表中的字段一一映射.

    3. 其中的映射应该由程序自动完成.无需人为干预.

常规JDBC的弊端

//利用jdbc,完成新增的功能
    private static void method2() throws Exception{
        //1,注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2,获取数据库的连接
        //数据传输协议   数据库的ip 端口号 数据库名
        String url = "jdbc:mysql://localhost:3306/cgb2107";
        Connection c = DriverManager.getConnection(url,"root","root");
        //3,获取传输器
        Statement s = c.createStatement();
        //4,利用传输器执行  增删改的SQL
        //executeUpdate()用来执行增删改的SQL,只返回影响行数
        int rows = s.executeUpdate(
                "INSERT INTO emp(ename,job) VALUES('rose','副总')");
        //5,释放资源
        //r.close();//结果集
        s.close();//传输器
        c.close();//连接
    }
  • 弊端

    1. 无论如何执行都必须获取数据库链接。 链接池: c3p0 druid HK链接池

    2. 操作sql语句时,步骤繁琐. 不便于学习记忆.

    3. 资源必须手动关闭.

  • 优点

    1. 操作数据库最快的方式就是JDBC. 协议 TCP

引出:

Mybatis

  1. MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射

  2. MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。(mybatis在内部将JDBC封装).

  3. MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

知识整理:

  1. 持久化:计算机在计算时,数据都在内存中.如果断电则数据清空,所以要求将内存数据保存到磁盘中. 概念.

  2. 持久层:程序通过Dao/Mapper 与数据库进行交互的层级代码 (Controller层 Service层 Dao/Mapper层) 具体操作.

小结: Mybatis是一个优秀的持久层框架,基于ORM设计思想,实现了以对象的方式操作数据库.

了解:Mybatis的ORM并不完全,只完成了结果集映射,但是Sql需要自己手写.所以也称之为半自动化的ORM映射框架.

Mybatis特点

  1. 简单易学

  2. 灵活

  3. 解除sql与程序代码的耦合

  4. 提供映射标签,支持对象与数据库的orm字段关系映射

  5. 提供对象关系映射标签,支持对象关系组建维护

  6. 提供xml标签,支持编写动态sql

Mybatis入门案例

准备资源:

导入jar包

 
        
            org.projectlombok
            lombok
        
​
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.0
        
​
        
        
            mysql
            mysql-connector-java
        

编辑POJO对象

package com.jt.pojo;
​
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
​
import java.io.Serializable;
​
@Data//1.实现get/set/...方法
@Accessors(chain = true)//2.链式加载--->设置值
@NoArgsConstructor//3.无参构造
@AllArgsConstructor//4.有参构造
public class DemoUser implements Serializable{//5.实现序列化
        private Integer id;
        private String name;
        private Integer age;
        private String sex;
​
}

编写xml形式的核心配置文件





​
    
    
​
        
        
            
            
            
            
                
                
                
                
                
            
        
    
​
    
    
        
    

编写持久层mapper的接口

package com.jt.mapper;
​
import com.jt.pojo.DemoUser;
​
import java.util.List;
​
/**
 *  说明:
 *      1.根据面向接口开发思想需要定义一个Mapper接口
 *      2.在接口中可以写方法,谁调用谁实现
 *      3.Mybatis中的实现类以xml文件形式存在
 */
public interface DemoUserMapper {
    //查询所有的User列表信息
    List findAll();
​
    DemoUser findOne(int id);
}

编写接口实现类的xml形式的映射文件



​
    
    

    

核心配置文件中配置mybatis关联的映射文件

    
    
        
    

编写测试类进行测试

package com.jt;
​
import com.jt.mapper.DemoUserMapper;
import com.jt.pojo.DemoUser;
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.jupiter.api.Test;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
public class TestMybatis {
​
    @Test
    public void testDemo1() throws IOException {
        /*创建SqlSessionFactory*/
        //指定配置文件地址
        String resource = "mybatis/mybatis-config.xml";
        //通过IO流 加载指定的配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //动态生成SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​
        /*从SqlSessionFactory中获取sqlSession 类比  数据库链接*/
        SqlSession sqlSession = sqlSessionFactory.openSession();
​
        /*获取mapper接口,执行接口方法*/
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        //获取数据
        List userList = demoUserMapper.findAll();
        System.out.println(userList);
        //关闭流
        sqlSession.close();
    }
    
    @Test
    public void findOne() throws IOException {
        String resource = "mybatis/mybatis-config.xml";
        //通过IO流 加载指定的配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //动态生成SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
​
        //获取接口
        DemoUserMapper mapper = sqlSession.getMapper(DemoUserMapper.class);
        int id=1;
        DemoUser demoUser = mapper.findOne(id);
        System.out.println(demoUser);
        sqlSession.close();
​
    }
​
}

Mybatis调用流程

根据ID查询数据

在入门案例中已经实现了,这里分离出来

编写业务接口

public interface DemoUserMapper {    //1.查询所有的表数据    public List findAll();    DemoUser findOne(int id);}

编辑xml映射文件

     

编辑测试API

/***     *  需求: 根据ID查询数据库记录   id=1的数据     */    @Test    public void testFindOne() throws IOException {        //指定配置文件地址        String resource = "mybatis/mybatis-config.xml";        //通过IO流 加载指定的配置文件        InputStream inputStream = Resources.getResourceAsStream(resource);        //动态生成SqlSessionFactory        SqlSessionFactory sqlSessionFactory =                new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        //获取接口        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);        int id = 1;        DemoUser demoUser = demoUserMapper.findOne(id);        System.out.println(demoUser);        //关闭链接        sqlSession.close();    }

mybatis入门操作

简化Mybatis操作

public class TestMybatis2 {
    //定义公共的属性
    private SqlSessionFactory sqlSessionFactory;
    @BeforeEach
    public void init() throws IOException {
        String resources = "mybatis/mybatis-config.xml";
        InputStream inputStream =Resources.getResourceAsStream(resources);
         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMybatis(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        List list = demoUserMapper.findAll();
        System.out.println(list);
        sqlSession.close();
    }

@BeforeEach注解说明

该注解的作用是在执行@Test方法前调用. 是测试方法提供的测试API

mybatis参数封装说明

报错说明:

  • 规则:

    1. mybatis如果遇到多值传参时,默认条件是采用下标的方式获取数据.

    2. mybatis天生只支持单值传参,如果遇到多值的问题,则应该将多值封装为单值.

常见封装策略

  1. 封装为实体对象

  2. 更为常用方式:Map集合

  3. 如果传递的数据有多个,使用注解 @Param 封装为Map集合

    使用方式: List findSA3(@Param("sex") String sex, @Param("age") int age);

测试案例:

编写测试方法

 //1.封装为实体对象
    @Test
    public void find1(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        //编程思想:面向对象
        DemoUser csc = new DemoUser();
        csc.setAge(18).setSex("女");
        List list = demoUserMapper.findSA(csc);
        System.out.println(list);
        sqlSession.close();
    }
    //2.封装为Map集合
    @Test
    public void find2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        Map map = new HashMap<>();
        map.put("sex", "女");
        map.put("age", 18);
        List list = demoUserMapper.findSA2(map);
        System.out.println(list);
        sqlSession.close();
    }
    //3.使用注解@Param封装
    @Test
    public void find3(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        String sex = "女";
        int age = 18;
        List list = demoUserMapper.findSA3(sex,age);
        System.out.println(list);
        sqlSession.close();
    }

编写业务接口

public interface DemoUserMapper {
    List findSA(DemoUser csc);
    List findSA2(Map map);
    //利用注解@Param将参数封装为Map集合
    List findSA3(@Param("sex") String sex, @Param("age") int age);
   }

编写xml映射文件

 
    

    
    

    
    

参数知识点总结:

  1. 如果参数采用对象封装,则可以使用#{属性}取值.

  2. 如果参数有多个,可以封装为map实现参数的传递. 可以利用#{key}获取数据

  3. 也可以使用@Param将多个参数封装为map, 利用#{key}的方式获取数据

#号和$符用法

规则说明

  1. 使用#{} 获取数据时,默认有预编译的效果.防止sql注入攻击.

  2. mybatis使用#{}获取数据时,默认为数据添加一对""号.

  3. 当以字段名称为参数时,一般使用${},但是这样的sql慎用. 可能出现sql注入攻击问题.

注意:一般条件下,能用#{},尽量不用${}

案例实现

编写测试方法

/**
     *需求:按照指定的age排序
     *  sql:select * from demo_user order by age
     *  #号 与 $符用法:
     *
     */
    @Test
    public void testFindOrder(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        String csc = "age";
        List list = demoUserMapper.findFO(csc);
        System.out.println(list);
        sqlSession.close();
    }

编写业务接口

public interface DemoUserMapper {
List findFO(String csc);
    }

编写xml文件

   

Mybatis 常规CURD操作

新增、删除、更改操作

编写测试方法

 /**
     * 需求:实现用户入库的操作
     */
    @Test
    public void saveUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        DemoUser demoUser = new DemoUser(null,"常世超",18,"女" );
        int rows= demoUserMapper.saveUser(demoUser);
        if(rows>0){
            System.out.println("影响的行数"+rows);
            sqlSession.commit();
        }

        sqlSession.close();
    }

    /**
     * 作业:
     *      1.把id=1的数据 name 改为 "守山大使"   age=5000
     *      2.将name="常世超"的数据 删除
     */
    @Test
    public void updateUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        DemoUser demoUser = new DemoUser(1, "守山大使", 5000, "");
        int rows = demoUserMapper.updateUser(demoUser);
        if(rows>0){
            System.out.println("影响行数"+rows);
            sqlSession.commit();
        }
        sqlSession.close();
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        String name = "常世超";
        demoUserMapper.deleteUser(name);
        System.out.println("删除成功");
        sqlSession.close();
    }

编写业务接口

public interface DemoUserMapper {  
	int saveUser(DemoUser demoUser);
    int updateUser(DemoUser demoUser);
   	void deleteUser(String name);
}

编写xml文件

    
        insert into demo_user value (null ,#{name} ,#{age},#{sex})
    

    
        update demo_user set name = #{name} ,age = #{age} where id =#{id}
    

    
        delete from demo_user where name =#{name}
    

总结

  1. 编写删除、更改、新增操作时,需要提交事务---》mybatis会自动回滚事务

  2. 提交事务的两种方式:

    1. SqlSession sqlSession = sqlSessionFactory.openSession(true);

    2. sqlSession.commit();

Mybatis中的转义标签

xml转义语法

xml文件中的转义字符:
        >  > 大于
        <  < 小于
        &  & 号
    说明:如果sql中有大量的转义字符 建议使用转义标签体
    语法: 

编写测试方法

 /**
     * 需求: 查询age> 18 and age< 100 的用户信息.
     * 规则: 如果不能使用对象封装,则一般使用Map集合
     */
    @Test
    public void testSelect01(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        Map map = new HashMap<>();
        map.put("minAge",18);
        map.put("maxAge",100);
        List userList = demoUserMapper.findByAge(map);
        System.out.println(userList);
        sqlSession.close();
    }

编写业务接口

public interface DemoUserMapper {
    List findByAge(HashMap map);
}

编写xml文件

Mybatis集合用法--批量

需求分析

  • 要求批量的删除数据库中的记录.

  • 规则: 如果遇到相同的多个数据,则一般采用集合的方式封装数据

封装方式

  1. array

  2. list

  3. map

编写测试方法

 //1.array封装
    @Test
    public void deleteIds(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        int[] ids = {231,232,233};
        demoUserMapper.deleteIds(ids);
        System.out.println("删除操作成功");
        sqlSession.close();
    }
    //2.list封装
    @Test
    public void deleteList(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        List list = new ArrayList();
        list.add(231);
        list.add(232);
        list.add(233);
        demoUserMapper.deleteList(list);
        System.out.println("删除操作成功");
        sqlSession.close();
    }
    //3.map封装
    @Test
    public void deleteMap(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        List list = new ArrayList();
        list.add(231);
        list.add(232);
        list.add(233);
        Map map = new HashMap();
        map.put("ids", list);
        demoUserMapper.deleteMap(map);
        System.out.println("删除操作成功");
        sqlSession.close();
    }

编写业务接口

public interface DemoUserMapper {    
	void deleteIds(int[] ids);
    void deleteList(List list);
 	void deleteMap(Map map);
}

编写xml文件

   
        delete from demo_user where id in
        
            #{id}
        
    

    
        delete from demo_user where id in
        
            #{id}
        
    

    
        delete from demo_user where id in
        
            #{id}
        
    

总结:

批量删除数据
难点:如果使用#{集合}获取的是集合的对象,删除无效
思路:将数组拆分为单个数据===》通过遍历数组的方式获取
语法:mybatis中为了遍历方便,提供了遍历的标签 ===》foreach
    关于标签参数的说明:
        1.collection
            1).如果参数传参为数组,       则collection="array"
            2).如果参数传参为list集合,   则collection="list"
            3).如果参数传参为map集合,    则collection="map集合中的key值"
    关于标签属性的说明:
        1.collection    集合的名称
        2.item          每次遍历的数据的性参变量
        3.open          循环开始的标签
        4.close         循环结束的标签
        5.separator     循环遍历的分割符
        6.index         循环遍历下标

模糊查询说明

需求: 查询name中包含"精"的数据.并且按照年龄降序排列

  1. 在传参为:String = "%精%"

  2. 在SQL语句中:select * from demo_user where name like "%"#{name}"%"

Mybatis的优化设置

Mybatis的核心配置文件是有顺序的

顺序为:

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".

Mybatis的简化---别名

  1. 别名标签

  2. 别名包

  3. 使用注解定义别名

别名标签

位置:核心配置文件中

说明:只对某个类生效


    

别名包

位置:核心配置文件中

说明:对包下的所有对象类生效


    

使用注解

位置:POJO类上

说明:只对某个类生效

@Alias("DemoUser")--->起别名
public class DemoUser implements Serializable{//5.实现序列化
        private Integer id;
        private String name;
        private Integer age;
        private String sex;
}

Mybatis的简化---SQL标签

说明

mybatis的xml映射文件中会有大量的Sql语句. 随着业务的增加,Sql语句的数量也会增加. 其中有部分"Sql片段"则可能重复. 如果想简化Sql语句,则可以使用Sql标签简化操作.

例子:

select id,name,age,sex from demo_user where id = 1
select id,name,age,sex from demo_user where name = xxx

sql标签的用法

    

         select id,name,age,sex from demo_user




    

sql标签的优点和缺点

优点:

  1. 使用Sql标签可以节省xml的文件大小.

  2. 代码的结构相对简单.

缺点:

  1. Sql只能抽取公共的Sql语句,局限性稍大.

  2. 如果大量的使用Sql标签,则代码的可读性差

Mybatis优化之开启驼峰映射规则

说明:

在mybatis映射数据时,经常出现字段名称与属性名称不一致的现象. 但是其中一部分可以采用驼峰规则的方式完成自动映射. 所以有如下的配置

编写xml核心配置文件

位置:核心配置文件中configuration配置标签之下

 
    
        
        
    

Mybatis之动态sql

IF-WHERE用法

需求:根据user对象查询数据.要求根据对象中不为null的属性充当where条件.实现动态的查询

解释:

用户可以根据用户名查询数据、也可以根据用户名+身份证号查询数据、也可以跟据3个条件查询

编辑测试方法

    /**
     * 封装DemoUser的对象,根据对象中不为null的属性查询
     */
    @Test
    public void testWhere(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        DemoUser demoUser = new DemoUser();
        demoUser.setName("金角大王")
                .setAge(3000)
                .setSex("男");
       List list = demoUserMapper.findWhere(demoUser);
        System.out.println(list);
        sqlSession.close();
    }

编辑接口

public interface DemoUserMapper {
    List findWhere(DemoUser demoUser);
}

编辑xml映射文件

    
    

动态sql----SET标签

说明:根据对象不为null的属性当做set条件

编辑测试方法

    /**
     * 根据ID,动态的实现数据的更新
     */
    @Test
    public void testUpdateSet(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        DemoUser demoUser = new DemoUser();
        demoUser.setName("黑黑")
                .setId(1)
                .setSex("女")
                .setAge(10000);
         demoUserMapper.findUpdateSet(demoUser);
        System.out.println("修改成功");
        sqlSession.close();
    }

编辑接口

public interface DemoUserMapper {
        void findUpdateSet(DemoUser demoUser);
}

编辑xml文件


    
        update demo_user
                
                    name = #{name},
                    age = #{age},
                    sex = #{sex}
                
                where
                    id = #{id};
    

动态Sql-choose when otherwise

需求:

根据条件实现数据的查询. 如果存在name则按照name查询,否则按照sex查询.
补充说明:
条件: name = “张三” , sex=“男”
select * from demo_user where name = #{name}

编写测试类

 /**
     * 需求:如果存在name则按照name查询,否则按照sex查询
     */
    @Test
    public void testSelectChoose(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        DemoUser demoUser = new DemoUser();
        demoUser.setName("白骨精").setSex("女");
        List list = demoUserMapper.findChoose(demoUser);
        System.out.println(list);
        sqlSession.close();
    }

编写接口

public interface DemoUserMapper {
    List findChoose(DemoUser demoUser);
}

编写xml映射文件


    

resultType和resultMap用法

标签说明

resultType说明: 当结果集中的字段名称,如果与属性的名称一致时,才会实现自动的数据封装

resultMap说明: 当结果集中的字段名称,与对象中的属性不一致时,可以使用resultMap实现自定义的封装

编辑测试类

@Test
    public void testFindDept(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
        List list = deptMapper.findAll();
        System.out.println(list);
        sqlSession.close();
    }

编辑接口

public interface DemoUserMapper {
    List findAll();
}

编辑xml映射文件


    

    
        
        
    

resultType的返回类型

对象类型

  • 接口的返回值是对象

  • 接口返回值是list集合,mybatis会把student对象放入list集合中

  • resultType 指定查询数据封装到那个对象中

定义接口

Student selectById(Integer id );

编辑xml映射文件



简单类型

  • xml文件中执行sql语句,得到的一个值(一行一列)

  • resultType 需要指定java.long包下的数据类型

定义接口

public interface DemoUserMapper {
   long  countStudent();
}

编辑xml映射文件

Map类型

  • 执行sql语句得到的是一个Map结构数据,Mybatis执行sql,把ResultSet转为map

    sql执行结果, 列名做map的key,列值做value

    sql执行得到的是一行记录,转为map结构是正确的

    dao接口返回是一个map,sql语句最多能获取一行记录,多余一行是错误的

  • resultType 需要指定java.util.HashMap

定义接口

//查询结构返回是一个map
public interface DemoUserMapper {
  Map selectMap(Integer id);
}

编辑xml映射文件

关联关系

常见的关联关系

  1. 一对一

  2. 一对多

  3. 多对多

一对一

规则:使用对象封装

关联查询实现一对一查询

编写测试类

  /**
     * 完成一对一映射
     * 规定:一个员工对应一个部门
     * 选取方向:员工方
     * 需求:需要在员工中,完成部门的封装
     */
    @Test
    public void testOneToOne(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List list = empMapper.findAll();
        System.out.println(list);
        sqlSession.close();
    }

编写接口

public interface EmpMapper {
    List findAll();
    }

编写xml映射文件



    
        

        
            
            
        
    

子查询实现一对一查询

编写测试类

    @Test
    public void testOneToOne2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List list = empMapper.findAllWhere();
        System.out.println(list);
        sqlSession.close();
    }

编写接口

    List findAllWhere();

编写xml映射文件


    
        
        
    
    
    
        
        
    

关联查询与子查询的区别

一对多

编写测试文件

    @Test
    public void testOneToMore(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DeptMapper deptMapper= sqlSession.getMapper(DeptMapper.class);
        List list = deptMapper.findDept();
        System.out.println(list);
        sqlSession.close();
    }

编写接口

List findDept();

编写xml文件


    
    
        

        
            
        
    

Mybatis的缓存机制

什么是缓存机制

  • 引入缓存可以有效降低用户访问物理设备的频次.提高用户响应速度.

  • 扩展: 1.mybatis自身缓存 一级缓存/二级缓存 2.Redis缓存 读取10万次/秒, 写 8.6万次/秒

一级缓存

概念说明: Mybatis默认开启一级缓存, 一级缓存可以在同一个SqlSession对象中查询相同的数据,可以实现数据的共享(缓存操作).

缓存测试

    /**
     * Mybatis一级缓存:默认开启
     *          规则:同一个SqlSession内部有效
     *                不同的SqlSession内部无效
     *          测试:
     *              看sql执行几次
     *              执行一次有缓存
     */
    @Test
    public void cache1(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List list1 = empMapper.findAll();
        List list2 = empMapper.findAll();
        List list3 = empMapper.findAll();
        System.out.println(list1==list2);
        sqlSession.close();
    }

二级缓存

说明: 二级缓存mybatis中默认也是开启的.但是需要手动标识. 二级缓存可以在同一个SqlSessionFactory内部有效.

注:要启动全局的二级缓存,需要在其SQL映射文件中添加

缓存测试

    /**
     * 二级缓存说明:
     *      SqlSession查询数据之后,会将缓存信息保存到一级缓存中,但是不会立即将数据交给二级缓存保存
     *      如果需要使用二级缓存,则必须将SqlSession业务逻辑执行成功之后,再关闭
     */
    @Test
    public void cache2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        empMapper.findAll();
        sqlSession.close();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);
        empMapper2.findAll();
        sqlSession2.close();
    }

你可能感兴趣的:(Java,mybatis,java,数据库)