bat 存储过程返回值_使用Mybatis过程中遇到的坑

常规SSM框架开发中,mybatis遇到的坑是最多的,把以下几点坑记录下来防止以后再遇到同样的情况。

1、mybatis 若果在mapper中返回值没有配置resultMap而是使用resultType直接返回的话,那么当心默认配置中的驼峰匹配规则,参考以下配置文件。该情况适用于bean属性字段和数据库完全一致且字段名带有下划线如(user_menu)这样的字段时

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="callSettersOnNulls" value="true"/>
		<setting name="cacheEnabled" value="true"/>
		<setting name="lazyLoadingEnabled" value="true"/>
		<setting name="aggressiveLazyLoading" value="true"/>
		<setting name="multipleResultSetsEnabled" value="true"/>
		<setting name="useColumnLabel" value="false"/>
		<setting name="useGeneratedKeys" value="false"/>
		<setting name="autoMappingBehavior" value="PARTIAL"/>
		<setting name="defaultExecutorType" value="SIMPLE"/>
		<!-- 禁用掉驼峰规则,不然实体类带下划线的都匹配不上 -->
		<setting name="mapUnderscoreToCamelCase" value="false"/>
                <setting name="localCacheScope" value="SESSION"/>
                <setting name="jdbcTypeForNull" value="NULL"/>
                <setting name="autoMappingUnknownColumnBehavior" value="FAILING"/>
               <!--自定义日志类-->
               <setting name="logImpl" value="main.com.log.MyBatisLogImpl" /> 
	</settings>
	
	<typeAliases>
		<typeAlias alias="Integer" type="java.lang.Integer"/>
		<typeAlias alias="Long" type="java.lang.Long"/>
		<typeAlias alias="String" type="java.lang.String"/>
		<typeAlias alias="HashMap" type="java.util.HashMap"/>
		<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
		<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
		<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
		<!-- 自定义实体类 -->
		
	</typeAliases>
</configuration>

2、mybatis想要打印sql,如果按照常规配置是无法打印的,

如果这样配置,sql可以打印,但是无法进入文件。

<setting name="logImpl" value="STDOUT_LOGGING " />

或者

<setting name="logImpl" value="SLF4J" />

但是有时候会失效

因为本人使用logback做日志管理,因此也无法用log4j来实现sql的打印。

这时候就需要重写log打印功能

@Component

mybatis 配置

<setting name="logImpl" value="xx.xx.MyBatisLogImpl" />

3、有的时候mybatis需要调用oracle存储过程,而这个存储过程的参数还是一个自定义的oracle类型。

private 

这里要注意:1、oracle的自定义类型和自定义列表必须是全局的,不能是pkg里面的,否则不识别。

2、本人没有找到使用Mybatis的自定义typeHandler来进行参数拼接方案,尤其是跨用户执行存储过程的时 候,使用typeHandler往往是匹配不上的,他会莫名其妙把你JDBC的用户名给带上去,所以我暂定的方案是直接拿连接池里面的连接直接操作数据库。

4、JDBC连接池拿到的连接有的时候需要转成oracle的connection或者mysql的connection,如果你直接close转换之后的连接实例是没用的,因为数据连接池的连接并没有关闭掉,而且调用连接池连接的关闭方法也不是真的关闭,而是放回至连接池中,所以如果要做转换,记得分两步,拿到连接池连接实例,操作完之后记得close掉。

5、这个相对大头一些,有的时候(通常是连oracle这种数据库),我们要导出大量数据到excel,如果数据量比较大,比如大概3、4 十万行,每行100多列的这种情况。

如果用常规的导出办法,也就是查到list中再传入poi进行处理,是会报堆溢出的,很明显list里面放那么多数据根本就放不下。那解决办法就是边查边导,这时候需要重写ResultHandler,按照自定义返回值处理的方式进行处理。

个人解决方案是,在service方法中写一个方法域内的全局list,逐条插入数据,当list.size()达到500的时候,将里面的数据用poi导到文档,清空list。往复循环,直到数据全部被插入到excel为止。

这里poi有几个特定的配置强调一下:

1、final SXSSFWorkbook sbook = new SXSSFWorkbook(100);

workboox实例要用SXSSFWorkbook初始化,常规的最大行数就到Integer.MAX_VALUE (65535)了,超过就溢出。

构造方法参数是内存缓存100条,超过就写入临时文件了,如果列超级多的话建议设置小点儿,但是不能不设置,不设置就是不限制了。

2、sbook.setCompressTempFiles(true); //要开启写入临时文件这个功能。

以上就是Mybatis遇到的几个比较大的坑,小来小去的错误就不在这写了,当然也可能有一些更大的坑被遗漏掉了,以后再慢慢捡吧。其实mybatis的本质就是一个常规JDBC的封装,添加了很多易用性的功能,它既是一个框架也可以算作一种规范了,不过不要被它限制死了,要学会使用它而不是被它使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用MyBatis的递归查询实现树形结构的查询。具体步骤如下: 1. 定义实体类 定义一个实体类,表示树的节点,包含节点id、父节点id、节点名称等属性。 2. 定义Mapper接口 定义一个Mapper接口,包含一个方法,用于查询树形结构的节点。方法的返回值为List集合,表示查询到的树形结构的节点。 3. 编写Mapper.xml配置文件 在Mapper.xml配置文件,编写递归查询语句,通过查询语句实现树形结构的查询。具体实现方式如下: - 定义一个select语句,用于查询指定节点的所有子节点。 - 在select语句使用union all关键字连接多个子查询语句,实现递归查询。 - 在子查询语句使用with recursive关键字定义递归查询语句。 4. 调用Mapper接口 在Java代码调用Mapper接口的方法,获取查询到的树形结构的节点。可以通过递归遍历节点,实现树形结构的展示。 下面是一个示例代码,供参考: ``` // 定义实体类 public class TreeNode { private Integer id; private Integer parentId; private String name; // getter和setter方法 } // 定义Mapper接口 public interface TreeNodeMapper { List<TreeNode> selectTreeNodes(Integer parentId); } // 编写Mapper.xml配置文件 <select id="selectTreeNodes" parameterType="java.lang.Integer" resultType="TreeNode"> with recursive cte(id, parent_id, name) as ( select id, parent_id, name from tree_node where parent_id = #{parentId} union all select tn.id, tn.parent_id, tn.name from tree_node tn inner join cte on tn.parent_id = cte.id ) select * from cte; </select> // 调用Mapper接口 @Autowired private TreeNodeMapper treeNodeMapper; public List<TreeNode> getTreeNodes(Integer parentId) { return treeNodeMapper.selectTreeNodes(parentId); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值