是什么
- mybatis是一种半ORM(对象关系映射)持久层框架。支持定制化sql、存储过程、和高级映射,使用xml或者注解来配置映射原生信息,将pojo映射成数据库中的记录
- Hibernate属于全自动的ORM框架,查询关联对象时可以根据对象关系模型直接获取,mybatis需要手动编写sql完成
传统jdbc存在的问题
- 频繁创建和释放数据库连接对象,容易造成资源浪费
- Sql语句存在硬编码,与java代码相结合,修改维护不方便
- 结果集处理麻烦,不能映射成java对象
mybatis优点
- 使用连接池管理数据库连接
- 将sql语句和java代码分离,更易于修改维护
- 自动将java对象映射成sql语句
- 自动将sql结果映射成java对象
mybatis编程步骤
- 创建一个sqlSessionFactory–>通过sqlSessionFactory创建一个SqlSession–>sqlsession操作数据库–>调用sqlsession.commiit()提交事务–>调用sqlSession.close()关闭事务
mybatis工作原理
- 读取mybatis配置文件–>加载mapper映射文件–>创建SqlSessionFactory会话工厂–>创建SqlSession会话对象–>调用Executor执行器–>调用mappedStatement(映射封装)对象–>输入参数映射—>输出结果映射
预编译
- 数据库在发送sql语句和参数给DBMS之前对sql语句进行编译
预编译的优点
- 可以优化sql的执行,合并多个操作为一个操作
- 预编译后产生一个缓存,可以重复使用,同一个sql可以使用sql
- 防止sql注入
mybatis延迟加载与实现原理
- mybatis仅支持association(一对一)和collection(一对多)关联对象的延迟加载。在配置文件中开启
tips:
-
懒加载:只加载一方,当需要的时候加载更多
-
侵入式延迟加载:默认只执行sql主加载,当访问主加载对象的详细信息时执行关联对象的sql
-
深度延迟加载:默认只执行性sql主加载,当调用主加载对象中关联对象信息时才会执行关联对象的sql
实现原理
- 使用CGliB创建目标对象的代理对象,在调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是空值,那么就会发送关联对象的sql,把B查询出来,然后调用a.setB(b),于是a就有了B的属性,也就可以调用a.getB().getname()了
#{}与${}的区别
- #{}是占位符,预编译处理。${}是拼接符,字符串替换,没有预编译处理可能会有sql注入问题
like模糊查询
-
“%”#{query}”%"或者concat(’%’,#{query},’%’)
-
或者使用bind标签
select * from user where username like #{pattern}
在mapper中如何传递多个参数
- 顺序传递, where user=#{0} and name=#{1}
- @param注解传递 public User select(@Param(“name”) String name)
- map传参 public User select(Map<String,Object> params)
- java bean传参<select id=“select” ,parameterType=“com,pojo.User”
foreach
- mybatis使用foreach标签执行批量操作
- foreach的主要属性有:item,index,collection,open,close,sepator
mapper编写方式
-
继承sqlSessionDaoSupport
-
使用mapperFactoryBean
-
使用mapper扫描器
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.mapper "></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
动态sql
- mybatis动态sql可以让我们在xml映射文件中,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能
- mybatis提供了9中动态sql标签trim、where、when、foreach、set、choose、if、bind、otherwise
- 执行原理:使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql.
mybatis分页及其原理
- mybatis使用RowBounds对象进行分页
- 原理:在插件的拦截方法内拦截待执行的sql,然后重写sql,添加对应的物理分页语句和分页参数
mybatis插件运行原理
- mybatis使用JDK动态代理,为需要拦截的接口生成代理对象,以实现接口方法拦截,只要执行接口方法就会进入拦截方法就是InvocationHandler的invoke()方法
mybatis的一级二级缓存
- 一级缓存:基于perpetualCache的HashMap本地缓存,作用域为session,当session.flush或者close之后,该session中的所有cache都将清空,默认开启
- 二级缓存:与一级存储机制相同,不同在于作用域是mapper(namespace),而且可以自定义存储源,使用二级缓存属性类需要实现serializabled序列化接口(用于保存对象的状态),在配置文件中开启
tips
- 对于缓存更新机制:当某一个作用域进行了C/U/D操作后,默认该作用域所用select中的缓存将被clear