2020-10-26
因工作需要经过两天IBatis学习,总结如下(部分转载)
客户端–表现层/客户端–服务层–持久层/DAO层–数据库
SpringMVC Service IBatis
前端展示 逻辑处理 交互数据
半自动的数据访问工具,sql需要自己写参数需要自己配。轻量级,仅需iBatis的一个jar和数据库的驱动即可运行
ibatis需要:.java 与表相对应的java实体类
.properties 连接配置Jdbc
.xml 配置DAO中调用的节点id,sql语句中传入的参数,结果集的封装类
Config.xml 总配置文件 引入所有的配置文件,配置框架的数据源等
🔺🔺
ibatis 常用标签:
🔺一级标签(根标签)及查询:
属性:
namespace:用于指定命名空间,在java程序段可以使用命名空间.标签id的形式来调用相应的sql语句-------使用方法 🔺
~例子1:
//设置别名方便使用
//ZZYY01.getAllUsers 调用本sql 结果集为User
select * //带参时可设置属性parameterClass=“java.lang.String”
from users
标签是设置别名用的,这里我们使用了一个Bean叫做User,声明别名后,在文件的后续部分可以直接使用别名而不用再给出完整类型了,
非常方便,如select标签中的resultClass属性。
的id是标识该SQL语句的标识符,要在应用程序中使用到,必须唯一。带参数时设置parameterClass,就是参数类型。
resultClass配置我们使用的是Bean作为返回的结果类型,当然也可以使用Map,非常灵活。Select标签体内的部分就是SQL语句了。
~例子2:带参数
select *
from users
where USERNAME=#VARCHAR# //#参数按字符串传入相当于变量替换,$是将参数直接传入相当于是字符串的拼接,又sql注入的安全风险不使用
数据库字段名全部大写,而传递的变量名采用小写方式,这样可以很清楚地辨别对应关系
~例子3:带多个参数
select *
from users
where REALNAME=#realName:VARCHAR# and MOBILE=#mobile:VARCHAR#
有一个参数时我们在XML中配置parameterClass写这种参数的类型就可以了,但是多个参数时却不能在parameterClass中写一串类型,
那么就需要抽象出一种数据结构来传递参数,很自然想到了HashMap,这种键值对形式的结构非常适合同名参数的传递。
~ParameterMap
public static void main(String[] args) throws SQLException {
ParameterMap parameterMap = new ParameterMap(“realName”, “sarin”,“mobile”, “15940990000”);
System.out.println(select(parameterMap));
}
public static HashMap select(Map parameterMap) throws SQLException {return (HashMap) sqlMap.queryForObject(“getUserByRealNameAndMobile”,
parameterMap);
}
sqlMap完成后的程序写起来也很简单,首先是加载iBatis的配置文件,然后使用SqlMapClient接口提供的方法进行数据操作即可。
🔺二级标签:
1.、、、、、
的作用如下
select * from users
<![CDATA[ where age > #value:INT# ]]>
操作代码:
List users = sqlMap.queryForList(“User.getUserAgeOver”,“23”);
System.out.println(users);
int userCount = (Integer) sqlMap.queryForObject(“User.getUserCountAgeOver”, “22”);
System.out.println(userCount);
2.
判断所传入参数是否为null或者为空。如果是empty,那么就将传入参数拼入sql语句。
属性:
prepend:拼接sql的前缀。
property:对应于java的属性
close和 open:包括拼接的sql
3.
与相反,判断传入参数是否不为空也不为null。如果不为null和空,那么就将参数拼接到sql中。
属性:
prepend:拼接sql的前缀。
property:对应于java的属性
close和open:包括拼接的sql
4.可以去除第一个prepend="and"中的字符(这里为and),从而可以帮助你实现一些很实用的功能。具体情况如下:
select * from Person表
name=#name#
sex=#sex#
当name、sex都非null时打出如下的sql语句:
select Person表 where (and) name= ? , and sex= ? 显然name前的and被自动去除了,很方便吧。若不使用
select * from Person表 WHERE 1=1
name=#name#
sex=#sex#
当name、sex都非null时打出如下的sql语句:select Person表 where and name= ? , and sex= ?显然name前多个and,sql语句错误。
dynamic 会自动去除第一个 prepend="and中的内容(这里为and),从而方便一些操作。
5.、、 空非空 参数与指定值是否相等
,,, 大于等于,大于,小于等于,小于
、、<isNotPropertyAvalible>
6.
配置在resultMap下,用于指定结果集中的每一项。
属性:
property:对应于要输出的字段名,在java程序段可以通过这个属性值获得相应的值
colunm:对应于数据表的字段
columIndex:对应于数据表字段的索引
jdbcType:仅当增删改是可能出现null值的字段,可以设置jdbcType。当该result为DATE类型时,指定jdbcType可以更加明确sql。因为DATE在java里是一种类型,但是在不同的数据库有不同的DATE类型。
javaType:对应于java的类型。如果在sql中使用了聚合函数,需要在对应的result中配置该属性,否则取出的是聚合函数的对象,显示出的就是java对象的哈希值。
nullValue:空值。
7.
用于循环输出,以便循环的生成sql。
属性:
property:对于要输出的集合
open和close:用于开始和结束,包括一段拼接的sql。
prepend:拼接sql的前缀
conjunction:循环输出拼接时需要的连接字符串,用于定义AND或OR
🔺
和的区别:
如果不传入参数,不会将其中的字符串拼入sql。而会将其中的字符串拼入sql,但是不赋值。
在动态拼接sql时,常常会遇到#和KaTeX parse error: Expected 'EOF', got '#' at position 12: ,他们的区别是: 1.#̲是将参数按照字符串传入,是将参数直接传入
2.#相当于是参数变量替换,KaTeX parse error: Expected 'EOF', got '#' at position 14: 相当于是字符串的拼接 3.#̲可以防止sql注入,不可以
所以能使用#的地方一定不使用$
如果不指定parameterClass,那么任何带有get/set方法的属性的javabean都可以作为输入参数。
在配置sql时,可以直接写select * from table,但是一定要配置一个包含数据表全部列的resultMap
🔺<![CDATA[ sql 语句 ]]>标记,将sql语句包裹住,不被解析器解析 CDATA全名为character data,指不使用XML解析器解析的文本数据
使用mybatis框架会在xml中写sql语句,如果sql中用到一些特殊字符的话(如直接使用:"<","&"…),XML 解析将会出现错误。
XML 解析器通常情况下会解析XML文档中的所有文本。当某个XML元素被解析的时候,🔺XML标签之间🔺的文本也会被解析:
假如在 XML 文档中放置了一个类似 “<” 字符,那么这个文档会产生错误,这是因为解析器会把它解释为新元素的开始。因此类似下边查询条件直接设置为 age<10 ,这种写法会报错:
可使用方法一:
select * from user where
age < 10
使用转义字符转义成符号对应的实体:< (“;”后边封号必须加)相当于小于号 “<”:
< < 小于
> > 大于
& & 和号
’ ’ 省略号
" " 引号
方法二:
< ! [ CDATA [忽略检查的文本:骗过xml解析器,不解析这里边的内容或者只是把这里边内容当成了普通文本]]>
🔺
用于引用包含一段已经定义好的sql
属性:
refid:被引用的sql的id
cachemodel是ibatis里面自带的缓存机制,正确的应用能很好提升我们系统的性能。
🔺查询在以一级签中,这里写插入更新删除的操作
~插入操作:
insert into users(USERNAME,PASSWORD,REALNAME,MOBILE,EMAIL)
values(#userName:VARCHAR#,#password:VARCHAR#,#realName:VARCHAR#,#mobile:VARCHAR#,#email:VARCHAR#)
public static void main(String[] args) throws SQLException {
ParameterMap parameterMap = new ParameterMap(“userName”, “sarin”,
“password”, “123”, “realName”, “sarin”, “mobile”, “1”,“email”,"@");
System.out.println(insert(parameterMap));
}
public static int insert(Map parameterMap) throws SQLException {
return sqlMap.update(“addUser”, parameterMap);
}
JDBC的更新操作返回的是影响的结果条数,插入操作没有特定的结果类型了
操作时返回的就是int类型的一个数值。当插入成功返回1,插入失败会报出具体的异常
~更新操作:
<update id="updateUser">
update users
set PASSWORD='123456'
</update>
操作没有传递任何参数,就不用写parameterClass属性了,然后在程序中调用就可以执行这个操作了
public static void main(String[] args) throws SQLException {
System.out.println(update());
}
public static int update() throws SQLException {
return sqlMap.update("updateUser");
}
执行更新操作后,结果返回的是影响数据表中的行数
~删除操作:
<delete id="deleteUser" parameterClass="java.lang.Integer">
delete from users
where ID=#INT#
</delete>
parameterClass属性就要设置为java.lang.Integer了,很容易理解,基本类型使用其包装类对象
public static void main(String[] args) throws SQLException {
System.out.println(delete(4));
}
public static int delete(int userId) throws SQLException {
return sqlMap.delete("deleteUser", userId);
}
这样就把ID为4的记录给删除了。