1.mybatis-config.xml中的配置概览
1.1 settings详解
1.1.1 cacheEnabled详解(二级缓存)
Mybatis默认开启一级缓存;二级缓存默认开启,可设置。
开启二级缓存:
- 在mybatis全局配置中settings中设置 cacheEnabled为true
- 在mpper.xml中写入<cache></cache>
1.1.2 lazyLoadingEnabled 和aggressiveLazyLoading 使用详解
lazyLoadingEnabled=true,开启延迟加载
aggressiveLazyLoading =true时,如果对象 User里面有延迟属性Sex,当调用User.getName()时,则延迟属性加载。
aggressiveLazyLoading =false时,如果对象 User里面有延迟属性Sex,当调用User.getName()时,则延迟属性不加载,调用 User.getSex()的时候,延迟属性才加载
1.2 typeAliases详解
在 MyBatis 的 sql 映射配置文件中,需要使用 paramterType、resultType 来设置 sql 语句的输入输出参数,一般参数都是基本的数据类型或封装类型,但都需要声明该类型的全路径,java.lang.String,或者 cn.com.mybatis.pojo.User, 这时就可以通过 typeAliases 别名来设置,简化复杂度。
1.当没有配置别名的时候,就需要输入全限定名称,特别不方便
<select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.com.mybatis.pojo.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
2.配置了typeAliases后
<typeAliases>
<typeAlias alias="user" type="cn.com.mybatis.pojo.User"/>
<typeAlias alias="str" type="java.lang.String"/>
</typeAliases>
就可以只输入别名,这样带来了极大的便利
<select id="findUserByUsername" parameterType="str" resultType="user">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
3.为每个类都取别名,这样会比较麻烦,可以使用包扫描的方式
<typeAliases>
<package name="cn.com.mybatis.pojo"/>
</typeAliases>
4.也可以通过在类上,注解的方式,来达到取别名的效果
@Alias("user")
public class User{
...........
}
5.mybatis为常见默认类型都指定了别名,这里直接使用即可
贴上Mybatis部分源码:
public TypeAliasRegistry() {
registerAlias("string", String.class);
registerAlias("byte", Byte.class);
registerAlias("long", Long.class);
registerAlias("short", Short.class);
registerAlias("int", Integer.class);
registerAlias("integer", Integer.class);
registerAlias("double", Double.class);
registerAlias("float", Float.class);
registerAlias("boolean", Boolean.class);
registerAlias("byte[]", Byte[].class);
registerAlias("long[]", Long[].class);
registerAlias("short[]", Short[].class);
registerAlias("int[]", Integer[].class);
registerAlias("integer[]", Integer[].class);
registerAlias("double[]", Double[].class);
registerAlias("float[]", Float[].class);
registerAlias("boolean[]", Boolean[].class);
registerAlias("_byte", byte.class);
registerAlias("_long", long.class);
registerAlias("_short", short.class);
registerAlias("_int", int.class);
registerAlias("_integer", int.class);
registerAlias("_double", double.class);
registerAlias("_float", float.class);
registerAlias("_boolean", boolean.class);
registerAlias("_byte[]", byte[].class);
registerAlias("_long[]", long[].class);
registerAlias("_short[]", short[].class);
registerAlias("_int[]", int[].class);
registerAlias("_integer[]", int[].class);
registerAlias("_double[]", double[].class);
registerAlias("_float[]", float[].class);
registerAlias("_boolean[]", boolean[].class);
registerAlias("date", Date.class);
registerAlias("decimal", BigDecimal.class);
registerAlias("bigdecimal", BigDecimal.class);
registerAlias("biginteger", BigInteger.class);
registerAlias("object", Object.class);
registerAlias("date[]", Date[].class);
registerAlias("decimal[]", BigDecimal[].class);
registerAlias("bigdecimal[]", BigDecimal[].class);
registerAlias("biginteger[]", BigInteger[].class);
registerAlias("object[]", Object[].class);
registerAlias("map", Map.class);
registerAlias("hashmap", HashMap.class);
registerAlias("list", List.class);
registerAlias("arraylist", ArrayList.class);
registerAlias("collection", Collection.class);
registerAlias("iterator", Iterator.class);
registerAlias("ResultSet", ResultSet.class);
}
<select id="selectByPrimaryKey" parameterType="Integer" resultType="TUser">
select * from t_user where id=#{id}
</select>
因为有一些基本数据类型和包装类型的名称一样(例如基本数据类型 byte 和包装类型 java.lang.Byte),所以在基本的数据类型前面加了下划线 “_” 来以此区分(byte 别名就是_byte,java.lang.Byte 别名就是 byte).
但是由于基本类型自动拆箱,装箱特性,"int","_int","_Integer","_integer","integer","Integer"的效果是一样的。
对于其他的 比如 hashMap,就只有 HashMap,和hashMap能生效
1.3 environments的详解
<!--配置environment环境 -->
<environments default="development">
<!-- 环境配置1,每个SqlSessionFactory对应一个环境 -->
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="UNPOOLED">
<property name="driver" value="${jdbc_driver}" />
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_username}" />
<property name="password" value="${jdbc_password}" />
</dataSource>
</environment>
</environments>
environment 元素是配置一个数据源的开始,属性id是它的唯一标识
transactionManager 元素配置数据库事务,其中type属性有三种配置方式
jdbc,采用jdbc的方式管理事务
managed,采用容器的方式管理事务,在JNDI数据源中使用;
自定义,自定义数据库事务管理办法;
dataSource 元素配置数据源连接信息,type属性是连接数据库的方式配置,有四种配置方式
UNPOOLED 非连接池方式连接
POOLED 使用连接池连接
JNDI 使用JNDI数据源
自定义数据源
1.4 mappers 详解
<!-- 映射文件,mapper的配置文件,一共3种方法,任选一种 -->
<mappers>
<!-- 方法1 在classpath下资源引用(也就是把*Mppper.xml放在src/main/resources下)-->
<mapper resource="sqlmapper/TUserMapper.xml" />
<mapper resource="sqlmapper/TSexMapper.xml" />
<!-- 方法2 通过类扫描mapper文件 -->
<!-- <mapper class="com.mybatis.mapper.TUserMapper" /> -->
<!-- <mapper class="com.mybatis.mapper.TSexMapper" /> -->
<!-- 方法3 扫描包下所有的mapper文件 -->
<!-- <package name="com.enjoylearning.mybatis.mapper"/> -->
</mappers>
2.*Mapper.xml中的配置
2.1 总览
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句 update – 映射更新语句
delete – 映射删除语句 select – 映射查询语句
2.1.1 resultMap详解
看代码比较直观,其中 在 association中的 column对应的是 TSex中所在表的id,而collection中的column对应的是TUser所在表的id
<resultMap id="BaseResultMap" type="TUser">
<!-- constructor,在某种业务下,该类不具有无参构造函数的时候,需要用到这个属性
<constructor>
<idArg column="id" javaType="int"/>
<arg column="user_name" javaType="String"/>
</constructor>
-->
<id column="id" property="id" jdbcType="INTEGER" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<!-- 在数据表中一对一的关系会使用到 association -->
<association property="sex" column="sex_id" javaType="TSex"
select ="com.mybatis.mapper.TSexMapper.selectById">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR"/>
</association>
<!-- 在数据表中一对多的关系会使用到 collection -->
<collection property="userRoles" select ="com.mybatis.mapper.TUserRoleMapper.selectById"
ofType="TUserRole" column="id">
<result column="role_id" property="id" />
<result column="role_name" property="name" />
</collection>
</resultMap>
2.1.2 select标签详解
2.1.3 insert, update 和 delete
在mysql中,表如果选择了自增主键,在insert标签中 设置了 useGeneratedKeys 则会自动为这条记录插入一个id,代码中不需要设置id。
而在插入之后 可以通过keyProperty获得由数据库产生的id。
TUser user = new TUser();
user.setUserName("张三");
userMapper.insert(user);
System.out.println(user.getId());
<insert id="insert" useGeneratedKeys ="true" keyProperty="id" parameterType="TUser">
insert into t_user (id,user_name) values (#{id},#{userName})
</insert>
2.1.4 selectKey
<insert id="insert" parameterType="TUser">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select
LAST_INSERT_ID()
</selectKey>
insert into t_user (id,user_name) values (#{id},#{userName})
</insert>
selectKey也可以达到useGenerateKeys的效果,并且可以支持oracle的序列
<selectKey keyProperty=“id” order= " Before" resultType="int"> select SEQ_ID.nextval from dual </selectKey>
2.1.4 动态sql
<!--
4.3.1 where用法
<where>标签的作用:如果该便签包含的元素中有返回值,就插入一个where;如果
where后面的字符串是一and或or开头的,就将它们剔除掉。
案例分析
当if条件不满足的时候,where元素中没有任何内容,所以SQL中不会出现where,也就
不存在4.1.1节中的SQL错误的问题。如果if条件满足,where元素的内容就是以and开
头的条件,where会主动去掉开头的and,这也能保证where条件正确。
——很尴尬的一点,这样的化,反倒会将整张表都给查出来。。。
-->
<select id="selectByUser" resultType="tk.mybatis.simple.model.SysUser">
SELECT id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo,
head_img headImg,
create_time createTime
FROM sys_user
<where>
<if test="userName != null and userName != ''">
AND user_name LIKE CONCAT('%',#{userName},'%')
</if>
<if test="userEmail != null and userEmail != ''">
AND user_email = #{userEmail}
</if>
</where>
</select>
<!--
4.3.2 set用法
<set>标签的作用:如果该标签包含的元素中有返回值,就插入一个set;如果set
后面的字符串是以逗号结尾的,就将这个逗号剔除掉。
-->
<update id="updateByIdSelective">
UPDATE sys_user
<set>
<if test="userName != null and userName != ''">
user_name = #{userName},
</if>
<if test="userPassword != null and userPassword != ''">
user_password = #{userPassword},
</if>
<if test="userEmail != null and userEmail != ''">
user_email = #{userEmail},
</if>
<if test="userInfo != null and userInfo != ''">
user_info = #{userInfo},
</if>
<if test="headImg != null">
head_img = #{headImg,jdbcType=BLOB},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
id=#{id}
</set>
WHERE id=#{id}
</update>
<!--
4.3.3 trim用法
<where>和<set>标签都可以用trim标签实现,并且底层就是通过TrimSqlNode实现的
<where>标签对应的trim实现:
<trim prefix="WHERE" prefixOverride="AND |OR ">
<set>标签对应的trim实现:
<trim prefix="SET" suffixOverrides=",">
提示:
prefixOverride中AND和OR后面的空格不能省略,为了避免匹配到andes或
orders等单词。实际上prefixOverride包含"AND""OR""AND\n""OR\n"
"AND\r""OR\r""AND\t""OR\t"
<trim>标签属性:
prefix:当trim元素包含内容时,会给内容增加prefix指定的前缀
prefixOverride:当trim元素包含内容时,会把内容中匹配的前缀字符串去掉。
suffix:当trim元素包含内容时,会给内容增加prefix指定的后缀
suffixOverride:当trim元素包含内容时,会把内容中匹配的后缀字符串去掉。
-->
批量操作
通过foreach动态拼装SQL语句
使用BATCH类型的excutor
后记: