MyBatis
MyBatis可以简化JDBC操作,实现数据的持久化
ORM:Object Relational Mapping
person对象 person表
ORM概念:
MyBatis是ORM的一个实现/Hibernate
orm可以是让开发人员 像操作对象一样操作数据库。
开发mybatis程序步骤:
1.配置mybatis
导入mybatis.sjar包
conf.xml:配置数据库信息和需要加载的映射文件
表 - 类
映射文件xxMapper.xml:增删改查标签<select>
测试类:
session.selectOne("需要查询的SQL的namespace.id","SQL的参数值");
配置方式:
abc.xml
<name>myProject</name>
约定:默认值就是myProject
具体实现步骤:
1.基础环境:mybatis.jar/ojdbc.jar、conf.xml、mapper.xml
2(不同之处)
约定的目标:省略掉statement,即根据约定直接可以定位出sql语句
接口,接口中的方法必须遵循以下的约定:
*1.方法名和mapper.xml文件中标签的id值相同
*2.方法的出入参数和mapper.xml文件中标签的parameterType类型一致(如果mapper.xml的标签中没有parameterType,则说明没有输入参数)
*3.方法的返回值和mapper.xml文件中标签的resultType类型一致(无论结果是一个还是多个(student、List<Student>),在mapper.xml标签中resultType中只写一个(Student))
除了以上约定,要实现接口的方法和Mapper.xml中SQL标签一一对应还需要以下一点:
namespace的值,就是接口的全类名(接口 - mapper.xml一一对应)
匹配的过程:(约定的过程)
1.根据接口名找到mapper.xml文件(根据的是namespace=接口的全类名)
2.根据接口的方法名找到mapper.xml文件中的SQL标签(方法名=SQL标签Id值)
以上2点可以保存:当我们调用接口中的方法时,程序能自动定位到某一个Mapper.xml文件中的SQL标签
习惯:SQL映射文件(mapper.xml)和接口放在同一个包中(注意修改conf.xml中加载mapper.xml文件的路径)
以上,可以通过接口的方法 ->SQL语句
执行:
StudentMapper studentMapper = session.getMapper(StudetnMapper.class); studentMapper.方法();
通过session对象获取接口(session.getMapper(接口.class);),再调用该接口中的方法,程序会自动执行该方法对应的SQL
优化
1.可以将配置信息 单独放入db.properties文件中,然后再动态引入
db.properties: k=v <configuration> <properties resource="db.properties"/> 引入之后,使用${key}
2.MyBatis全局参数
在conf.xml中设置
<settings> <setting name="cacheEnabled" value="false"/> <setting name="lazyLoadingEnabled" value="false"/> </settings>
3.别名
<typeAliases> <!-- 单个别名 <typeAlias type="org.xw.mybatis.Person" alias="Person"/>--> <!-- 批量定义别名(别名忽略大小写),以下会自动将该包中的所有类批量定义别名:别名就是类名(不带包名的类名) --> <package name="org.xw.mybatis"/> </typeAliases>
除了自定义别名外,MyBatis还内置了一些常见类的别名
类型处理器(类型转换器)
1.Mybatis子代一些常见的类型处理器
2.自定义MyBatis类型处理器
java - 数据库(jdbc类型)
针对sql中可能出现一些特殊符号,导致xml在解析的时候出现异常:
1.使用CDATA把所有内容括起来;
CDATA可以把括起来的所有内容当成普通文本直接输出,而不做任何解析
2.针对引起异常的特殊符号,使用转义字符来替换
这里同时又多个参数需要传入:
1.可以指定实体类类型;
2.使用map来传递
<![CDATA[ select empno, ename, job, mgr, hiredate, sal, comm, deptno from (select rownum rn,empno, ename, job, mgr, hiredate, sal, comm, deptno from (select empno, ename, job, mgr, hiredate, sal, comm, deptno from emp where ${column} like '%${kw}%' order by ${cln} desc) where rownum<=#{end}) where rn>#{start} ]]> --> 或 where rownum<=#{end}) where rn>#{start}
模糊查询,方式二:
student.setStuName("w");
select stuno,stuname,stuage from student where stuage=#{stuAge} or stuname like '%${stuname}%'
ii:嵌套类型对象
2.对象类型
#{属性名}
${属性名}
输入对象为HashMap:
where stuage=#{stuAge}
用map中key的值匹配占位符#{stuAge},如果匹配成功就用map的value替换占位符
mybatis调用存储过程
<select id="queryCountByGradeWithProcedure" statementType="CALLABLE" parameterType="HashMap"> { CALL queryCountByGradeWithProcedure( #{gName,jdbcType=VARCHAR,mode=IN} #{scount,jdbcType=INTEGER,mode=OUT} ) } </select>
其中通过statementType="CALLABLE"设置SQL的执行方式是存储过程。存储过程的输入参数gName需要通过HashMap设置
在使用时,通过hashmap的put方法传入参数的之;通过hashmap的Get方法获取输入的参数的值。
要注意Jar问题:ojdbc6.jar不能再调用存储过程时,回车、空格,但是ojdbc7.jar可以。
如果报错:No enum constant org.apache.ibatis.type.JdbcType.XXX,则说明mybatis不支持XX类型,需要查表(百度)
输出参数resultType
1.简单类型(8个基本+String)
2.输出参数为实体对象实例
3.输出参数为实体类对象类型的集合:虽然输出类型为集合,但是resultType依然写集合的元素类型(Student)
4.输出参数类型为HashMap
--HashMap本身是一个集合,可以存放多个元素
但是根据提示发现返回值为HashMap时,查询的结果只能是一个学生(sid,sname)
-->结论:一个HashMap对应一个学生的多个元素(多个属性)【一个map一个学生】
二维数组
{
{1,zs,23,xa} --一个HashMap对象
{2,ls,23,xa}
{3,ww,23,xa}
{4,zs,23,xa}
}
动态SQL
简单类型的数组:
无论编写代码是什么,传递的是什么参数名(id),在mapper.xml中,必须用array代替该数组
集合:
无论编写代码是什么,传递的是什么参数名(id),在mapper.xml中,必须用list代替该数组
对象数组:
Person[] person = {person1,person2,person3}每个studentx包含一个学号的属性
注意几点:
parameterType="Object[]"
<foreach collection="array" open=" and id in(" close=")" item="person" separator=",">
#{person.id}
</foreach>
SQL片段:
<sql id="queryxxx"> <foreach collection="array" open=" and id in(" close=")" item="person" separator=","> #{person.id} </foreach> <sql>
-----调用sql片段
<include refid="queryxxx"></include>