MyBatis最简单的实例也已跑通,实现了增删改查,涉及到复杂情况就是两眼一抹黑。这篇主要讲讲参数配置,方便后期项目,我这里没有从头到尾地去讲每个参数的使用,而是在实际使用中遇到了问题才会去看,故可能没法给您提供有效的帮助。
参数表参考自:http://blog.csdn.net/chris_mao/article/details/48804493
设置参数描述有效值默认值 cacheEnabled 该配置影响的所有映射器中配置的缓存的全局开关。 true | false true lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 true | false false aggressiveLazyLoading 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。 true | false true multipleResultSetsEnabled 是否允许单一语句返回多结果集(需要兼容驱动)。 true | false true useColumnLabel 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 true | false true useGeneratedKeys 允许 JDBC 支持自动生成主键(使用jdbc的getGenereatedKeys方法获取主键并赋值到keyProperty设置的属性中,useGeneratedKeys="true"时,keyProperty也必须同时设置),需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 true | false false autoMappingBehavior 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 NONE, PARTIAL, FULL PARTIAL defaultExecutorType 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 SIMPLE REUSE BATCH SIMPLE defaultStatementTimeout 设置超时时间,它决定驱动等待数据库响应的秒数。 Any positive integer Not Set (null) defaultFetchSize Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a query setting. Any positive integer Not Set (null) safeRowBoundsEnabled 允许在嵌套语句中使用分页(RowBounds)。 true | false False mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 true | false False localCacheScope MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 SESSION | STATEMENT SESSION jdbcTypeForNull 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER OTHER lazyLoadTriggerMethods 指定哪个对象的方法触发一次延迟加载。 A method name list separated by commas equals,clone,hashCode,toString defaultScriptingLanguage 指定动态 SQL 生成的默认语言。 A type alias or fully qualified class name. org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver callSettersOnNulls 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 true | false false logPrefix 指定 MyBatis 增加到日志名称的前缀。 Any String Not set logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING Not set proxyFactory 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。 CGLIB | JAVASSIST JAVASSIST (MyBatis 3.3 or above) vfsImpl Specifies VFS implementations Fully qualified class names of custom VFS implementation separated by commas. Not set
1.主键自增长:
见过多数教程都说自增长要加useGeneratedKeys="true"和keyProperty="主键字段",然而MySQL在对表设置了auto_increment之后即可实现自增长,那么为何要用useGeneratedKeys="true"和keyProperty属性呢?
答:加了useGenerateKeys=“true”和keyProperty可返回插入数据后的主键,参考自:http://www.cnblogs.com/lilh/archive/2016/05/23/5521271.html
int pk = sqlSession.insert("UserMapper.insertUser",user1); System.out.println("输出:"+pk);
不管是否设置useGenerateKeys="true"都返回1,这个1为操作的记录条数;
要返回主键用操作的对象get该主键,例如:System.out.println("我才是主键:"+ user1.getId());
useGenerateKeys="false"则user1.getId()返回0;
[plain] view plain copy <insert id="insertUser" parameterType="sysUser" useGeneratedKeys="true" keyProperty="id"> insert into `user`(userName, birthday, salary, address) values(#{userName}, #{birthday}, #{salary}, #{address}) </insert>至于另一种方式适用于解决Insert数据时不支持主键自动生成的问题,例如Oracle,参考自:http://blog.csdn.net/isea533/article/details/21153791(这个比较详细):
[plain] view plain copy <insert id="insert" parameterType="map"> insert into table1 (name) values (#{name}) <selectKey resultType="java.lang.Integer" keyProperty="id"> CALL IDENTITY() </selectKey> </insert>2.实体类属性和表字段不一致:
表结构:
[sql] view plain copy CREATE TABLE `user` ( `id` INT(11) PRIMARY KEY AUTO_INCREMENT, `user_name` VARCHAR(50), `birthday` DATE, `salary` DECIMAL(8,2), `address` VARCHAR(200) ) ENGINE=INNODB CHARSET=utf8;实体类属性:
[java] view plain copy public class Users { private int id; private String userName; private Date birthday; private Double salary; private String address; ... }类的配置文件修改
[plain] view plain copy <insert id="insertUser" parameterType="sysUser" useGeneratedKeys="true" keyProperty="id"> insert into `user`(user_name, birthday, salary, address) values(#{userName}, #{birthday}, #{salary}, #{address}) </insert>发现直接这样对应就可以解决类属性和表字段不一致的问题,那么什么时候才需要在类的配置文件中设置resultMap呢?
答:insert sql语句中values与表字段一一对应所以不存在相关问题,其它方式sql语句没有对应的情况则
查询中出现的问题:
[plain] view plain copy <select id="findUserById" parameterType="int" resultType="sysUser"> select * from `user` where id = #{id} </select>返回记录的user.getUserName() == null(没报错,由于实体类属性和数据表字段无法对应出现的问题) 第一种方法:对sql语句的表字段取别名,字段别名与实体类属性一致即可(如果我要查询全表字段,字段一致的也要列出来,会比较烦);
[plain] view plain copy <select id="findUserById" parameterType="int" resultType="sysUser"> select user_name userName, address from `user` where id = #{id} </select>第二种方式:在类配置文件mapper内设置resultMap;
[plain] view plain copy <!--通过<resultMap>映射实体类属性名和表的字段名对应关系 --> <resultMap type="com.chensan.sys.Users" id="sysUser"> <!-- 用id属性来映射主键字段 --> <id property="id" column="id"/> <!-- 用result属性来映射非主键字段 --> <result property="userName" column="user_name"/> </resultMap>然后第二种方式测出的结果user.getUserName() == null,搞了半天发现resultType需要改成resultMap,真的是要抽自己;
[plain] view plain copy <select id="findUserById" parameterType="int" resultMap="sysUser"> select * from `user` where id = #{id} </select>