您的位置:首页 > 编程语言 > Java开发

Mybatis 优缺点,配置,使用,结合Spring使用,常见错误,代码自动生成(草稿)

2016-06-06 13:48 1016 查看
Copyright 2016 by 蔡舒啸 保持署名-非商业性使用-相同方式共享 Creative Commons BY-NC-ND 3.0

目录:

mybatiscfgxml模板

Mapperjava
 常见错误
orgapacheibatisexceptionsTooManyResultsException Expected one result or null to be returned by selectOne but found 16

Mapperxml
select返回多条记录映射到List

where子句传多个参数的3种写法

字符串模糊查询3种写法

Mybatis 从数据库表自动生成DaoMapperxml

Mybatis结合Spring

Mybatis的优势和缺点
优势

缺点

使用最新版Mybatis逐个验证以上优缺点

因为 mybatis 框架很简单,所以我只写了这一篇博文记录 mybatis 的配置和使用

配合mybaitis-generator代码自动生成Entity,xml,mapper类,比hibernate轻多了

项目环境:

Eclipse for J2EE

ant+ivy

jdk 6

mybatis 3.3.0

mybatis-spring 1.2.3

mybatis.cfg.xml模板

<?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>
<!-- changes from the defaults -->
<setting name="lazyLoadingEnabled" value="false" />
<!-- 表名重用预编译的SQL语句 -->
<setting name="defaultExecutorType" value="REUSE" />
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 查询时,关闭关联对象即时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="false" />
<!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 允许使用列标签代替列名 -->
<setting name="useColumnLabel" value="true" />
<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
<!-- <setting name="useGeneratedKeys" value="true" /> -->
<!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
<setting name="autoMappingBehavior" value="FULL" />
<!-- ========================================
对于批量更新操作缓存SQL以提高性能
<setting name="defaultExecutorType" value="BATCH" />
-->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 数据库超过25000秒仍未响应则超时 -->
<setting name="defaultStatementTimeout" value="25000" />
</settings>

<!-- 别名定义 -->
<typeAliases>
</typeAliases>

</configuration>


Mapper.java

package com.pingan.ebd.sp.dao.fang;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.pingan.ebd.sp.dto.icd.DishonestPersonInc;

public interface SpAccessLogMapper {
int insert(DishonestPersonInc record);

int insertSelective(DishonestPersonInc record);

DishonestPersonInc selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(DishonestPersonInc record);

int updateByPrimaryKey(DishonestPersonInc record);

List<DishonestPersonInc> selectByCompanyId(@Param(value="companyId")String companyId);
}


 常见错误

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 16

起初以为是映射SQL中返回resultType 或resultMap 写错了,一检查没有错,原来报错的是Mapper.java接口里的返回类型写错了

<select id="selectMusicByGeshou" parameterType="int" resultMap="com.ltkj.zhepg.karaoke.mapper.MusicMediaMapper.musicMediaResult">
select * from ok_music_media where geshou_id= #{geshouId}
</select>


应当写为List返回类型:

public List<GeShou> selectMusicByGeshou(int id) throws ApplyException;


Mapper.xml

SQL语句写在xml文件里,和项目源代码分离是mybatis的精髓,所以不要用新版mybatis的注解方式把SQL写到源代码里。

写代码时,可以把xml文件放在 项目/resource/ 路径下,用ant或maven打包时把xml文件copy到 AbcMapper.class 目录下。运行时 AbcMapper.xml 文件必须和 AbcMapper.class 在同一目录下。

具体使用方法http://blog.csdn.net/zhll3377/article/details/8203440

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.pingan.ebd.sp.dao.fang.SpAccessLogMapper" >
<!--===========================
resultMap标签的子标签: id和result标签的属性相同, 都有:

property
javaType
column
jdbcType
typeHandler

其中, org.apache.ibatis.type.JdbcType枚举类的全部类型, 参考API文档, 有

ARRAY BIGINT BINARY
BIT BLOB BOOLEAN
CHAR CLOB CURSOR
DATE DECIMAL DOUBLE
FLOAT INTEGER LONGVARBINARY
LONGVARCHAR  NCHAR  NCLOB
NULL NUMERIC NVARCHAR
OTHER REAL SMALLINT
STRUCT TIME TIMESTAMP
TINYINT UNDEFINED
VARBINARY VARCHAR
============================-->

<!--resultMap标签负责Java类和数据表的映射(ORM)-->
<resultMap id="result_SpAccessLog" type="com.pingan.ebd.sp.dto.fang.db.SpAccessLog" >
<id     column="access_id"
jdbcType="BIGINT"
property="id"
javaType="java.math.BigInteger"/> <!--用全称以免找Mybatis不到报错-->

<result column="arg"
jdbcType="VARCHAR"
property="sArg"
javaType="String"/>

