mybatis系统学习(四)——mybatis配置优化

说明

在第二篇中,我所实现的是最简单的一个mybatis功能,完全没有考虑其他任何内容,比如日志、性能、可维护性等。
因此,除了指定必要的接口实现文件之外,使用的mybatis配置也仅有一个数据源和必要的事务管理器,而且数据源还是在mybatis的配置文件中写死的。
不过如果有人去github看了demo,会发现demo中数据源的配置,已经改成了从config.properties文件中加载,这也是相对来说更好的做法。
同时,我还在里边设置了启用控制台日志功能。

properties属性优化

config.properties文件相对于mybatis本身的配置来说,是一个外部文件,如果要使用properties中的内容,就需要引入这个文件,语法如下:

<properties resource="config.properties"/>

其实上边配置的意思,就是属性内容,引用config.properties中的内容,这个文件中内容如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=tuzongxun
jdbc.password=123456

实际上,这个属性文件代替的是如下这样一段内容:

<properties resource="org/mybatis/example/config.properties">
  <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
  <property name="jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
  <property name="jdbc.username" value="tuzongxun"/>
  <property name="jdbc.password" value="123456"/>
</properties>

那么结合第三篇使用spring引入配置文件后,会发现其实这里的这种引入就不需要了,因为spring一开始就已经引入,并且还必须引入,因为必须要配置databaseSource。
所以,既然在加载mybatis的配置之前已经引入,这里实际就没有必要再重复。

其他配置优化

要使mybatis跑起来,只需要第二篇的内容就够了,要使spring+mybatis跑起来,只需要第三篇就够了。最多是把配置改成上边所说的写法,提高维护性,使得可变数据统一配置。
但实际使用的过程中,自然不会只是跑起来就行,还需要涉及到是否要控制台打印日志、使用什么日志框架、性能及功能调优、是否需要自定义类型处理器、是否需要别名等等。

settings配置

上边说的日志及性能和功能调优,实际上都是使用settings标签及其子标签进行设置的,里边有一些属性有默认值。
就我目前看到的,mybatis官网说明非常详细,还有中文版,所以就没有必要再重复搬运一遍,想要一一了解的可以直接去官网查看:
http://www.mybatis.org/mybatis-3/zh/configuration.html

这里边有默认值的一般直接使用默认值就好,例如cacheEnabled,默认是true,也就是默认开启缓存。在这种情况下,对于重复的操作,一般都会从缓存中拿结果而不会再次连接数据库。
如果想要验证,可以启用数据库日志记录,然后就会看到使用默认值true时,同一个操作短时间内操作多次只会有一次数据库记录,也就是实际只操作了一次数据库。
而设为false,则会每次都有记录,也就是即使一模一样的操作,也会重新操作数据库,所以这个属性对于提升性能肯定是很重要的。

官网中有一个完整配置的示例,如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

可以看到上边的配置有些就是和默认值一样的,但有些本身没有默认值,这里也配置了。
例如lazyLoadingEnabled默认是false,这里是true;autoMappingUnknownColumnBehavior默认值为NONE,这里是WARNING,而且这个值似乎也是3.4以后的新特性;defaultStatementTimeout、defaultFetchSize原本没有默认值。
这个配置其实就是一个比较好的参考,具有很大程度的通用性,我目前遇到的项目中,大多数基本都是这样,或者是在此基础上再做一定的修改。
例如可能修改defaultStatementTimeout的超时时间,具体值根据实际业务和数据量而定。
也可能修改defaultFetchSize的值,之所以要设置这个值,是因为mysql驱动默认的行为是需要把整个结果全部读取到内存中,才开始允许应用读取结果,那么当结果数据量很大的时候,对内存的消耗可想而知。
当配置了defaultFetchSize,这个结果数据就会以流的方式读取,并且根据具体的配置控制流的大小,一定程度上使内存可控。
还需要注意的是,lazyLoadingEnabled配置看起来没有明确的说和aggressiveLazyLoading有什么关系,但是实际使用的时候却有很密切的关系。
aggressiveLazyLoading的值如果是true,那么只要有一个延时加载的属性被加载,其他所有延时加载的都会被触发。很显然,这就会导致有些可能还不想被加载的属性会在不当的时间被加载。
所以,如果要使用lazyLoadingEnabled,正确的做法就应该是让aggressiveLazyLoading为false。
在上述的官网示例中,并没有显示配置aggressiveLazyLoading,那么就是使用的默认值。但是需要注意的是一开始对于这个值的说明,默认值false (true in ≤3.4.1),也就是说只有版本大于3.4.1的才默认是false,因此如果版本小于或等于3.4.1,就需要显示设置为false。
除了上边所说,可能有时候还需要记录mybatis的sql,那么还需要启动日志功能。

