125.mybatis中#{}和${}的区别
答案:#{}是预编译处理,${}是字符串替换,#{}安全性更高,防止sql注入
126.mybatis有几种分页方式
答案:数组分页,sql分页,拦截器分页,rowBounds分页
128.mybatis逻辑分页和物理分页的区别是什么
答案:一般常用的分页方式mybatis自带的rowbounds分页功能,是逻辑分页,将所有数据都查询出来,然后在内存中分页,
通过自己写sql或者分页插件称为物理分页,把分页功能交给了数据库
逻辑分页内存开销较大,在数据量比较小的情况效率比物理分页高,
物理分页内存开销较小,数据量比较小的情况下物理分页性能不如逻辑分页
129.mybatis是否支持延迟加载,延迟加载的原理是什么
答案:mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection值得就是一对多查询,在mybatis配置文件中,可以配置是否启用延迟加载
它的原理是,使用cglib创建目标对象的代理对象,党调用目标方法时,进入拦截器方法,比如调用a.gatb().getName(),拦截器invoke方法发现a.getb()是null,那么就会单独发送事先保存好的查询关联b对象的sql,把b查询上来,然后调用a.getb(b),于是a的对象b就有值了,接着完场a.getb.getname的调用,这就是延时加载的基本原理.
130.mybatis的一级缓存和二级缓存
答案:一级缓存仅作用于本session之间,党session close之后,session中的所有cache就会清空,mybatis默认打开一级缓存
二级缓存的作用于可以跨越session,默认不打开二级缓存,若要打开二级缓存,使用二级缓存属性类需要实现serializable接口
131.mybatis和hibernate的区别
答案:mybatis不完全是个orm框架,因为mybatis需要程序员自己边写sql
mybatis可直接编写原生态sql,可以严格空值sql执行性能,灵活度高,适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频分,一旦需求变化要求迅速输出成果.
hibernate对象关系映射能力强,数据库无关性好,使用hibernate开发会节省许多代码
132.mybatis有那些执行器
答案:mybatis有三种基本执行器,
simpleExecutor,每执行一次update或select,就开启一个statement对象,用完立刻关闭
ReuseExecutor执行update或select,以sql作为key查找statement对象,存在就使用,不存在就创建,不关闭statement对象,而是放在map中供下次使用
BatchExecutor,执行update(没有select,jdbc不支持select批处理),将所有sql都添加到批处理中,等待统一执行,它缓存了多个statement对象,每个statement对象都是addBatch完毕后,等待注意执行executeBatch处理
133.mybatis分页插件的实现原理是什么
答案:分类插件的基本原理是使用mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数
134.mybatis如何编写一个自定义插件
答案:mybatis自定义插件针对mybatis四大对象,executor,statementHandler,ParameterHandlerResultSetHandler,进行拦截,具体拦截方式为
executor拦截执行器的方法,StatementHandler拦截sql语法结构的处理,ParameterHandler拦截参数的处理,ResultSetHandler拦截结果集的处理
自定义插件必须实现Interceptor接口
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
intercept方法,拦截器具体处理逻辑方法
plugin方法,根据签名signatureMap生成动态代理对象
setProperties方法,设置Propertise属性
自定义插件demo:
// ExamplePlugin.java
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理对象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法参数
// do something ...... 方法拦截前执行代码块
Object result = invocation.proceed();
// do something .......方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
一个@Intercepts可以配置多个@Signature,@Signature中的参数定义如下
type:表示拦截的类,这里是Executor的实现类;
method:表示拦截的方法,这里是拦截Executor的update方法;
args:表示方法参数。