mybatis使用介绍 mybatis实现细节 mybatis拦截器 pagehelper使用介绍

2016-03-16 20:34:00
admin
原创 2812
摘要:mybatis使用介绍 mybatis实现细节 mybatis拦截器 pagehelper使用介绍

一、mybatis使用介绍

1、mybatis帮助:https://www.mybatis.org/mybatis-3

2、mybatis-spring帮助:https://www.mybatis.org/spring

3、mybatis-generator帮助https://www.mybatis.org/generator/index.html

4、项目配置mysql.propertiesgenerateConfig.xmlmybatis-config.xml

5、项目文件:pom.xmlMybatisApp.javaMyStringTypeHandler.java

6、整个工程:mybatisdemo.zip

7、生成dao:修改mysql.properties,修改generateConfig.xml的table;

8、生成dao:ByExample用于生成动态数据库语句,实际比较少使用;

9、生成dao:mvn mybatis-generator:generate


配置说明:

1、typeHandler处理不支持的数据类型,实现TypeHandler,或者继承BaseTypeHandler

2、transactionManager等于JDBC,session.commit调用connection.commit;

3、transactionManager等于MANAGEDsession.commit不做任何事情;

4、dataSource等于UNPOOLED,每次请求都会打开和关闭连接;

5、dataSource等于POOLED,避免重复创建连接,连接会被缓存起来;

6、setting的logImpl用来配置日志,org.apache.ibatis用来配置系统日志;

7、使用log4j时,trace显示请求和结果,debug只显示请求;


获取连接

1、poolMaximumActiveConnections,正在使用的最大连接数量,默认10个;

2、poolMaximumIdleConnections,处于空闲的最大连接数量,默认5个;

3、poolMaximumCheckoutTime,从连接池取出后最长使用时间,默认20秒,

4、poolTimeToWait,获取不到连接时,单次等待最长时间,默认20秒;

5、获取连接1:空闲队列非空,直接从空闲队列获取一个连接;活跃连接数没有达到上限,直接创建一个连接;

6、获取连接2:最早签出的连接达到签出时间上限,使用这个连接的真实连接创建一个新连接,然后废除这个连接

7、获取连接3:如果仍然无法获取连接,则进行等待;等待超时或空闲队列有连接,则从新执行以上流程;


PING机制细节:

1、获取连接或归还连接,通过PING机制判断连接是否有效

2、poolPingQuery,侦测的语句,一般需要配置为SELECT 1;

3、poolPingEnabled,是否通过侦测判断连接是否有效,默认false;

4、poolPingConnectionsNotUsedFor,连接自上次使用多久之后才需要侦测;

5、侦测条件:poolPingEnabled && getTimeElapsedSinceLastUse()>poolPingConnectionsNotUsedFor


函数说明:

1、SqlSessionFactory全局作用域,最好使用单实例,重复创建浪费资源;

2、SqlSession局部作用域,线程不安全,使用完之后最好关闭;

3、SqlSessionFactory.openSession(),开启会话,关闭autoCommit;

4、SqlSessionFactory.openSession(autoCommit),开启会话,指定autoCommit;

5、SqlSession包含一个执行器Executor,执行器包含一个事务Transaction,事务包含一个连接Connection;

6、Resources工具类用于加载资源,支持类路径、文件系统、网络环境;

7、SQL工具类用于生成数据库语句,可以使用匿名类风格或生成器风格;

8、SqlSourceBuilder.removeExtraWhitespaces删除数据库语句的多余空白字符;


二、mybatis实现细节

参数提取:

1、接口参数是数组,转换为MapperMethod.ParamMap,包含成员arg0、array;

2、接口参数是集合,转换为MapperMethod.ParamMap,包含成员arg0、collection;

3、接口参数是动态数组,转换为MapperMethod.ParamMap,包含成员arg0、collection、list;

4、接口包含多个参数,转换为MapperMethod.ParamMap,包含成员arg0、arg1、param0、param1;

5、接口包含一个参数,不进行转换,注解参数进行转换@Param("name"),包含成员name、parram1;

6、接口包含一个参数,不进行转换,使用#{0}获取参数,0可以换成任意值;

7、接口参数是对象或字典,不进行转换,直接获取对象属性或字典元素;

8、接口参数是字典,如需使用foreach提取元素,需要注解参数@Param("name");


数据转换:

1、typeHandler用于JavaType和JdbcType之间相互转换;

2、JavaType在执行SQL之前已知,JdbcType在执行SQL之前未知;

3、JavaType有一个类型处理器,可以仅使用JavaType查找typeHandler;

4、JavaType有多个类型处理器,必须使用JavaType和JdbcType查找typeHandler;

5、@MappedJdbcTypes指定typeHandler应用于指定JdbcType;

6、resultMap指定typeHandler应用于指定字段,select指定typeHandler应用于指定语句;

