ibatis学习
SQLMapXMLFiles
ibatis最⼤的优点就是可以把sql语句移到xml⽂件中,SQLMapXMLFiles包含如下⼏个元素:
cache:配置命名空间内的缓存机制
cache-ref:引⽤两⼀个命名空间的缓存配置
resultMap:获取数据库结果集时转化为对象的映射
sql:sql命令
inrt:inrt语句配置
update:update语句配置
delete:delete语句配置
lect:lect语句配置
lect
Xml代码
SELECT*FROMPERSONWHEREID=#{id}
lect>
定义了⼀个名称为lectPerson的⽅法,包含⼀个int类型的形参,返回⼀个由列名和值⽣成的哈希表
注意这⾥的#{id},实际上ibatis创建了⼀个PreparedStatement去处理这种参数,类似的jdbc代码如下:
//SimilarJDBCcode,NOTiBATIS…
Java代码
StringlectPerson=“SELECT*FROMPERSONWHEREID=?”;
PreparedStatementps=eStatement(lectPerson);
(1,id);
lect标签还有很多的可配置属性:
Xml代码
id=”lectPerson”
parameterType=”int”
parameterMap=”deprecated”
resultType=”hashmap”
resultMap=”personResultMap”
flushCache=”fal”
uCache=”true”
timeout=”10000”
fetchSize=”256”
statementType=”PREPARED”
resultSetType=”FORWARD_ONLY”
>
属性描述
id命名空间中唯⼀标识sql语句的标识符
parameterTypesql语句中的参数类型
resultTypesql语句返回类型(与resultMap只能使⽤⼀个)
resultMap引⽤外部resultMap(与resultType只能使⽤⼀个)
flushCache设置⽴即输出缓存中数据默认fal
uCache设置是否使⽤缓存默认true
timeout设置数据库超时时间默认根据数据库驱动⽽定
fetchSize⼀次抓取数据量默认根据数据库驱动⽽定
statementType可以设置为STATEMENT,PREPARED,CALLABLE,默认为PREPARED,像在调⽤存储过程时就可以使⽤
CALLABLE类型
resultSetType结果集类型,主要是说游标,具有⽅向性,可以去FORWARD_ONLY、SCROLL_SENSITIVE、
SCROLL_INSENSITIVE默认根据数据库驱动⽽定
inrt,update,delete
Xml代码
id="inrtAuthor"
parameterType=""
flushCache="true"
statementType="PREPARED"
keyProperty=""
uGeneratedKeys=""
timeout="20000">
id="inrtAuthor"
parameterType=""
flushCache="true"
statementType="PREPARED"
timeout="20000">
id="inrtAuthor"
parameterType=""
flushCache="true"
statementType="PREPARED"
timeout="20000">
属性描述
id命名空间中唯⼀标识sql语句的标识符
parameterTypesql语句中的参数类型
flushCache设置⽴即输出缓存中数据默认fal
timeout设置数据库超时时间默认根据数据库驱动⽽定
uGenerateKeys(inrt)是否使⽤数据库⾃动⽣成的键(如⾃增列)默认fal
statementType可以设置为STATEMENT,PREPARED,CALLABLE,默认为PREPARED,像在调⽤存储过程时就可以使⽤
CALLABLE类型
keyProperty(inrt)将数据库⾃动⽣成的键值赋值给哪⼀个字段值
Xml代码
inrtintoAuthor(id,urname,password,email,bio)
values(#{id},#{urname},#{password},#{email},#{bio})
inrt>
uGeneratedKeys=”true”keyProperty=”id”>
inrtintoAuthor(urname,password,email,bio)
values(#{urname},#{password},#{email},#{bio})
inrt>
updateAuthort
urname=#{urname},
password=#{password},
email=#{email},
bio=#{bio}
whereid=#{id}
update>
deletefromAuthorwhereid=#{id}
delete>
ibatis还对不⽀持⾃动⽣成主键值的数据库提供了主键值⽣成⽅案,如下是⼀个随机数主键值:
Xml代码
lectCAST(RANDOM()*1000000asINTEGER)MY1
lectKey>
inrtintoAuthor
(id,urname,password,email,bio,favourite_ction)
values
(#{id},#{urname},#{password},#{email},#{bio},
#{favouriteSection,jdbcType=VARCHAR}
)
inrt>
关于lectKey详细属性说明如下:
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
属性描述
keyProperty语句返回值的赋值对象
resultType返回类型
order可以设置为BEFORE、AFTER。如果是BEFORE,会先lect键值,赋值键值然后执⾏inrt语句。如果是AFTER,那么会先执⾏
inrt语句之后再lect。默认AFTER
statementType可以设置为STATEMENT,PREPARED,CALLABLE,默认为PREPARED,像在调⽤存储过程时就可以使⽤
CALLABLE类型
sql
定义重⽤的sql代码
Xml代码
lect
fromsome_table
whereid=#{id}
lect>
Parameters
简单类型传参
传递⼀个int值给sql语句
Xml代码
lectid,urname,password
fromurs
whereid=#{id}
lect>
对象传参
将ur对象的idurnamepassword属性传递给sql语句
Xml代码
inrtintours(id,urname,password)
values(#{id},#{urname},#{password})
inrt>
定义特殊传参类型
#{property,javaType=int,jdbcType=NUMERIC}
注意,使⽤这种⾃定义类型转换时,jdbcType必须传递⾮空字段的值。
(⽹上查阅了⼀下,很多资料说ibatis对于null处理不好,发现lect语句数据库中有null时基本没问题,⽽inrt语句参数不能为null,原
因是ibatis的赋值时有个java类型到数据库类型的转换,根据参数调⽤不同的转换器类型,null的话ibatis就⽆法识别参数类型,需要在
sqlMap配置⽂件中显式说明参数类型,如:#{score:INTEGER}或者#{score,jdbcType=INTEGER})
对于NUMERIC类型,还有numericScale可以设置
#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}
可以设置IN、OUT、INOUT参数类型
#{department,
mode=OUT,
jdbcType=CURSOR,
javaType=Department,
resultMap=departmentResultMap}
resultMap
Xml代码
lectid,urname,hashedPassword
fromsome_table
whereid=#{id}
sql>
这种hashmap的返回类型将所有的字段以字段名为key的hashMap返回,但是这样⼦并不是很好的对域中的对象进⾏映射,我们考虑下⾯
这个POJO:
Java代码
publicclassStudent{
privateintid;
privateStringname;
privateStringmajor;
privateDatebirth;
privatedoublescore;
}
我们之前使⽤的lect语句配置是:
lect*fromStudentwhereid=#{id}
lect>
这⾥ibatis默认使⽤表列名和POJO属性名对应的规则给属性赋值,我们也可以指定这种映射关系
Xml代码
lect
table_idas"id",
table_nameas"name",
table_majoras"major",
table_birthas"birth",
table_scoreas"score"
fromStudentwhereid=#{id}
lect>
这⾥我们引进resultmap,可以对这种映射关系进⾏复⽤
Java代码
resultMap>
lect
idas"id",
nameas"name",
majoras"major",
birthas"birth",
scoreas"score"
fromStudentwhereid=#{id}
lect>
引⽤
注意如果是查询返回了多个结果集合,那么ibatis会返回⼀个集合,如:
lect*fromStudent
lect>
可以使⽤List接受ibatis返回的结果集合
List
再来看⼀个复杂⼀点的映射
Java代码
lect
og_id,
sblog_title,
_idasblog_author_id,
thor_id,
measauthor_urname,
rdasauthor_password,
sauthor_email,
uthor_bio,
ite_ctionasauthor_favourite_ction,
st_id,
_idaspost_blog_id,
_idaspost_author_id,
d_onaspost_created_on,
naspost_ction,
taspost_subject,
sdraft,
post_body,
mment_id,
_idascomment_post_id,
comment_name,
tascomment_text,
g_id,
tag_name
fromBlogB
_id=
=_id
=_id
leftouterjoinPost__id=
_id=
=#{id}
lect>
constructor>
association>
collection>
collection>
discriminator>
collection>
resultMap>
下⾯具体来看看resultMap的⼦元素
constructor:⽤于在类构造函数中注⼊参数
idArg:ID参数⽤于提⾼整体性能
arg:普通参数
id:ID结果
result:注⼊POJO属性的结果值
association:复杂的类型关联
collection:复杂类型集合
discriminator:根据结果值决定使⽤哪个resultMap
ca:判断条件
详细说明各个元素的作⽤:
id,result:
Java代码
id,result均将单个列的值映射到POJO中的单个简单类型属性(如int,double,Date等等)
id映射主键,result映射普通属性
属性描述
propertyPOJO中对应的属性
column数据库中列名
javaTypejava类型
jdbcTypejdbc类型遇到空值时需要显⽰指明
typeHandler类型转换器
⽀持的jdbcTypes
BITFLOATCHARTIMESTAMPOTHERUNDEFINED
TINYINTREALVARCHARBINARYBLOBNVARCHAR
SMALLINTDOUBLELONGVARCHARVARBINARYCLOBNCHAR
INTEGERNUMBERICDATELONGVARBINARYBOOLEANNCLOB
BIGINTDECIMALTIMENULLCURSOR
Java代码
constructor:
constructor>
constructor属性可以配置通过类构造函数注⼊属性的⼀些参数。考虑Ur类这个构造函数
publicclassUr{
//…
publicUr(intid,Stringurname){
//…
}
//…
}
为了实现这种注⼊,ibatis需要表明构造函数的各个参数类型,正如上⾯的xml代码段所⽰。保证配置参数按照构造函数中参数的顺序进⾏
配置参数类型
属性描述
column数据库中列名
javaTypejava类型
jdbcTypejdbc类型遇到空值时需要显⽰指明
typeHandler类型转换器
association:
Java代码
association>
association标签定义了实体之间的关联,⽐如blog拥有⼀个作者属性,那么这来两个实体之间就可以⽤上⾯那个关系来定义。
属性描述
property列映射的POJO属性
column关联的列名
javaTypejava类型
jdbcTypejdbc类型遇到空值时需要显⽰指明
typeHandler类型转换器
ibatis有两种加载关联关系的⽅法:
NestedSelect:
属性描述
lect另⼀个加载数据的sql语句id
例如:
Java代码
lect=”lectAuthor”/>
resultMap>
SELECT*FROMBLOGWHEREID=#{id}
lect>
SELECT*FROMAUTHORWHEREID=#{id}
lect>
在这⾥我们有两个lect语句,⼀个去加载blog数据,另⼀个去加载author数据,在blog定义的resultMap中使⽤了加载author的lect
语句,对blog中的author属性进⾏赋值。也就是说,这种简单的⼀对⼀关系,执⾏了两条lect语句。
使⽤nestedlect会产⽣“N+1”问题,⾮常常见,性能消耗相当⼤,可以使⽤懒加载来解决,或者使⽤下⾯⼀种⽅法。
NestedResult:
属性描述
resultMap映射关联属性字段的resultMapid值,采⽤join的⽅式⼀次查询得出结果
例如:
Java代码
resultMap=”authorResult”/>
resultMap>
resultMap>
或者:
Java代码
association>
resultMap>
在lect语句中使⽤:
Java代码
lect
og_id,
sblog_title,
_idasblog_author_id,
thor_id,
measauthor_urname,
rdasauthor_password,
sauthor_email,
uthor_bio
_id=
=#{id}
lect>
collection:
Java代码
collection>
collection对应POJO中的集合属性,如:
privateListposts;
collection元素的关联加载
NestedlectforCollection:
Java代码
ofType="Post"lect=”lectPostsForBlog”/>
resultMap>
SELECT*FROMBLOGWHEREID=#{id}
lect>
SELECT*FROMPOSTWHEREBLOG_ID=#{id}
lect>
NestedresultsforCollection:
Java代码
collection>
resultMap>
在lect语句中使⽤:
Java代码
lect
og_id,
sblog_title,
_idasblog_author_id,
st_id,
taspost_subject,
post_body,
fromBlogB
=_id
=#{id}
lect>
discriminator:
discriminator>
有时候我们从数据库中得到的值不仅仅对应⼀种POJO,可能根据参数不同对应不懂的POJO,如车辆的属性根据卡车、汽车⽽不同,那么
可以使⽤以下配置
Java代码
discriminator>
resultMap>
cache:
ibatis中可以使⽤cache提⾼效率,默认不开启cache配置,需要使⽤标签,其默认含义为:
所有lect语句返回的数据将被缓存
inrtupdatedelete语句将会强制输出缓存
使⽤LRU算法
没有强制输出的周期(NoFlushInterval)
缓存区⼤⼩为1024条记录或者对象的引⽤
可读写的缓存,缓存中的数据可以被调⽤它的函数修改
也可以⼿动设置这些配置属性,例如:
Java代码
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
上⾯的配置说明了使⽤FIFO缓存机制,每60秒输出⼀次缓存,缓存区⼤⼩为512,缓存中的数据是只读的。
缓存过期算法:
LRU最近最少使⽤
FIFO先进先出
SOFT只有当⽬前内存不⾜的情况下,JVM在垃圾回收时才会收回其包含的引⽤
WEAK只要JVM启动了垃圾回收机制,那么WeakReference所对应的对象就将被JVM回收
cache的使⽤机制和sqlMapFile的命名空间是绑定的。
本文发布于:2022-12-28 00:41:51,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/43662.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |