首页 > 其他分享 >MyBatis

MyBatis

时间:2022-10-11 11:47:18浏览次数:37  
标签:xml mapper 缓存 Mybatis mybatis session MyBatis

Mybatis

作用

  • 是一款优秀的持久层框架 支持定制化的sql 存储过程以及高级映射

  • 之前我们学过的所有的JDBC代码和手动设置参数获取结果集 都不用写了

  • 使用简单的XML配置文件或者注解 来映射原生信息 更加的方便

 

持久化

持久化把数据存储在磁盘而不是内存

  1. 程序产生的数据首先都是在内存

  2. 内存不可靠 我们需要一些技术把数据永久存储在硬盘上

 

持久层

之前的Dao层 之前通过反射 通过泛型 通用的Dao 我们在操作不同的表或者逻辑的时候 我们之前会创建一个接口 在创建接口的实现类 实际上这个dao层 就叫持久层(让数据持久化的层)

 

优缺点

  • sql语句与代码分离 寄存于xml文件中(最牛X的特点)

    • 优点:便于维护管理 不用在java代码中找sql语句

    • 缺点:不能通过打断点的方式调试,通过日志来解决这个问题

  • 动态sql语句(最牛X的特点)

    • 优点:通过逻辑标签代替编写逻辑代码 生成不同的sql

    • 缺点:拼接一些比较复杂的sql语句时,没有直接拼接更直观

  • 查询结果和java对象自动映射

    • 优点:保证名称之间的对应关系 可以下划线和驼峰自动转换

    • 缺点:对开发人员的sql语句以来很强

 

XML配置文件

约束

保证我们的xml能够使用哪些标签 保证xml的有效性

 

主配置文件xml

外部配置文件

<properties resource="db.properties"></properties>

 <dataSource type="com.jsoft.datasource.DruidDataSourceFactory">
     <!-- 获取配置文件的值${key} -->
     <property name="druid.driverName" value="${druid.driverName}"/>
     <property name="druid.url" value="${druid.url}"/>
     <property name="druid.username" value="${druid.username}"/>
     <property name="druid.password" value="${druid.password}"/>
 </dataSource>

别名

<!--别名 给实体类起别名-->
<typeAliases>
   <!-- 给单个类起别名-->
   <typeAlias type="com.jsoft.entity.User" alias="user"></typeAlias>

   <!-- 当前包下的所有的实体类 都以类名的首字母小写来设置别名 -->
   <package name="com.jsoft.entity"/>

   <!-- 场景:当前包下的某个类不想以类名小写来当作别名   使用注解@Aliases-->
</typeAliases>
<?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 环境们 配置数据库连接相关 可以配置多个数据库连接-->
   <environments default="development">
       <environment id="development">
           <!--事务管理 -->
           <transactionManager type="JDBC"></transactionManager>
           <!-- 数据源配置 -->
           <dataSource type="POOLED">
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://127.0.0.1/lyh_db03?useUnicode=true&amp;characterEncoding=utf-8/>
               <property name="username" value="root"/>
               <property name="password" value="123"/>
           </dataSource>
       </environment>
   </environments>
</configuration>

另外一个xml

第一次使用Mybatis 需要两个文件

  • 一个接口类mapper(就是咱们之前写的dao)java文件 不需要我们写实现类

  • 一个接口对应一个xml文件

  • 两个文件的名字最好相同 UserMapper.java -> UserMapper.xml

  • 框架会根据mapper和xml联合 通过代理模式创建实现类

  • 一般情况下 我们管接口对应的xml的文件叫映射文件

 

sql语句传参规定

 

能只传一个对象 就只传一个对象

传多个参数时 不超过三个(效率低) 类型要相同 例如 都是封装类或集合 尽量不要传不同的类(效率太低)

 

如果传入的是User对象 在mapper.xml 映射文件中 就必须和对象的属性名匹配

如果传入的是Java内置的数据类型的参数 String,Integer。。

  • 如果只传入一个参数 直接使用#{参数名} #{param1} #{XXX}

  • 如果传入多个参数 必须使用#{param1} #{arg0} 不能用#{参数名}

     

原理:

