作者:Dewey | 来源:互联网 | 2023-09-18 16:50
一、核心API介绍1、Mapper映射器。由一个Java接口和XML文件(或者注解构成)2、SqlSession就相当于一个数据库连接(Connection对象),可以在一个事务里
一、核心 API 介绍 1、Mapper映射器。由一个 Java 接口和 XML 文件(或者注解构成) 2、SqlSession 就相当于一个数据库连接(Connection 对象),可以在一个事务里面执行多条 SQL,然后通过commit、rollback 方法提交或者回滚事务。 3、SqlSessionFactory 可以被认为是一个数据库连接池,里面存储SqlSession对象。单例模式的对象,在应用中被共享。 4、SqlSessionFactoryBuilder 的作用是使用构建者模式创建 SqlSessionFactory 接口对象。
二、全局配置文件、配置文件
三、Mybatis 中的参数绑定 在映射配置文件中向 SQL 语句中绑定参数的语法结构为#{ }和${ }。 #{ } 和 ${ }的区别: #{ } 解析为一个 JDBC 预编译语句(PreparedStatement)的参数标记符占位符 ?。使用该方式可避免 SQL 注入。 仅 仅 为 一 个 纯 碎 的 S t r i n g 替 换 , 在 M y b a t i s 的 动 态 S Q L 解 析 阶 段 将 会 进 行 变 量 替 换 。 { } 仅仅为一个纯碎的 String 替换,在 Mybatis 的动态 SQL 解析阶段将会进行变量替换。 仅仅为一个纯碎的String替换,在Mybatis的动态SQL解析阶段将会进行变量替换。{ } 在预编译之前已经被变量替换了,这会存在 SQL 注入问题 四、使用 ThreadLocal 存储 SqlSession 如果多个 DML 操作属于一个事务,因为 commit()和 rollback()都是由 SqlSession 完成的,所以必须保证使用一个 SqlSession。但是多个不同的 DML 操作可能在不同类的不同方法中,每个方法中要单独的获取 SqlSession。比如商城下订单时,其实涉及商品库存变化、订单添加、订单明细添加、付款、日志添加等多个 DML 操作,分布在不同类中。如何在多个 DML 操作之间使用同一个 SqlSession 呢,可以使用 ThreadLocal 来存储。保证一个线程中的操作使用的都是一个 SqlSession。 创建 Mybatis 工具类
public class MybatisUtils { private static ThreadLocal threadLocal = new ThreadLocal<>(); private static SqlSessionFactory sqlSessiOnFactory= null; static{ //创建 SqlSessionFactory InputStream is = null; try{ is = Resources.getResourceAsStream("mybatis-cfg.xml"); }catch (IOException e){ e.printStackTrace(); } sqlSessiOnFactory= new SqlSessionFactoryBuilder().build(is); } //获取 SqlSession public static SqlSession getSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ sqlSession = sqlSessionFactory.openSession(); threadLocal.set(sqlSession); 29} return sqlSession; } //关闭 SqlSession public static void closeSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession != null){ sqlSession.close(); threadLocal.set(null); } } } @Override public void deleteUsersById(int userid) { SqlSession sqlSession = MybatisUtils.getSqlSession(); final int delete = sqlSession.delete("com.bjsxt.mapper.UserMapper.deleteUsersById", userid); }
五、日志处理 日志处理,线上问题追踪、错误排查、基于日志的业务的逻辑统计分析。常用日志框架Log4J、common Logging 、slf4J Log4j 的日志级别 Log4j 定义了 8 个日志级别(除去 OFF 和 ALL,可以说分为 6 个级别),优先级从低到高 DEBUG、INFO、WARN、ERROR 四个日志级别。
六、分页查询 1、rowbounds ->offset:偏移量,从 0 开始计数 limit:限制条数 List selectUsersRowBounds(RowBounds rowBounds); 2、SQL语句分页:SQL 语句来实现分页处理。在 MySQL 数据库中我们可以使用 limit 实现分页。
select * from users limit #{offset},#{limit}
3、PageHelper使用分页插件 分页查询 API PageHelper.startPage(int pageNum,int pageSize); 给定分页参数,该方法需要在执行查询之前调用 pageNum:起始的页数,从 1 开始计算。 pageSize:每页显示的条数。 PageInfo 对象 存放分页结果对象 pageInfo.getList() 获取分页查询结果。 pageInfo.getTotal() 获取查询总条数。 pageInfo.getPages() 获取总页数。 pageInfo.getPageNum() 获取当前页。 pageInfo.getSize() 获取每页显示的条数。 使用步骤:
sqlSession.getMapper(UsersMapper.class); UsersExample usersExample = new UsersExample(); PageHelper.startPage(3,2); List list =usersMapper.selectByExample(usersExample); list.forEach(System.out::println); PageInfo pageInfo = new PageInfo<>(list);
七、MyBatis动态代理 ------mybatis 主键值回填 ----------------
keyProperty="userid"> insert into users values(default ,#{username},#{usersex}) parameterType="com.telecomyt.plat.cmac.alarm.entity.AlarmDispose" useGeneratedKeys="true"> insert into alarm_dispose (alarm_content_id........)values () ------------动态代理原理解析mapperproxy.newInstance//代理对象也就是接口实现类、JDK动态代理-对象创建mapperProxy
------------动态SQL-----------------------
if条件的判断:
and username = #{username}
多选一条件:choose中没有条件满足执行otherwise
select * from users where 1=1 and username = #{username} and usersex = #{usersex} and userid = 1
根据用户给定的条件进行查询使用 where 标签实现
select * from users and userid = #{userid} and username = #{username} and usersex = #{usersex}
模糊查询
select * from users where username like concat('%',#{name},'%') select * from users where username like #{likeName}
set标签
update users username = #{username}, usersex = #{usersex},
集合
select * from users where userid inseparator="," close=")"> #{userid}
八、MyBatis缓存 缓存是一般的 ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力,缓存的重要性是不言而喻的。Mybatis 会将相同查询条件的 SQL 语句的查询结果存储在内存或者某种缓存介质当中MyBatis 缓存方式分为一级缓存和二级缓存,同时也可配置关于缓存设置。一级缓存是将结果缓存在 SqlSession 对象中,二级缓存是存储在 SqlSessionFactory 对象中。默认情况下,MyBatis 开启一级缓存,没有开启二级缓存。当数据量大的时候可以借助一些第三方缓存技术来协助保存 Mybatis 的二级缓存数据。
一级缓存也叫本地缓存,MyBatis 的一级缓存是在会话(SqlSession)层面进行缓存的。MyBatis 的一级缓存是默认开启的,不需要任何的配置。MyBatis 在开启一个数据库会话时,会创建一个新的 SqlSession 对象,SqlSession 对象中会有一个新的 Executor 对象。Executor 对象中持有一个新的PerpetualCache 对象;当会话结束时,SqlSession 对象及其内部的 Executor 对象还有 PerpetualCache 对象也一并释放掉。
二级缓存是 SqlSessionFactory 上的缓存,可以是由一个 SqlSessionFactory 创建的不同的 SqlSession 之间共享缓存数据。默认并不开启。二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis 要求缓存的 POJO 必须是可序列化的, 也就是要求实现 Serializable 接口。在映射配置文件中配置就可以开启缓存了。
二级缓存的特点
映射语句文件中的所有 select 语句将会被缓存。 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。 二级缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响 如果在加入标签的前提下让个别 select 元素不使用缓存,可以使用 useCache属性,设置为 false。 缓存会使用默认的 Least Recently Used(LRU,最近最少使用的)算法来收回 九、多表查询
```java SELECT alarm_content.alarm_content_id as alarmContentId, alarm_content.alarm_describe as alarmDescribe, alarm_content.alarm_level as alarmLevel, ahi.asset_id as assetHostId, ahi.asset_name as assetHostName, ahi.responsible_telephone as hostManagerPhone, ahi.maintenance_telephone as hostMaintainPhone, ahi.manu_facturers as factory, dtio.dict_name as areaName, alarm_dispose.alarm_dispose_status as alarmDisposeStatus alarm_dispose.alarm_dispose_time as alarmDisposeTime, alarm_dispose.alarm_comment as alarmComment, asset_user.name as alarmDisposeUser FROM alarm_content INNER JOIN alarm_dispose ON alarm_content.alarm_content_id = alarm_dispose.alarm_content_id LEFT JOIN asset_user ON alarm_dispose.alarm_dispose_user_id = asset_user.user_id LEFT JOIN asset_soft_server ass on alarm_content.alarm_service_name = ass.server_name LEFT JOIN asset_host_info ahi on alarm_content.alarm_service_name = ahi.asset_name LEFT JOIN dict_type_info dtio ON ahi.area = dtio.dict_id alarm_dispose.alarm_dispose_status =#{alarmListParam.alarmDisposeStatus} AND alarm_content.alarm_type =#{alarmListParam.alarmType} AND alarm_content.alarm_level =#{alarmListParam.alarmLevel} AND alarm_content.alarm_describe like concat('%',#{alarmListParam.alarmDescribe},'%') ORDER BY alarm_dispose.alarm_dispose_time desc limit #{alarmListParam.pageNum},#{alarmListParam.pageSize} resultMap="usersAndOrdersAndItems"> select * from users as u,orders as o, orders_items as oi ,items as i where u.userid = o.user_id and o.orderid = oi.order_id and oi.item_id = i.itemid and u.userid = #{userid}
或者使用修改全局配置文件配置触发方法 延迟加载,调用get方法后才能进行查询加载,此为延迟加载。