<result column="timestamp_access"
jdbcType="TIMESTAMP"
property="timestamp_access"
javaType="java.sql.Timestamp"/> <!--用全称以免找Mybatis不到报错-->
</resultMap>
<sql id="Base_Column_List" >
id, entname, username, regno, entorgcode, offareacode, province, oriregno, regcapamt,
fctcapamt, regcapcur, opendate, rundatefrom, rundateto, enttype, runstatus, canceldate,
revokedate, address, allrunitem, runitem, busiscope1, busiscope2, regorg, chkyear,
industrycode, industryname, cocode, coname
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from ebd_icd_ent_exchange_info
where id = #{id,jdbcType=VARCHAR}
</select>
<select id="selectByName" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
id, entName, userName, regNo, entOrgCode, offAreaCode, province, oriRegNo, regCapAmt, fctCapAmt, regCapCur, openDate, runDateFrom, runDateTo, entType, runStatus, cancelDate, revokeDate ,address ,allRunItem, runItem, busiScope1, busiScope2, regOrg,chkYear,industryCODE,industryName,coCode,coName
from ebd_icd_ent_exchange_info
where 1=1
<if test="entName != null and entName!=''" >
and entName = #{entName,jdbcType=VARCHAR}
</if>
</select>
</mapper>


select返回多条记录映射到List

MyBatis默认是用List保存多条数据的。

你可以先用List保存下来之后,然后再写入数组呗。

public interface AbcMapper{
List<MyObject> query();
}


@Autowired //spring框架自动注入
AbcMapper abcMapper;

void queryDatabase(){
List<MyObject> list = abcMapper.query();
}


where子句传多个参数的3种写法

http://www.2cto.com/database/201409/338155.html

字符串模糊查询3种写法

http://blog.sina.com.cn/s/blog_667bef380101f2da.html

Mybatis 从数据库表自动生成Dao,Mapper,xml

转自http://www.cnblogs.com/smileberry/p/4145872.html

Mybatis结合Spring

Mybatis 3

Spring 4.2

http://www.tuicool.com/articles/BbAz6v/

原理:

只需要在 applicationConfiguration.xml 中使用

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="你的包路径.mapper" />
</bean>


自动加载 XxxxMapper.java。不需要手动配置 实体类的 bean, 因为加载 XxxxMapper.java 的过程中会自动加载实体类 Xxxxx.java。

Mybatis的优势和缺点

优势

转自http://www.tuicool.com/articles/Fj6zIb

MyBatis是一个混合型解决方案。它汲取了所有这些解决方案中最有价值的思想并将它们融会贯通

方案相同的优点解决的问题
存储过程MyBatis对 SQL 进行了封装和外部化 , 使 SQL 从你 的应用程序代码中分离出来。MyBatis 具有与存储 过程相似的 API但MyBatis 业务逻辑从数据库中分离出来,应用程序更容易部署与测试,也具有更好的可移植性
内联 SQLMyBatis允许 SQL 以其最自然的方式书写。没有字符串拼接,没有参数 “ 设置 ” , 没有结果 “ 获取 ”MyBatis对应用程序代码没有任何影响。不需要任何预编译器 , 并且你能够完全访问 SQL 的所有特性,而不只是一个子集
动态 SQLMyBatis提供了若干特性以支持基于参数的动态 构建査询。不需要 “ 査询构建工具”这样的 API MyBatis不要求 SQL 被写成一堆字符串的拼接,中间还夹杂着应用程序的代码
ORMMyBatis支持许多与 ORM 工具一样的特性,例如 延迟加载、连接抓取、高速缓存、运行时代码生成 以及继承MyBatis 可用于任意数据模型与任意对象模型的组合。它对这两者中的任何一个的设 计没有任何约束和要求
更多优点参考https://www.zhihu.com/question/21104468

mybatis 3.x.x 版本主要改动 http://zhaohe162.blog.163.com/blog/static/382167972011111114742371/

缺点

转自http://blog.csdn.net/wangpeng047/article/details/17039573

1. sql工作量很大,尤其是字段多、关联表多时,更是如此。

2. sql依赖于数据库,导致数据库移植性差。

3. 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。

4. 字段映射标签和对象关系映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。(比如配置了一对多Collection标签,如果sql里没有join子表或查询子表的话,查询后返回的对象是不具备对象关系的,即Collection的对象为null)

5. DAO层过于简单,对象组装的工作量较大。

6. 不支持级联更新、级联删除。

7. 编写动态sql时,不方便调试,尤其逻辑复杂时。

8 提供的写动态sql的xml标签功能简单(连struts都比不上),编写动态sql仍然受限,且可读性低。

9. 若不查询主键字段,容易造成查询出的对象有“覆盖”现象。

10. 参数的数据类型支持不完善。(如参数为Date类型时,容易报没有get、set方法,需在参数上加@param)

11. 多参数时,使用不方便,功能不够强大。(目前支持的方法有map、对象、注解@param以及默认采用012索引位的方式)

12. 缓存使用不当,容易产生脏数据。

使用最新版Mybatis逐个验证以上优缺点

先看文档, MyBatis3用户指南中文版

最新版 Mybatis 3.4.0 (截止2016-06-20)

先看看大版本更新日志的主要改动:

Mybatis 3.4.0

MyBatis 3.3.0

MyBatis 3.2.0

MyBatis 3.1.0

MyBatis 3.0.0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mybatis spring