Mybatis 在封装参数的时候 封装成了一个Map集合

  • 如果传入的是一个封装对象 例User value{“username” :“admin” , “password”:“123456”}

  • 如果传入的是一个内置类型的参数 字面量 【"xxx":"admin"】

  • 如果传入的是多个参数 【"param1":"admin"】,【"param2":"123456"】

    • 底层封装的map集合 arg0和arg1 起了个别名叫param1 param2

    • 如果用arg0 param1来命名 代码可读性极差

    • 使用别名 @Param ("命名") 传参

  • 如果传入的是集合 【"param1":"{1,2,3,4,5}"】

 

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<!--namespace: 对应mapper接口的全类名 -->
<mapper namespace="com.jsoft.dao.UserMapper">
   <!-- 写sql语句 -->
   <!--
       id mapper接口中的方法名
       resultType 方法的返回值类型 如果时entity类型 需要全类名
       parameterType   方法的入参的类型 可以省略
       #{id} 代表方法的入参 类似于之前的? 占位符   Mybatis底层使用的是什么? PreparedStatement
    -->
   <select id="selectUserById" resultType="com.jsoft.entity.User" parameterType="">
      select id,username,password from user where id = #{id}
   </select>
</mapper>

映射文件最终要交给mybatis去处理,所有的映射文件需要在主配置文件中进行注册。

<?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:环境们
    配置数据库连接相关。可以配置多个数据库连接
  -->
   <environments default="development">
       <environment id="development">
           <!-- 事务管理   -->
           <transactionManager type="JDBC"></transactionManager>
           <!-- 数据源配置 -->
           <dataSource type="POOLED">
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://127.0.0.1/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
               <property name="username" value="root"/>
               <property name="password" value="root"/>
           </dataSource>
       </environment>
   </environments>
   
<!-- 注册各个映射文件   -->
   <mappers>
       <mapper resource="mapper/UserMapper.xml"></mapper>
   </mappers>
   
</configuration>

 

测试类

可以将重复的语句 使用@Before @After 注释

@Before 在所有方法执行之前执行

@after 在所有方法执行之执行

public class UserMapperTest {
   SqlSession session;
   UserMapper mapper
       
   @Before
   public void before(){
       InputStream inputStream = UserMapperTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
       SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
       SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
       // 获取session
       session = sqlSessionFactory.openSession();
       //获取对应的mapper
       mapper = session.getMapper(UserMapper.class);
  }

   @After
   public void after(){
       try {
           session.commit();
           session.close();
      }catch(Exception e){
           e.printStackTrace();
           session.rollback();
      }
  }

   @Test
   public void testSelectUserById(){
       // 调接口里的方法
       User user = mapper.selectUserById(1);
       System.out.println(user);
  }
}

 

Mybatis有两种方式可以提交事务

1.通过session调用commit方法

2.关闭session

 

 

在Mybatis的映射文件中 $和#的区别?

$ 底层使用的是Statement 拼串

·#· 底层使用的时PrepareStatement 预编译 #相当于占位符

 

如果想要做模糊查询 在我们java代码层面去解决%问题

 

自定义数据源

<!--  引入外部的资源文件  -->
<properties resource="db.properties"/>


<environments default="development">
<environment id="development">
<!--   事务管理     -->
<transactionManager type="JDBC"/>
<!-- 数据源配置 -->
<!--
               type:
                   1、UNPOOLED:不使用连接池
                   2、POOLED:使用Mybatis默认的连接池
                   3、JNDI:使用JNDI实现的数据源
                   4、使用我们自定义的连接池实现,需要我们去写一个具体的实现类
             -->
<dataSource type="com.jsoft.datasource.DruidDataSourceFactory">
<!-- property标签中的name属性只需要按照druid的命名规则命名即可   -->
<property name="druid.driverName" value="${druid.driverName}"/>
<property name="druid.url" value="${druid.url}"/>
<property name="druid.username" value="${druid.username}"/>
<property name="druid.password" value="${druid.password}"/>
</dataSource>
</environment>
</environments>

 

别名处理

<typeAliases>
<!--   <typeAlias type="com.jsoft.entity.User" alias="user"></typeAlias> -->
<!--   当前包下的所有的实体类都是以类名的首字母小写来设置别名 -->
<!-- 场景:当前包下的某个类不想以类名小写来当做别名   -->
<package name="com.jsoft.entity"/>
</typeAliases>

 

Mybatis缓存

 

一级缓存最大的共享范围就是一个SqlSession内部

当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个共同的 cache,也就是二级缓存被多个 SqlSession 共享,是一个全局的变量

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

 

缓存标签的配置

设置 cache 标签的属性 cache 标签有多个属性

eviction: 缓存回收策略,有这几种回收策略

  • LRU - 最近最少回收,移除最长时间不被使用的对象

  • FIFO - 先进先出,按照缓存进入的顺序来移除它们

  • SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象

  • WEAK - 弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象

默认是 LRU 最近最少回收策略

 

  • flushinterval 缓存刷新间隔,缓存多长时间刷新一次,默认不清空,设置一

个毫秒值

  • readOnly : 是否只读;true 只读,MyBatis 认为所有从缓存中获取数据的操作

都是只读操作,不会修改数据。MyBatis 为了加快获取数据,直接就会将数据在缓

存中的引用交给用户。不安全,速度快。读写(默认):MyBatis 觉得数据可能会被修

  • size : 缓存存放多少个元素

  • type : 指定自定义缓存的全类名(实现Cache 接口即可)

  • blocking : 若缓存中找不到对应的key,是否会一直blocking,直到有对应的

数据进入缓存。

部分设置  和  一级缓存开启(主配置文件中设置    默认开启)
<settings>
<!-- 数据库的字段名以下划线命名的自动转换成小驼峰 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 日志实现:记录发生过的事情,主要是记录在本地,后期运营维护 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- mybatis中,如果说这个settings配置的属性,用得到,尽量把它写出来 -->
<!-- 开启一级缓存,默认开启 -->
<setting name="cacheEnabled" value="true"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
具体的mapper配置文件中开启   
<!-- 开启二级缓存 -->
<!--
       eviction:缓存满了的淘汰机制
           1.LRU:最近最少使用的,最长时间不适用的
           2.FIFO:先进先出
           3.SOFT:软引用,基于垃圾回收器状态的软引用规则
           4.WEAK:弱引用,基于垃圾回收机状态的弱引用规则
      flushInterval:刷新时间间隔,单位毫秒
      size:缓存最多可以存多少个对象,一般情况下1024个,不宜设置过大
      redOnly:只读,默认是false,不允许修改缓存
    -->
<cache eviction="LRU" flushInterval="10000"/>

 

集合处理

 

<resultMap id="deptEmpResult" type="dept">
   <id property="id" column="did"></id>
   <result property="name" column="dname"></result>
   <collection property="employees" ofType="employee"  select="com.jsoft.dao.EmployeeMapper.getEmpByDid" column="id">
   </collection>
</resultMap>

<select id="findAllDepts" resultMap="deptEmpResult">
  select id,name from dept1
</select>

<select id="getEmpByDid" resultType="employee">
  select id,name,did from employee where did = #{did}
</select>
 

标签:xml,mapper,缓存,Mybatis,mybatis,session,MyBatis
From: https://www.cnblogs.com/lyh15552012044/p/16778680.html

相关文章

  • springboot~对mybatis的start包进行单元测试
    一个start包,它不需要有springboot启动类,它只提供一切公用的功能,被其它包依赖就行了,通过META-INF/spring.factories或者META-INF/spring/org.springframework.boot.autoconf......
  • Spring-04:持久化数据,了解SpringDataJPA和Mybatis
    1Javaweb阶段的方式在之前的Javaweb项目中,我们持久化数据的方式还是直接使用JDBC参考:Javaweb总结-目前开发Javaweb的套路梳理https://www.cnblogs.com/fancy2022/p/16......
  • mybatis动态sql语句拼接总结
    mybatis中如果需要在where后面追加条件判断语句中有多个判断条件我们可以在if条件后面写上类似三元运算符的关系表达式其中a.pub_timeISNOTNULL为条件如果......
  • [转]Mybatis plus 多租户方案踩坑记录
    原文地址:Mybatisplus多租户方案踩坑记录-掘金(juejin.cn)公司的老项目要改造多租户,于是进入了大坑,本文写点遇到的坑以及解决方案,每次遇到问题在网上搜了好久,记录......
  • MyBatis-plus 新增时List转String 查询时String转list
    MyBatis-plus新增时List转String查询时String转list1.需求说明项目为:SpringBoot+MyBatisPlus采用实体类接受参数,有一个参数为List,对应的数据库字段为nvachar,要求新......
  • MyBatis之ResultMap的association和collection标签详解
    一、前言MyBatis创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。我们希望每个数据库都具备良好的第三范式或BCNF范式,可惜它们并不都是那样。如果能有一......
  • SpringBoot+MyBatis Plus对Map中Date格式转换的处理
    在SpringBoot项目中,如何统一JSON格式化中的日期格式问题现在的关系型数据库例如PostgreSQL/MySQL,都已经对JSON类型提供相当丰富的功能,项目中对于不需要检索......
  • MyBatis之ResultMap的association和collection标签详解
    一、前言MyBatis创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。我们希望每个数据库都具备良好的第三范式或BCNF范式,可惜它们并不都是那样。如果能......
  • MyBatis理论
    MyBatis简介MyBatis是什么?MyBatis是一款优秀的持久层框架,一个ORM(对象关系映射)框架,它支持定制化SQL、存储过程以及高级映射。MyBaits避免了几乎所有JDBC代码和手动设置参......
  • springboot整合mybatisPlus
    引入场景启动器              ......