7、自动映射默认模式是PARTIAL,关联查询以外属性会自动映射,然后处理手动映射;

8、constructor成员必须指定JavaType,用于查找构造函数;


mapper细节:

1、#{var}变量替换时自动加上引号,${var}只进行变量替换,井号可以防止SQL注入;

2、resultMap存在id元素,则通过id判断对象唯一性,否则比较对象所有非集合成员;

3、id元素在关联查询和缓存结果时能够显著提升性能,一个对象只能有一个id元素;

4、insert可以嵌入一个selectKey,用于生成插入数据行的主键;

5、association可以嵌入一个select,用于生成关联的对象;

6、collection可以嵌入一个select,用于生成关联的集合;

7、关联查询可以使用lazy模式,直到使用时才发起关联查询,通过代理对象实现;

8、lazy模式,会话未关闭则使用当前SqlSession,否则每次关联查询会创建SqlSession;


对象缓存:

1、一级缓存仅能在SqlSession内部使用,打开全局开关即可;

2、二级缓存在不同SqlSession之间访问,需要同时打开全局和mapper开关;

3、setting的localCacheScope用来配置一级缓存,默认开启;

4、setting的cacheEnabled用来配置二级缓存,默认开启;

5、每个mapper文件需要使用cache单独开启,默认关闭;

6、默认策略开启:<cache/>,LRU剔除算法,没有过期时间,size=1024,readOnly=false;

7、指定策略开启:<cache eviction="LRU" flushInterval="60000" size="1024" readOnly="true"/>

8、readOnly=true直接返回缓存对象,readOnly=false返回对象副本,通过反序列化创建对象;


三、mybatis拦截器

1、Interceptor通过代理实现,可以拦截Executor、StatementHandler、ParameterHandler、ResultSetHandler;

2、Interceptor按plugin申明顺序初始化,一个plugin只会初始化一次,但调用按plugin申明逆序

3、Executor.query用于数据库DQL操作,第一个参数是数据库语句,第二个参数是数据库语句参数;

4、Executor.update用于数据库DML操作,第一个参数是数据库语句,第二个参数是数据库语句参数;

5、StatementHandler.prepare,调用getBoundSql()获取BoundSql对象;

6、StatementHandler.query,调用getBoundSql()获取BoundSql对象;

7、StatementHandler.update,调用getBoundSql()获取BoundSql对象;

8、ParameterHandler.setParameters,通过反射获取BoundSql对象,调用自身方法获取参数;

9、ResultSetHandler.handleResultSets,通过反射获取BoundSql对象,返回值是对象列表;

10、BoundSql.getParameterMappings,获取数据库语句位置参数,语句对应位置被替换成问号;

11、拦截器代码示例:MybatisInterceptor.java


Executor.query调用过程:

1、StatementHandler.prepare,直接调用;

2、ParameterHandler.setParameters,直接调用;

3、StatementHandler.query,直接调用;

4、ResultSetHandler.handleResultSets,前面步骤调用;


Executor.update调用过程:

1、StatementHandler.prepare,直接调用;

2、ParameterHandler.setParameters,直接调用;

3、StatementHandler.update,直接调用;


四、pagehelper使用介绍

1、在线帮助:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

2、一个项目只能配置一个分页插件PageInterceptor,PageHelper.startPage后面第一个查询分页;

3、PageInterceptor一定会调用PageHelper.clearPage,clearPage清除当前线程的分页设置;

4、PageInterceptor使用dialect分页,dialect默认是PageHelper;

5、PageHelper使用autoDialect分页,autoDialect默认是PageAutoDialect;

6、PageAutoDialect使用delegate分页,delegate默认是AbstractHelperDialect;

7、AbstractHelperDialect.beforeCount是否统计总量:!page.isOrderByOnly() && page.isCount()

8、AbstractHelperDialect.beforePage是否执行分页:page.isOrderByOnly() || page.getPageSize()>0

9、pageSize==0 && orderBy!=null就会导致orderByOnly=true

10、Page继承了ArrayList,返回的数组实际是Page对象;

11、获取分页信息:PageInfo page = new PageInfo(list);


pagehelper常用参数:

1、helperDialect生成分页参数的数据库,不配置时自动侦测,建议配置;

2、defaultCount是否进行count查询,控制所有分页查询,默认为true;

3、reasonable分页参数合理化,false直接根据参数查询,默认为false;

4、reasonable=true,pageNum<=0查询第一页,pageNum>pages查询最后一页;

5、pageSizeZero是否允许pageSize为零,为零查询所有数据,默认为false;


pagehelper配置:

<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"></property>
</plugin>


分页设置1:reasonable=false && pageSizeZero=false

PageHelper.startPage(1, 20);
PageHelper.orderBy("id");


分页设置2:reasonable=true && pageSizeZero=true
PageHelper.startPage(1, 20, true, true, true);
PageHelper.orderBy("id");

发表评论
评论通过审核之后才会显示。