Spring boot Mybatis面试题

一、JDBC存在的问题

1.1 JDBC存在的问题

  • 硬编码问题:数据库的驱动名、数据库的URL、数据库的用户名、数据的密码等存在硬编码

解决方案:将数据库驱动名、数据库URL、数据库用户名、密码配置在xml|properties

  • sql语句存在硬编码、占位符索引存在硬编码、占位符值存在硬编码

解决方案:sql语句写在xml文件、占位符的索引自动分配、占位符的值可以根据索引进行自动绑定。

*查询结果的列名存在硬编码、对象需要自己创建、对象的属性需要自己赋值、需要手工将对象添加至列名。

解决方案:查询结果的列名可以配置在xml文件中、对象可以自动创建、对象的属性值可以自动绑定、对象自动添加到列表中去。

二、Mybatis

2.1 Mybatis是什么

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

2.2 工作原理

  • 全局配置文件配置了数据源,事务等mybatis运行环境
  • SqlSessionFactory创建SqlSession对象
  • SqlSession提供了操作数据库的方法
  • Excutor执行器·,真正负责处理数据库操作
  • MappedStatement 封装输入参数类型,封装输出结果类型,sql语句
  • DB数据库

2.3 #{}和${}的区别

#{}相当于占位符${}相当于字符串拼接符
#{}解决了sql注入${}存在sql注入

${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中
#{} 在动态解析的时候,会解析成一个参数标记符。
#{}将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

2.4 xml中特殊字符处理

在这里插入图片描述

三、缓存机制

3.1 目的

缓存目的是为了减少对数据库的访问次数,提升数据库的执行效率。
mybatis缓存机制包括:1.一级缓存 2.二级缓存

3.2 一级缓存

一级缓存也叫sqlSession级别的缓存 ,也就是在同一个sqlSession内执行两次多次相同结果的查询语句,只会在第一次时发出sql查询数据库的数据,然后之后每次从一级缓存中查询数据返回。

3.2 清除一级缓存

  • 如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前SqlSession缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
  • 当一个SqlSession结束后那么他里面的一级缓存也就不存在了

3.3 二级缓存

二级缓存是mapper级别的缓存,也就是同一个namespace的mappe.xml,当多个SqlSession使用同一个Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域

3.4 清除二级缓存

  • 如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前mapper缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读

3.5 使用缓存过程

  • 当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存
  • 当另一个sqlsession执行select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能

3.6 验证一级缓存

在这里插入图片描述

四、面试题

参考:https://www.cnblogs.com/aishangJava/p/10526957.html

五、Spring Boot整合mybatis

5.1 需要的依赖

 <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
 </dependency>

5.2 数据库配置

spring:
  datasource:
    password: 123
    username: root
    url: jdbc:mysql://localhost:3306/stus

5.3 编写department类

public class Department {
    private Integer id;
    private String departmentName;

    public Department() {
    }

    public Department(Integer id, String departmentName) {
        this.id = id;
        this.departmentName = departmentName;
    }

    public Integer getId() {
        return id;
    }

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

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
}

5.4 mapper类

@Mapper
public interface DepartmentMapper {
    @Select("select * from department where id = #{id}")
    public Department Select();
    @Delete("delete form department where id = #{id}")
    public void delete();
    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public void update();
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public void insert(Department department);
}

5.5 Controller测试

@Controller
@ResponseBody
public class departmentController {
    @Autowired
    DepartmentMapper mapper;
    @GetMapping("/dept/{id}")
    public Department getDepartment(@PathVariable("id") Integer id){
        return mapper.Select();
    }
    @GetMapping("/dept")
    public Department insert(Department department){
       mapper.insert(department);
       return department;
    }
}

5.5 总结

  • 从url获取如id参数,配置是:
GetMapping("/dept/{id}")

不需要加#号

  • insert语句,表名称后面一定要加入插入的属性名
insert into department(departmentName) values(#{departmentName})
  • 如果要得到自增的主键的值,需要在mapper中加入如下的注解,useGeneratedKeys 为true代表使用自增的主键的值,keyProperty 告诉哪个属性是主键
  @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public void insert(Department department);
  • 今天出错的原因是GetMapping(“/dept/{id}”),id前加了#,自动创建数据库的配置未注释。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值