同步操作将从 Java精选/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
一级缓存
Mybatis一级缓存是指SQLSession
一级缓存的作用域是SQlSession
Mabits默认开启一级缓存
同一个SqlSession中,执行相同的SQL查询时第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。
当执行SQL时两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。
每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。
Mybatis的内部缓存使用一个HashMap,其中key为hashcode+statementId+sql语句,Value为查询出来的结果集映射成的java对象。
SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。
二级缓存
二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。
第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放到mapper对应的二级缓存区域。
第二次调用namespace下的mapper映射文件中,相同的sql去查询用户信息,会去对应的二级缓存内取结果。
方式一:对于支持自动生成主键的数据库,如Mysql、sqlServer,可以通过Mybatis元素useGeneratedKeys返回当前插入数据主键值到输入类中。
<insert id="insertJingXuan" useGeneratedKeys="true" keyProperty="id"
parameterType="com.jx.domain.IdentityUser">
insert into identity_user(name)
values(#{name,jdbcType=VARCHAR})
</insert>
方式二:对于不支持自动生成主键的数据库。Oracle、DB2等,可以用元素selectKey回当前插入数据主键值到输入类中。
<insert id="insertJingXuan" useGeneratedKeys="true" keyProperty="id"
parameterType="com.jx.domain.IdentityUser">
<selectKey keyProperty="id" resultType="String" order="BEFORE">
SELECT REPLACE(UUID(),'-','')
</selectKey>
insert into identity_user(name)
values(#{name,jdbcType=VARCHAR})
</insert>
selectKey元素说明
keyProperty:selectKey语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn:匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
resultType:结果的类型。MyBatis通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的Object或一个Map。
order:这可以被设置为BEFORE或AFTER。如果设置为BEFORE,那么它会首先选择主键,设置keyProperty然后执行插入语句。如果设置为AFTER,那么先执行插入语句,然后是selectKey元素-这和像Oracle的数据库相似,在插入语句内部可能有嵌入索引调用。
statementType:MyBatis支持STATEMENT,PREPARED和CALLABLE语句的映射类型,分别代表PreparedStatement和CallableStatement类型。
Mybatis可以映射枚举类,不单可以映射枚举类,Mybatis可以映射任何对象到表的一列上。
映射方式为自定义一个TypeHandler,实现TypeHandler的setParameter()和getResult()接口方法。
TypeHandler有两个作用,一是完成从javaType至jdbcType的转换,二是完成jdbcType至javaType的转换,体现为setParameter()和getResult()两个方法,分别代表设置sql问号占位符参数和获取列查询结果。
方式一:Java代码中添加sql通配符
String mname = "%Java精选,微信公众号%";
List<UserInfo> list = mapper.selectUserInfo(mnane);
<select id="selectUserInfo">
select * from t_userinfo where name like #{mname}
</select>
方式二:sql语句中拼接通配符
String name = "Java精选,微信公众号";
List<UserInfo> list = mapper.selectUserInfo(nane);
<select id="selectUserInfo">
select * from t_userinfo where name like '%${name}%'
</select>
sql语句中拼接通配符需要注意sql注入的问题,在参数放入sql语句前校验是否合法。
Mybatis支持association关联对象和collection关联集合对象的延迟加载。
association指的就是一对一 collection指的就是一对多查询
在Mybatis配置文件中,启用延迟加载配置参数
lazyLoadingEnabled=true。
原理:使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法。
比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,就会单独发送事先保存好的查询关联B对象的SQL语句,先查询出B,然后再调用a.setB(b)赋值,最后再调用a.getB().getName()方法就有值了。几乎所有的包括Hibernate、Mybatis,支持延迟加载的原理都是一样的。
虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。
原理是Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。
1)Mybatis不完全是一个ORM框架,这是应为MyBatis需要开发人员自己来编写SQL语句。
2)Mybatis直接编写原生态SQL语句,可以严格控制SQL语句执行,其性能、灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套SQL映射文件,工作量大。
3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。
1)“#”符号将传入的数据当成一个字符串并将传入的数据加上双引号。
如:order by #{userId},如果传入的值是1,那么解析成sql时的值为order by "1",如果传入的值是userId,则解析成的sql为order by "userId"。
2)“$”符号将传入的数据直接显示生成在sql语句中。
如:order by ${userId},如果传入的值是1,那么解析成sql时的值为order by 1, 如果传入的值是userId,则解析成的sql为order by userId。
3)“#”符号能够很大程度防止sql注入,而“$”符号无法防止sql注入。
4)“$”符号方式一般用于传入数据库对象,例如传入表名。
5)一般能用“#”符号的就别用“$”符号
6)MyBatis排序时使用order by动态参数时需要注意使用“$”符号而不是“#”符号。
Mybatis中不同的Xml映射文件,如果配置了namespace,那么id可以重复;反之ID不能重复。
这是因为namespace+id是作为Map<String, MapperStatement>的key来使用,如果没有namespace空间,那么ID重复会导致数据互相覆盖。
通过设置namespace空间,ID相同但是namespace不同,namespace+id自然也就不同。目前新版本的namespace是必须的。
xml配置文件使用转义字符
SELECT * FROM test WHERE crate_time <= #{crate_time} AND end_date >= #{crate_time}
xml转义字符关系表
字符 | 转义 | 备注 |
---|---|---|
< | < | 小于号 |
> | > | 大于号 |
& | & | 和 |
' | ' | 单引号 |
" | " | 双引号 |
注意:XML中只有”<”和”&”是非法的,其它三个都是合法存在的,使用时都可以把它们转义了,养成一个良好的习惯。
转义前后的字符都会被xml解析器解析,为了方便起见,使用
<![CDATA[...]]>
来包含不被xml解析器解析的内容。标记所包含的内容将表示为纯文本,其中...表示文本内容。
但要注意的是:
1)此部分不能再包含”]]>”;
2)不允许嵌套使用;
3)”]]>”这部分不能包含空格或者换行。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。