MyBatis

MyBatis

MyBatis是一款优秀的持久层框架
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程
MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的实体类映射成数据库中的记录

什么是持久化
持久化是将程序数据在持久状态和瞬时状态间转换的机制

把内存中的对象保存到数据库,XML或者磁盘当中。例如JDBC机制和文件

什么是持久层
完成持久化工作的代码块,Dao层。我们的架构当中,应该有一个相对独立的逻辑层面,专注于数据持久化逻辑的实现

MyBatis使用的流程

  1. 搭建数据库
  2. maven配置
  3. 配置myBatis-config
  4. myBatis工具类
public class Mybatis{

   private static SqlSessionFactory sqlSessionFactory;

   static {
       try {
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      } catch (IOException e) {
           e.printStackTrace();
      }
  }
   //获取SqlSession连接
   public static SqlSession getSession(){
       return sqlSessionFactory.openSession();
  }

}
  1. 构建实体类
  2. 编写Mapper接口
  3. 配置Mapper.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="com.yzh.dao.UserMapper">
 <select id="selectUser" resultType="com.yzh.pojo.User">
  select * from user
 </select>
</mapper>
  1. 编写测试类然后运行

配置文件可配置内容包括

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

自动映射

ResultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来。

实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码。

ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

手动映射

<select id="selectUserById" resultMap="UserMap">
  select name,pwd from user where id = #{id}
</select>

手动映射实现ResultMap

<resultMap id="UserMap" type="User">
   <!-- id为主键 -->
   <id column="id" property="id"/>
   <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
   <result column="name" property="name"/>
   <result column="pwd" property="password"/>
</resultMap>

mysql的日志实现

在测试sql时,使用日志输出sql的话能够帮助我们更快找出问题所在

我们可以使用Log4j进行日志的输出

//日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

//控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

注解开发

sql注解主要分为:

  • @select()
  • @insert()
  • @update()
  • @delete()
  • @one
  • @many

例如select

//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();

增删改要处理事务

动态sql

如果需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

if语句

<select id="queryIf" parameterType="map" resultType="User">
  select * from user where
  
   <if test="xxx != null">
      and xxx = #{xxx}
   </if>
</select>

where语句

<select id="queryIf" parameterType="map" resultType="User">
  select * from user
   <where>
       <if test="xxx != null">
          xxx= #{xxx}
       </if>
   </where>
</select>

set语句

<!--注意set是用的逗号隔开-->
<update id="update" parameterType="map">
  update user
     <set>
         <if test="xxx!= null">
            xxx = #{xxx},
         </if>
     </set>
  where id= #{id};
</update>

choose语句

<select id="queryChoose" parameterType="map" resultType="user">
  select * from user
   <where>
       <choose>
           <when test="xxx != null">
                xxx = #{xxx }
           </when>
           <otherwise>
              and xxx = #{xxx}
           </otherwise>
       </choose>
   </where>
</select>

引用sql语句
例如引用上一个的例子

<select id="queryIf" parameterType="map" resultType="user">
  select * from user
   <where>
       <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
       <include refid="queryChoose"></include>
       <!-- 在这里还可以引用其他的 sql 片段 -->
   </where>
</select>

Foreach语句

<select id="queryForeach" parameterType="map" resultType="user">
  select * from user
   <where>
       <!--
       collection:指定输入对象中的集合属性
       item:每次遍历生成的对象
       open:开始遍历时的拼接字符串
       close:结束时拼接的字符串
       separator:遍历对象之间需要拼接的字符串
       select * from blog where 1=1 and (id=1 or id=2 or id=3)
     -->
       <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
          id=#{id}
       </foreach>
   </where>
</select>

缓存

  • 缓存就是存在内存中的临时数据
  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。

使用缓存的原因
减少和数据库的交互次数,减少系统开销,提高系统效率。

MyBatis缓存

分为一级缓存和二级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
@Test
public void testQueryUserById(){
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = mapper.queryUserById(1);
   User user2 = mapper.queryUserById(1);
   session.close();
}//第二次没有进行数据库查询

一级缓存失效的四种情况

  1. sqlSession不同
@Test
public void testQueryUserById(){
   SqlSession session = MybatisUtils.getSession();
   SqlSession session2 = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);
   UserMapper mapper2 = session2.getMapper(UserMapper.class);

   User user = mapper.queryUserById(1);
   User user2 = mapper2.queryUserById(1);

   session.close();
   session2.close();
}

每个sqlSession中的缓存相互独立

  1. sqlSession相同,查询条件不同
  2. sql相同,两次查询间进行了增删改操作
  3. sqlSession相同,手动清除一级缓存

二级缓存

  • 二级缓存也叫全局缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存

一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;新的会话查询信息,就可以从二级缓存中获取内容;不同的mapper查出的数据会放在自己对应的缓存(map)中;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值