至于在配置中使用别名,官网中示例很详细,上边已经贴出了官网地址,也就没有必要重复记录。
而自定义类型处理器,在我目前的项目中几乎就没有看到,mybatis自己定义的完全够用,因此也暂时略作了解,知道可能自定义就好。

项目参考地址:
https://github.com/tuzongxun/mybatis-study

发布了268 篇原创文章 · 获赞 364 · 访问量 125万+
展开阅读全文

mybatis 查询大量数据 效率低

10-31

下面是我的mapper文件,查询超级慢,请问有什么办法优化吗 ``` <select id="selectMedAlls" resultMap="BaseResultMap" > with temp as (select FUN_GET_DEPT_NAME(a.nurse_cell_code) as nurse_cell_name, month_code, sum(a.out_num) as out_num, /*出院人数*/ sum(a.bednum) as sjkfzcrs /*实际开放总床日数*/, round((sum(a.bednum) / 30), 1) as pjkfcws /*平均开发床位数*/, sum(a.end_num) as sjzyzcws /*实际占用总床日数*/ /*'期末人数'*/ from nurse_day_report a where a.month_code between '201501' and '201511' group by a.nurse_cell_code, month_code order by a.nurse_cell_code), data as ( select 'thisM' as time , nvl(max((select count(1) as aa from fin_opr_register t1 WHERE t1.dept_code not in ('0019', '0277', '0278') /*挂号主表.科室号 急诊科 急诊外科 急诊产科*/ and t1.valid_flag = '1' and t1.reglevl_name <![CDATA[<>]]> ' ' and to_char(t1.oper_date, 'yyyymm') = month_code)),0) as regist, /*门诊人次:期内科室号不属于'0019', '0277', '0278'的有效挂号人数*/ nvl((sum(temp.out_num)),0) as outer, /*期内出院人数总计:0 治愈1 好转 2 未愈3 死亡 4 其他'*/ nvl(sum(sjzyzcws),0) as sjzyzcrs, /*实际占用总床日数,*/ nvl(to_number(nvl(decode(sum(pjkfcws), 0, 0, round(sum(out_num) / sum(pjkfcws), 1)),0)),0) as zzcs, /*周转次数,*/ nvl(to_number(nvl(decode(sum(sjkfzcrs), 0, 0, round(sum(sjzyzcws) * 100 / sum(sjkfzcrs), 1)), 0)),0) as cwsyl /*床位使用率*/ from temp where month_code='201511' union all select 'lastM' , nvl(max((select count(1) as aa from fin_opr_register t1 WHERE t1.dept_code not in ('0019', '0277', '0278') /*挂号主表.科室号 急诊科 急诊外科 急诊产科*/ and t1.valid_flag = '1' and t1.reglevl_name <![CDATA[<>]]> ' ' and to_char(t1.oper_date, 'yyyymm') = month_code)),0) as regist, /*门诊人次:期内科室号不属于'0019', '0277', '0278'的有效挂号人数*/ nvl((sum(temp.out_num)),0) as outer, /*期内出院人数总计:0 治愈1 好转 2 未愈3 死亡 4 其他'*/ nvl(sum(sjzyzcws),0) as sjzyzcrs, /*实际占用总床日数,*/ nvl(to_number(nvl(decode(sum(pjkfcws), 0, 0, round(sum(out_num) / sum(pjkfcws), 1)),0)),0) as zzcs, /*周转次数,*/ nvl(to_number(nvl(decode(sum(sjkfzcrs), 0, 0, round(sum(sjzyzcws) * 100 / sum(sjkfzcrs), 1)), 0)),0) as cwsyl /*床位使用率*/ from temp where month_code='201511' union all select 'thisY' , nvl(max((select count(1) as aa from fin_opr_register t1 WHERE t1.dept_code not in ('0019', '0277', '0278') /*挂号主表.科室号 急诊科 急诊外科 急诊产科*/ and t1.valid_flag = '1' and t1.reglevl_name <![CDATA[<>]]> ' ' and to_char(t1.oper_date, 'yyyymm') = month_code)),0) as regist, /*门诊人次:期内科室号不属于'0019', '0277', '0278'的有效挂号人数*/ nvl((sum(temp.out_num)),0) as outer, /*期内出院人数总计:0 治愈1 好转 2 未愈3 死亡 4 其他'*/ nvl(sum(sjzyzcws),0) as sjzyzcrs, /*实际占用总床日数,*/ nvl(to_number(nvl(decode(sum(pjkfcws), 0, 0, round(sum(out_num) / sum(pjkfcws), 1)),0)),0) as zzcs, /*周转次数,*/ nvl(to_number(nvl(decode(sum(sjkfzcrs), 0, 0, round(sum(sjzyzcws) * 100 / sum(sjkfzcrs), 1)), 0)),0) as cwsyl /*床位使用率*/ from temp where month_code between '201601' and '201511' union all select 'lastY' , nvl(max((select count(1) as aa from fin_opr_register t1 WHERE t1.dept_code not in ('0019', '0277', '0278') /*挂号主表.科室号 急诊科 急诊外科 急诊产科*/ and t1.valid_flag = '1' and t1.reglevl_name <![CDATA[<>]]> ' ' and to_char(t1.oper_date, 'yyyymm') = month_code)),0) as regist, /*门诊人次:期内科室号不属于'0019', '0277', '0278'的有效挂号人数*/ nvl((sum(temp.out_num)),0) as outer, /*期内出院人数总计:0 治愈1 好转 2 未愈3 死亡 4 其他'*/ nvl(sum(sjzyzcws),0) as sjzyzcrs, /*实际占用总床日数,*/ nvl(to_number(nvl(decode(sum(pjkfcws), 0, 0, round(sum(out_num) / sum(pjkfcws), 1)),0)),0) as zzcs, /*周转次数,*/ nvl(to_number(nvl(decode(sum(sjkfzcrs), 0, 0, round(sum(sjzyzcws) * 100 / sum(sjkfzcrs), 1)), 0)),0) as cwsyl /*床位使用率*/ from temp where month_code between '201501' and '201511' ) select sum(case when TIME = 'thisM' then regist else 0 end) as "thisM", sum(case when TIME = 'lastM' then regist else 0 end) as "lastM", decode(sum(case when TIME = 'lastM' then regist else 0 end) ,0,0,round((sum(case when TIME = 'thisM' then regist else 0 end)-sum(case when TIME = 'lastM' then regist else 0 end))*100/sum(case when TIME = 'lastM' then regist else 0 end),3))as lvM, sum(case when TIME = 'thisY' then regist else 0 end) as "thisY", sum(case when TIME = 'lastY' then regist else 0 end) as "lastY" , decode(sum(case when TIME = 'lastY' then regist else 0 end) ,0,0,round((sum(case when TIME = 'thisY' then regist else 0 end) -sum(case when TIME = 'lastY' then regist else 0 end) )*100/sum(case when TIME = 'lastY' then regist else 0 end) ,1))as lvY from data union all select sum(case when TIME = 'thisM' then outer else 0 end) as "thisM", sum(case when TIME = 'lastM' then outer else 0 end) as "lastM", decode(sum(case when TIME = 'lastM' then outer else 0 end) ,0,0,round((sum(case when TIME = 'thisM' then outer else 0 end)-sum(case when TIME = 'lastM' then outer else 0 end))*100/sum(case when TIME = 'lastM' then outer else 0 end),1)) as LvM, sum(case when TIME = 'thisY' then outer else 0 end) as "thisY", sum(case when TIME = 'lastY' then outer else 0 end) as "lastY", decode(sum(case when TIME = 'lastY' then outer else 0 end),0,0,round((sum(case when TIME = 'thisY' then outer else 0 end)-sum(case when TIME = 'lastY' then outer else 0 end))*100/sum(case when TIME = 'lastY' then outer else 0 end),1) ) as LvY from data union all select sum(case when TIME = 'thisM' then sjzyzcrs else 0 end) as "thisM", sum(case when TIME = 'lastM' then sjzyzcrs else 0 end) as "lastM", decode(sum(case when TIME = 'lastM' then sjzyzcrs else 0 end) ,0,0,round((sum(case when TIME = 'thisM' then sjzyzcrs else 0 end)-sum(case when TIME = 'lastM' then sjzyzcrs else 0 end))*100/sum(case when TIME = 'lastM' then sjzyzcrs else 0 end),1)) as LvM, sum(case when TIME = 'thisY' then sjzyzcrs else 0 end) as "thisY", sum(case when TIME = 'lastY' then sjzyzcrs else 0 end) as "lastY", decode(sum(case when TIME = 'lastY' then sjzyzcrs else 0 end) ,0,0,round((sum(case when TIME = 'thisY' then sjzyzcrs else 0 end)-sum(case when TIME = 'lastY' then sjzyzcrs else 0 end) )*100/sum(case when TIME = 'lastY' then sjzyzcrs else 0 end) ,1)) as LvY from data union all select sum(case when TIME = 'thisM' then zzcs else 0 end) as "thisM", sum(case when TIME = 'lastM' then zzcs else 0 end) as "lastM", decode(sum(case when TIME = 'lastM' then zzcs else 0 end) ,0,0,round((sum(case when TIME = 'thisM' then zzcs else 0 end)-sum(case when TIME = 'lastM' then zzcs else 0 end))*100/sum(case when TIME = 'lastM' then zzcs else 0 end),1)) as LvM, sum(case when TIME = 'thisY' then zzcs else 0 end) as "thisY", sum(case when TIME = 'lastY' then zzcs else 0 end) as "lastY", decode(sum(case when TIME = 'lastY' then zzcs else 0 end),0,0,round((sum(case when TIME = 'thisY' then zzcs else 0 end)-sum(case when TIME = 'lastY' then zzcs else 0 end))*100/sum(case when TIME = 'lastY' then zzcs else 0 end) ,1)) as LvY from data union all select sum(case when TIME = 'thisM' then cwsyl else 0 end) as "thisM", sum(case when TIME = 'lastM' then cwsyl else 0 end) as "lastM", decode(sum(case when TIME = 'lastM' then cwsyl else 0 end) ,0,0,round((sum(case when TIME = 'thisM' then cwsyl else 0 end)-sum(case when TIME = 'lastM' then cwsyl else 0 end))*100/sum(case when TIME = 'lastM' then cwsyl else 0 end),1)) as LvM, sum(case when TIME = 'thisY' then cwsyl else 0 end) as "thisY", sum(case when TIME = 'lastY' then cwsyl else 0 end) as "lastY", decode(sum(case when TIME = 'lastY' then cwsyl else 0 end),0,0,round((sum(case when TIME = 'thisY' then cwsyl else 0 end)-sum(case when TIME = 'lastY' then cwsyl else 0 end))*100/sum(case when TIME = 'lastY' then cwsyl else 0 end) ,1)) as LvY from data </select> ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 成长之路 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览