mybatis的知识点总结

Mybatis 是一个对数据库进行操作的 ORM 框架,主要是封装提供灵活的增删改查sql,开发中,service层能够通过mybatis组件查询和修改数据库中表的数据;作为查询工具,mybatis有使用缓存,当我们从数据库中查询过的数据,会存入缓存,当我们进行二次查询时,就不需要重新链接数据库进行二次查询,缓存的生命周期创建的会话。

什么是ORM框架

  1. 首先ORM是对象关系映射,作用是实现java对象和数据库表的自动转换,屏蔽原生SQL,用面向对象的方式操作数据库。
  2. 核心映射关系
  • 实体类(emp)<->数据库表
  • 类的成员属性<->表的字段(列)
  • 类的对象实例<->表的一行数据
  1. 核心思想
  • 不用大量手写sql,通过操作对象,由框架自动生成,执行sql,完成增删改查。

Mybatis的环境搭建

  1. 导入maven依赖
xml 复制代码
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.19</version>
</dependency>
  1. 编写实体类(实体类的属性名要和数据库的字段名对应)
  2. 编写Mapper接口,例如
python 复制代码
@Select("select * from emp where empno=#{id}")
emp findAll(int id);
  1. 编写Mybatis核心配置文件(config.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>
    <settings>
        <!--输出日志到控制台中-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--分别书写驱动类、网址、账号和密码 注意网址中&使用&amp;代替-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/book_21"/>
                <property name="username" value="root"/>
                <property name="password" value="LQYOW2580"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--引入的资源文件-->
        <package name="org.example.mybatis.m5.mapper"/>

    </mappers>
</configuration>

5.编写Mapper Xml映射文件

xml 复制代码
<?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="org.example.mybatis.m1.mapper.informationMapper">//这个是你当前映射文件的路径

<!--
代表一个查询方法
 id:方法名(必须和Mapper接口全类名完全一致)
 resultType:返回类型路径
 parameterType:参数类型,没有就删掉
-->
<select id="findAll" resultType="org.example.mybatis.m1.bean.information">
<!--这里是Sql-->
    select * from information
</select>

利用注解的方式

  1. 依赖,实体类,配置文件这些和XML完全一样,不用改,只有一处要改,config.xml的,改成扫包注册接口:
ini 复制代码
<package name="org.example.mybatis.m2.mapper"/>

2。注解版Mapper接口,举个全查询例子

less 复制代码
@Select("select * from emp")//注解
List<emp> findAll();

3.最常考,最常用的一个:主键回填,新增时想插入后自动把数据库生成id赋给java对象

less 复制代码
  @Options(useGeneratedKeys=ture,keyProperty="id")  
    直接加在@insert下面就行
  1. 测试类,直接复制粘贴
ini 复制代码
    
//加载配置文件
InputStream resourceAsStream = Main.class.getClassLoader().getResourceAsStream("config.xml");
//创建会话工厂
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
//创建会话
SqlSession sqlSession = build.openSession();
// 获取到对象
empMapper mapper = sqlSession.getMapper(empMapper.class);

mybatis的参数问题

在mybatis中,接口传递参数到xml或者注解的形式,主要分为单参数,多参数,特殊参数(Map)三种情况

1.单参数
  • mybatis对单参数没有限制,直接通过#{}或${}(这个时拼接具体区别请看别的文章)
java 复制代码
//单个参数问题
@Select("select * from emp where empno=#{id}")//#{}输出对应占位符
emp findEmpById(int id);
@Select("select * from emp where empno=${id}")//${}直接把参数拼接上去
emp findEmpById1(int id);
//单个参数时,名称可以不对应
@Select("select * from emp where empno=#{abc}")
emp findEmpById2(int id);   
2多参数问题.
复制代码
  当方法传入多个参数的时候,mybatis会自动进行封装,不能注解使用参数名,必须使用指定别名
  • 解决方案:使用@Param注解--这是最优雅的方式,通过注解给参数起别名
less 复制代码
@Select("select * from emp where ename like #{name} and job=#{job}")
List<emp> findEmp3(@Param("name") String name, @Param("job") String job);
  1. 数据库表中的列和对象的属性名不一致时
  2. 方案1:给数据库字段起个别名,让其和java属性相等
python 复制代码
@Select("select e.*,job as 'job1'from emp e where empno=#{id}")
emp find1(int id);

3方案二. //解决方案2--让数据库名等于Java名

less 复制代码
    
@Select("select * from emp where empno=#{id}")
    ```
@Results(
        @Result(column = "job",property = "job1")
)
emp find2(int id);
映射
  • 映射是指将数据库查询的结果集转换成java对象的过程
  1. 自动映射
  • 前提条件:数据库字段名和java实体类属性名一致
  • 使用场景:简单的单表查询,字段名差异不大

2.手动映射

  • 当字段名与属性完全不一致,或者需要多表查询,例多表查询:
less 复制代码
@Select("select * from emp where empno=#{empno}")
  @Results(
          /*
          column:将数据库查出来的列赋给property
          propery:代表bean包中的某一个属性
           */
          value = {
                  @Result(column = "empno", property = "empNo", id = true),
                  //非主键
                  @Result(column = "ename", property = "ename", javaType = String.class),
                  @Result(column = "deptno",
                  property = "dept",javaType = dept.class,
                          one = @One(select = "org.example.mybatis.m3.mapper.DeptMapper.findDeptById")
                  )
          }
  )
emp findEmpById(int empno);
  • 在另一个类中写查找dept的方法
java 复制代码
@Select("select * from dept where deptno=#{deptNo}")
dept findDeptById(int deptNo)

   

这就是多表查询,多对一的例子,一对多同理,将One改成Many

mysql动态sql--用xml方便,利用注解很麻烦

  • 动态sql核心作用是根据不同条件动态生成不同的sql语句
  • 核心标签详解:
  1. <if 标签:条件判断--这里id必须和接口中方法名一致
bash 复制代码
 <select id="find1" resultType="org.example.mybatis.m4.bean.emp">
    select * from emp
    <if test="ename!=null">
        where ename like #{ename}
    </if>
</select>

2.类似if-else标签《choose>《when>《otherwise>

ini 复制代码
   
<choose>
    <when test="sal>3000">
        where job='程序员'
    </when>
    <when test="sal>6000">
        where job='网页设计'
    </when>
    <otherwise>
        where job='歌手'
    </otherwise>
</choose>

3.《where>标签:自动处理where子句:

xml 复制代码
  
select * from emp
    <where>
        <if test="job!=null">
            job=#{job}
        </if>
        <if test="sal!=null">
            and sal>#{sal}
        </if>
    </where>
    <!--第二种方式-->
    <trim prefix="where" suffixOverrides="and|or">
        <if test="job!=null">
            job=#{job}
        </if>
        <if test="sal!=null">
            and sal>#{sal}
        </if>
    </trim>

</select>

4.《foreach>标签:遍历集合

typescript 复制代码
   
//集合必须加Pararm,起名字,或者用默认名"collection"
List<emp> find5( @Param("job") List<String> job);

select * from emp
    <where>
        <if test="job!=null">
            job in
            <!--
           for(String ab:job)
            -->
            <foreach collection=" job" open="(" close=")" separator="," item="ab">
                #{ab}
            </foreach>
        </if>
    </where>
</select>

5.《set>标签,动态更新

bash 复制代码
 update emp
    <set>
        <if test="ename!=null">
            ename=#{ename},
        </if>

        <if test="job!=null">
            job=#{job},
        </if>

        <if test="mgr!=null">
            mgr=#{mgr},
        </if>
    </set>
    where empno=#{empNo}
</update>

5.《bind> 模糊查询

csharp 复制代码
<bind name="abc" value="'%' + _parameter.getEname() + '%'"/>
select *
from emp
where ename like #{abc}

缓存问题

  • 缓存是将频繁查询,不常修改的数据存储到数据存储在内存的技术 第一次查询:从数据库中查询数据,存入缓存
  • 后续查询相同内容,直接从缓存中取数据,无需访问数据库

1.一级缓存(sqlsession级别,默认开启)

  • 作用域也可以说缓存的生命周期:同一个sqlSession内有效,sqlsession关闭后清空
缓存失效场景:

1.执行insert,delete,update操作(会清空当前sqlsession的一级缓存)

2.手动调用sqlsession.clearCache()清空缓存 3.不同sqlsession之间不共享

ini 复制代码
    // 同一个SqlSession,两次查询,第二次命中一级缓存
try (SqlSession sqlSession = MyBatisUtils.getSqlSession(true)) {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user1 = mapper.selectUserById(1); // 第一次:查数据库
    User user2 = mapper.selectUserById(1); // 第二次:命中缓存,不查数据库
    System.out.println(user1 == user2); // true(同一个对象)
}

二级缓存

-作用域:全局共享

-默认关闭,要手动开启

  • 开启缓存的步骤在config.xml中配置
xml 复制代码
 <!--开启全局二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>
相关推荐
小江的记录本17 小时前
【注解】常见 Java 注解系统性知识体系总结(附《全方位对比表》+ 思维导图)
java·前端·spring boot·后端·spring·mybatis·web
小飞Coding17 小时前
MyBatis Mapper 实现原理彻底解密——从动态代理到 JDBC 执行全链路剖析
后端·mybatis
华科易迅21 小时前
MybatisPlus乐观锁
java·开发语言·mybatis
野犬寒鸦1 天前
Redis复习记录Day03
服务器·redis·后端·面试·bootstrap·mybatis
爱丽_1 天前
MyBatis 性能优化:批处理、分页、缓存与慢 SQL 定位
缓存·性能优化·mybatis
PacosonSWJTU2 天前
(转)mybatis拦截器
数据库·redis·mybatis
二等饼干~za8986682 天前
豆包GEO优化源码开发全解析:技术架构、实现逻辑与实操指南
数据库·sql·重构·架构·mybatis·音视频
星晨雪海2 天前
MyBatis-Plus 常用 CRUD 方法大全
linux·tomcat·mybatis
yangyanping201082 天前
广告系统设计二之RTA系统设计
java·spring·mybatis