Mybatis第二阶段
输入映射跟输出映射
输入映射(dao传入参数类型)
- 简单类型
#{}
占位符:传入参数是简单类型(String,double,integer),#{}
里面的名称随意写${}
拼接符:传入的参数是简单类型(String,double,integer),${}
里面必须是value
- pojo
#{}
:传入参数是pojo类,#{}变量类型必须是pojo类中的属性.属性.属性。。。${}
:传入参数是pojo类,#{}变量类型必须是pojo类中的属性.属性.属性。。。
- 简单类型
输出映射(dao的返回值类型)
- 简单类型:只有返回值为一行一列的时候,返回的才可以使简单类型
- pojo类型:
- 使用resultType属性进行自动映射,查询的sql语句返回的列名必须和pojo的属性名称一一对应
- 使用resultMap手动映射将列名跟pojo类中的属性一一映射
- List:使用resultType属性进行自动映射,要写list中的泛型的类型
使用resultMap的时候首先先要定义:
- resultMap的使用
- id属性:resultMap的唯一标识
- type属性:返回的结果集标识
- id标签:指定主键列的映射关系
- column列:数据库中的列名
- property:pojo类中的属性名称
- result标签:指定非主键列的映射关系
- column列:数据库中的列名
- property:pojo类中的属性名称
- association标签:指定单个对象的映射关系
- 里面也是id跟result
- 然后在使用的时候在,sql语句的标签上直接写resultMap=上面resultMap的id即可
动态sql
作用:在一些高级查询的时候,sql语句中的where条件可能多也可能少,所以这时候就要动态的拼接sql
在要写sql语句的后边可以添加:
where标签
作用:- 可以自动添加where关键字
- 可以去掉第一个条件中的and关键字
- where里边也有
if标签
:判断传入的参数是否为空等判断条件用
- 全局sql语句
- sql标签:封住sql语句,封装后别的sql语句中可以重用这个条件.
- include标签:引用封装好的sql语句,例如
<include refide="userWhere"></include>
.
|
|
- where中的
foreach
标签,拼接功能:遍历传入的集合数据collection
: 要遍历的集合变量item
: 每遍历一次当前的变量数据open
:循环开始拼接的字符串close
:循环结束拼接的字符串separator
:分隔符
|
|
关联映射
一对一
以订单表跟用户表为例,订单跟用户从整体上来看是多对一,但是从局部上来看是一对一
- 使用自动映射
resultType
,可以封装大而全的自定义pojo
把要接受的数据的属性全都封装在其中
|
|
- 使用手动映射
resultMap
,需要手动指定sql的列名和pojo
中的属性名的关系,在resultMap
中可以使用association
标签来映射单个对象的关系
|
|
多对多
自动映射是用不了的,所以使用手动映射
12345678910111213141516171819202122 <resultMap type="cn.itcast.pojo.User" id="userAndOrdersResultMap"><id column="id" property="id"/><result column="username" property="username"/><result column="birthday" property="birthday"/><result column="sex" property="sex"/><result column="address" property="address"/><!--collection标签指定对集合对象关系映射property:将查询出的订单数据放入User对象中的ordersList属性中保存ofType: ordersList的泛型的类型--><collection property="ordersList" ofType="cn.itcast.pojo.Orders"><id column="oid" property="id"/><result column="user_id" property="userId"/><result column="createtime" property="createtime"/><result column="number" property="number"/></collection></resultMap><select id="findUserAndOrders" resultMap="userAndOrdersResultMap">select u.*,o.id oid, o.user_id, o.createtime, o.numberfrom user u, orders o where u.id = o.user_id</select>
mybatis跟spring的整合
- 映射文件, 接口, mybatis核心配置文件
Application-Context.xml
- spring的配置文件, 这里面配置了数据源, 连接池, 会话工厂, 引入原生dao或者是动态代理的接口
使用
导入jar包:mybatis,spring,两者的整合包,还有log4j包,数据库连接的包…
创建appliationContext.xml配置文件
- 加载jdbc配置文件
- 配置数据库连接池
- 配置会话工厂
|
|
测试原生DAO开发
- 在spring的配置文件中配置UserDao,把会话工厂给配置进去
|
|
- 接口
|
|
- 实现类
|
|
动态代理的方式
引入单个Mapper(不常用)
|
|
但是这种方法有一个局限性,就是每一个dao都要配置一下,代码量太大了,所以一般用下面这种方法
使用包扫描的方式批量引入整个包下的mapper
- 推荐使用包扫描的时候不用引入会话工厂, 它会自动调用当前配置文件下的会话工厂配置
- 实例化引用的时候, 使用类名, 首字母小写
|
|
逆向工程
作用:替我们连接数据库根据表生成pojo,接口和映射文件
导入三个包:
- 还有数据库连接包
mapper生成配置文件
- 在
generatorConfig.xml
中配置mapper生成的详细信息,注意改下几点:- 添加要生成的数据库表
- 文件所在包路径
mapper
文件所在包路径
- 在
|
|
- 使用
java
类生成mapper
文件:
|
|
- 运行,拷贝生成的mapper文件到工程中指定的目录中
Mapper.xml
的文件拷贝至mapper
目录内Mapper.java
的文件拷贝至mapper
目录内- 注意:mapper xml文件和mapper.java文件在一个目录内且文件名相同。
逆向工程注意事项
- Mapper文件内容不覆盖而是追加
- Mapper.xml文件已经存在时,如果进行重新生成则mapper.xml文件内容不被覆盖而是进行内容追加,结果导致mybatis解析失败。
- 解决方法:删除原来已经生成的mapper xml文件再进行生成。
- Mybatis自动生成的po及mapper.java文件不是内容而是直接覆盖没有此问题
Table schema问题
下边是关于针对oracle数据库表生成代码的schema问题:
Schma
即数据库模式,oracle
中一个用户对应一个schema
,可以理解为用户就是schema
。- 当Oralce数据库存在多个schema可以访问相同的表名时,使用
mybatis
生成该表的mapper.xml
将会出现mapper.xml
内容重复的问题,结果导致mybatis
解析错误。 解决方法:
- 在table中填写schema,如下:
<table schema="XXXX" tableName=" " >
XXXX
即为一个schema
的名称,生成后将mapper.xml
的schema
前缀批量去掉,如果不去掉当oracle用户变更了sql语句将查询失败。- 快捷操作方式:
mapper.xml
文件中批量替换:“from XXXX.”
为空
- 在table中填写schema,如下:
Oracle
查询对象的schema
可从dba_objects
中查询,如下:select * from dba_objects