第一章:Mybatis入门
1、前身背景
前身是iBatis,是轻量级的数据持久化框架,为Apache的一个开源项目。2010年迁移到了Google Code,改名为MyBatis.2013年迁移到Github。
MyBatis框架以及ORM
MyBatis是一个开源的数据持久层框架,内部封装了通过JDBC访问数据库的操作,支持普通的SQL查询、存储过程和高级映射。作为持久层框架,主要思想是将程序中的大量的SQL语句分离出来,配置在相应的配置文件中,这样可以在不修改代码的情况下,直接在配置文件中的修改SQL。
ORM(Object/Relational Mapping)对象关系映射。是一种数据持久化的技术。在对象模型和关系型数据库之间建立关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据。MyBatis通过简单的XML或者注解进行配置和原始映射,将实体类和SQL语句之间建立映射关系,是一种半自动化的ORM实现。
MyBatis优缺点以及其适用场合
优点:
1.与JDBC相比,代码量减少了50%以上。
2.最简单的持久层框架,小巧简单易学
3.SQL语句写在XML文件,从程序代码中彻底分离,便于统一管理和优化,并可重用。
4.提供XML标签,支持编写动态SQL语句。
5.提供映射文件,支持对象与数据库的ORM字段关系映射。
缺点:
1.SQL编写工作量较大,对开发人员编写SQL语句的功底有一定的要求。
2.SQL依赖于数据库,数据库的移植性差,不能随意更换数据库。
适应场合:
专注于SQL本身,一个灵活的DAO层的解决方案,对性能要求较高,或者需求变化较多的项目。
2、MyBatis环境搭建
1、下载jar包
登录mybatis官网(https://github.com/mybatis/mybatis-3/)。中文官网:https://mybatis.org/mybatis-3/zh/index.html
在官网入门的安装中,有个mybatis-x-x-x.jar,点击既可,或者最下面(或者再上面的releases标签,点击),可以看到下载的连接,点击去可以下载版本
2、部署jar包
创建普通java项目或者web项目
将下载的jar包以及需要的jar包,log4j负责日志数据jar文件)部署至项目WebRoot的lib目录下(普通java项目新建lib,然后添加到项目依赖环境中)。
记得要加对应的log4j的配置文件log4j.xml,方便后面查看执行的SQL语句(resources源码目录下))
3、创建mybatis核心配置文件-mybatis-config.xml
然后新建一个普通的xml文件:mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 配置 -->
<configuration>
<!-- 环境配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/edocdb"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
</environments>
<!-- 引入sql映射文件 -->
<!-- <mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers> -->
</configuration>
4、案例
1、新建一个测试Junit类TestMybatis.java
/**
*
* 两个重要的配置文件
* mybatis-config.xml :全局配置文件 , 数据库连接信息、 引入SQL映射文件等....
* UserMapper.xml :SQL映射文件 , 配置增删改查的SQL语句的映射
*
* 两个重要的对象
* SqlSessionFactory: SqlSession的工厂对象, 主要是用于获取SqlSession对象
* SqlSession: Java程序与数据库的会话对象.可以理解为是对Connection的封装.
*/
@Test
public void testSqlSessionFactory() throws Exception{
// 1)读取全局配置文件(xxx.xml”)
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 2)创建sqlsessionfactory,完成配置文件的读取。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
System.out.println(sqlSessionFactory);
}
3、执行查询SQL语句
获取到一个对象,SqlSessionFactory是sqlsession的工厂
// 3)创建sqlSession对象,通过sqlSession调用相应的方法进行操作。
// 打开sqlSession对象
SqlSession session = sqlSessionFactory.openSession();
System.out.println(session);
创建SQL映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 配置SQL映射
namespace: 名称空间.
1. 随便写
2. Mapper接口开发,不能随便写,按照规定来写。
-->
<!-- <mapper namespace="wusuowei"> -->
<mapper namespace="com.kgc.mybatis.dao.UserMapper">
<!--
<select>: 定义查询语句
id: <select>的唯一标识
resultType: 结果集的映射类型。
#{id}: 获取参数值
-->
<select id="selectUser" resultType="com.kgc.mybatis.entity.User">
select * from users where id = #{id}
</select>
</mapper>
通过SqlSession实例直接运行映射的SQL语句
// 4)执行sql语句。
User user = session.selectOne("com.kgc.mybatis.dao.UserMapper.selectUser", 1);
System.out.pringln(user);
改好之后,由于是读取的mybatis-config.xml,所以还要加载映射SQL文件,才可以
放开mybatis-config.xml中的mapper配置映射文件,改为新建的mapper配置文件的路径,直接resource改为UserMapper.xml即可,从类路径下直接读取。
<!--引入SQL映射文件
<mapper>:引入一个SQL映射文件
resource: 引入类路径下的SQL映射文件
-->
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
执行单元测试,测试结果,正确查询出用户数据,即可
小结:
* 两个重要的配置文件
* mybatis-config.xml :全局配置文件 , 数据库连接信息、 引入SQL映射文件等....
* UserMapper.xml :SQL映射文件 , 配置增删改查的SQL语句的映射
*
* 两个重要的对象
* SqlSessionFactory: SqlSession的工厂对象, 主要是用于获取SqlSession对象
* SqlSession: Java程序与数据库的会话对象.可以理解为是对Connection的封装.可以进行增删改查(crud操作,可以直接点出来对应的方法)
3、Mybatis的接口开发
正常分层开发中,有Controller,service,dao,那mybatis就提供了根据dao层接口直接进行映射开发,比现在开发会更简单
增加对应的接口
public interface UserMapper {
//根据id查询Employee
User getUserById(Integer id );
}
因为mybatis是会通过代理的方式帮我们生产实现类的,我们只需要关注接口和对应的sql映射处理就可以了
UserMapper userMapper = session.getMapper(UserMapper.class);
// 打印的是jdk的动态代理对象
System.out.println(userMapper.getClass().getName());
// 执行查询获取实体值
User user = userMapper.getUserById(1);
System.out.println(user);
将UserMapper.xml映射文件的namespace值改为UserMapper的全类名
<mapper namespace="com.kgc.mybatis.dao.UserMapper">
执行单元测试,可以输出结果。
小结:
* 两个绑定:
* 1. Mapper接口与SQL映射文件的绑定.
UserMapper.xml的映射文件的namespace的值必须指定成接口的全类名.(实体类)
* 2. Mapper接口的方法 与 SQL映射文件的具体SQL语句的绑定 (sql文件)
SQL语句的id值:必须指定成接口的方法名.
将UserMapper.xml文件中,mapper标签中,增加一个新的配置方法
由于接口是不可以直接使用的,所以要先获取到MyBatis为Mapper接口生成的代理实现类对象
Mapper接口开发的好处:
对比javaweb的dao模式写的代码,只需要写接口和对应的查询语句,配置映射即可,这个就是其强大的地方,且不用关心sqlsession有哪些方法。
1. 有更明确的类型,不需要关心SQLSession到底有哪些方法,而之前第一个列子的写法,session.selectOne,参数和返回都是Object类型,可以随便写,但是运行时可能会出问题,改变参数类型,不会编译报错,运行就错了,而下面的写法,就有强制要求了
2. 接口本身: 接口本身就是抽象. 抽出了规范. 方便解耦
4、mybatis全局配置文件
全局配置文件
1) The MyBatis configuration contains settings and properties that have a dramatic effect on how MyBatis behaves.
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。
2) 文件结构如下: 基本了解即可
configuration 配置文件的根节点
properties
从外部引入指定的properties属性文件,一般为数据库连接的配置信息
settings
设置MyBatis运行中的一些行为,如果,此次设置MyBatis的log日志文件实现为LOG4J,既使用log4j实现日志功能。
environments表示配置多套运行环境,映射到不同的数据库,该元素下可以配置多个environment子元素节点,但是必须通过default指定一个默认的运行环境。
typeAliases 类型命名
typeHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
databaseIdProvider 数据库厂商标识
mappers 映射器,作用是告诉MyBatis去哪里找SQL映射文件
Mapper:具体指定SQL映射文件的路径,resource属性的值表示映射文件的路径
注意:
核心配置,所有的配置都必须放在这个父标签内
mybatis的所有的配置,是有固定顺序的,顺序为:(properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?,
reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)
顺序不能颠倒,要注意
1、properties属性
增加数据库连接配置化引入内容:
<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<!--
1. properties: 属性配置
<property>: 一个具体的属性配置,一般不配置
resource: 引入类路径下的属性文件,常用方式
url: 引入网络路径或者是磁盘路径下的属性文件.
-->
<!-- 引入 jdbc.properties 文件-->
<properties resource="jdbc.properties"/>
<!--
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
-->
两种方式同时使用:
<properties resource="jdbc.properties">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/bookdb"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</properties>
resource的优先级会更高,所以property配置错误也不影响
2、settings配置优化
<!-- 2. settings: 包含了很多重要的设置项 -->
<settings>
<!-- 映射下划线到驼峰Camel命名 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
可以解决数据库是下划线,但是类属性是驼峰命名的
3、优化typeAliases元素配置:
<!-- 3. typeAliases: 别名处理
<typeAlias>: 给某个java类型取别名
type: 指定java的全类名
alias:指定别名. 默认的别名就是类名. 大小写不区分
<package>: 为指定的包以及子包下的类批量取别名.
如果有别名冲突的情况, 可以使用@Alias()注解为冲突的类具体指定别名(加到实体类的定义上@Alias("别名")). 建一个子包,也定义个实体User
建议:由于给实体起别名可以降低冗余的全限定类名书写,但是可读性不好,从xml不能直接确定具体的实体类型
所以还是建议之间用全类名(可以从xml直接跳转到实体对象)
对应系统提供的别名处理,可以选择使用,也可以不适用(开发中也一般使用全类名,如果有不是全类名的写法,也要知道什么含义)
-->
<!--类型别名-->
<typeAliases>
<!-- <typeAlias alias="User" type="com.kgc.entity.User"/> -->
<package name="com.kgc.mybatis.entity"/>
</typeAliases>
4、environments环境配置
<!--
environments: Mybatis支持配置多个环境, 通过 default来指定具体使用的环境.
environment: 具体的环境
mybatis支持多个环境配置,通过default属性指定当前使用哪个环境(开发环境,线上环境,测试环境等)
<environment> : 具体的环境配置
<transactionManager> : 指定事务管理(JDBC|MANAGED),一般使用JDBC事务处理
结论:学完spring之后,整合Mybatis,会将事务处理交给spring
<dataSource> :指定数据源 ,类型有三种-UNPOOLED|POOLED|JNDI,一般使用POOLED(使用mybatis自带的数据连接池管理jdbc数据源),JNDI(使用tomcat的数据源)
结论:学完spring之后,整合Mybatis,会将数据源交个spring处理(比如c3p0)
-->
<environments default="development">
<environment id="development">
<!--配置事务管理,采用JDBC的事务管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- POOLED:mybatis自带的数据源连接池,JNDI:基于tomcat的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbcUrl}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
5、优化mappers配置
<!--
5. 引入SQL映射文件
加载、引入SQL映射文件,如果映射文件中出现错误,直接加载失败,抛出异常
<mapper> : 引入一个SQL映射文件
resource属性:默认是类路径下的SQL映射文件(完整的映射文件路径,注意不能写 . ,必须是 / )
class属性:mybatis自动加载指定的接口的全类名,为其创建代理实现类对象做准备
<package> : 批量引入SQL映射文件
如果用了此配置,有一个强校验:SQL映射文件和mapper接口必须是同名同路径
如果接口和SQL映射文件不再同一个位置,建议为SQL映射文件创建一个跟包同样目录
注意:这个是mybatis的规范,强约束,后面讲ssm的时候,在spring中可以实现路径自定义
-->
<mappers>
<!-- <mapper resource="UserMapper.xml" /> -->
<package name="com.kgc.mybatis.mapper"/>
</mappers>
第二章:Mybatis的Sql映射文件
1、SQL映射的XML文件标签
MyBatis 真正的强大在于映射语句,专注于SQL,功能强大,SQL映射的配置却是相当简单
SQL映射文件的几个顶级元素(按照定义的顺序)
mapper – namespace
cache – 配置给定命名空间的缓存
cache-ref – 从其他命名空间引用缓存配置
resultMap –用来描述数据库结果集和java对象的对应关系
sql – 可以重用的SQL块,也可以被其他语句引用
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
2、具体用法
2.1、insert元素
属性:
id 对应接口的名称
parameterType 参数对象
<!--
parameterType:指定参数类型. 可以省略不配置.
mybatis可以根据参数类型自动推断,但是resultType不可以,建议不确定的情况下,能不写的就不写,写的多了如果错了就会出问题
-->
<insert id="接口方法" parameterType="入参类型">
sql语句
</insert>
扩展:获取插入数据的主键值
insert标签增加属性 useGeneratedKeys="true" keyProperty="id"
useGeneratedKeys: 告诉Mybatis使用主键自增的方式,true
keyProperty: 指定用对象的哪个属性保存Mybatis返回的主键值,写主键id对应实体的名
2.2、update 元素
属性:
id 对应接口的名称
parameterType 参数对象
用法同insert
2.3、 delete元素
属性:
id 对应接口的名称
parameterType 参数对象
用法同insert
注意:
insert、update、delete元素均没有resultType属性
mysql默认是不会提交事务的,所以要手动提交
在获取sqlsession对象时候,可以通过ssf.openSession(true);来获得带有自动提交事务的session
2.4、 多参数入参处理(默认只能接收一个参数)
参数传递的方式
- 单个普通(基本/包装+String)参数
这种情况MyBatis可直接使用这个参数,不需要经过任何处理。
取值:#{随便写} 演示:以根据id查询用户为例,mapper.xml中取值可以随便写
- 多个参数
任意多个参数,都会被MyBatis重新包装成一个Map传入。 Map的key是param1,param2,或者0,1…,值就是参数的值
取值: #{0 1 2 … N / param1 param2 …… paramN}
* mybatis的多参处理
* 1)单个参数:在SQL映射文件中,可以随便取值,方式#{自定义},不需要指定参数别名,一般使用形参名称
* 2)多个参数:使用mybatis默认参数名,不能直接使用形参名称,只能用参数序号:#{0},#{1}...或者#{param1},#{param2}...
* 3)多个参数:使用自定义参数名,可以通过@Param注解给形参指定一个别名处理(@Param("别名")),SQL映射文件中,可以用自定义参数名#{注解自定义参数名}...或者#{param1},#{param2}...
* 4)实体参数:在SQL映射文件中,直接通过对象的属性名获取参数值,如:#{实体属性名},如果给实体也起了别名,那获取参数就必须通过别名.属性名,比如实体别名是stu,取值,就是#{stu.stuNo}
* 5)map作为参数:直接使用map作为参数传递,SQL映射文件中,直接通过map的key获取,比如#{map的key}
2.5、参数获取方式
#{参数名},可以获取普通类型,pojo类型,多个参数,集合等
预编译放到SQL中(使用 PreparedStatement ?),安全的
${参数名},也可以获取普通类型,pojo类型,多个参数,集合等
直接将获取的参数拼接到SQL中,存在注入问题(Statement)
注意,如果是单个普通参数,必须使用_parameter来获取,这个是mybatis内置设置好的
原则:能直接用#{}就优先用#{},#解决不了的才用${}
例如:原生jdbc中不能用占位符的地方,比如列名,表名等
2.6、Select语句查询多条数据:
id 命名空间中唯一的标识符
接口中的方法与映射文件中的SQL语句id一一对应
parameterType
传入SQL语句的参数类型
resultType
SQL语句返回值类型的完整类名或别名
返回单个对象,可以直接指定resultType为实体类的全类名即可
返回对象集合list,也是一样的
2.7、查询数据返回Map:
单条数据返回一个map类型的数据
那resultType可以直接写map或者java.util.HashMap就可以,返回的内容为键值对,键是列名,值是列的值
多条数据返回一个map类型的数据
定义接口的返回值类型为Map<Integer, User>,然后再接口上增加注解@MapKey("id"),指定使用对象的哪个属性作为map的key值,然后xml中的resultType还是实体类的全类名就可以了
2.8,结果集的映射方式
分为两种
1) resultType自动映射 是标签属性 1) autoMappingBehavior默认是PARTIAL,开启自动映射的功能。唯一的要求是列名和javaBean属性名一致 2) 如果autoMappingBehavior设置为null则会取消自动映射 3) 数据库字段命名规范,POJO属性符合驼峰命名法,如A_COLUMN和aColumn,我们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true 局限:只能完成单表的基本的映射,如果多表查询的结果,就不好做了 2)resultMap自定义映射 单独标签 1) 自定义resultMap,实现高级结果集映射 2) id :用于完成主键值的映射 3) result :用于完成普通列的映射 4) association :一个复杂的类型关联;许多结果将包成这种类型 5) collection : 复杂类型的集
resultMap的用法实例
单表:不建议使用,直接用resultType就可以,先引入用法讲解
<!--
当数据库中的字段信息与对象的属性不一致时需要通过resultMap来映射
type 为最终映射结果集封装类型,id属性是取的别名,给select的resultMap属性用的
resultMap标签内可以有
id标签,是专门对主键进行映射的
result标签是对普通列的映射的,column指定查询列名,property是对应的属性名
注意:如果resultMap中除了指定对应的映射关系外,没指定的列,仍然会执行实体自动映射
-->
<!--
结果集映射方式
1 自动映射:select标签的resultType属性,值指定为具体的实体类的全类名
mybatis默认开启自动映射,要求数据查询列名必须和属性名保持一致(驼峰,别名处理),才可以进行映射
只能单表自动映射(单个查询结果-对应单个实体),如果是多表查询且查询列在多个实体中,不能自动映射
2 自定义映射:select标签的resultMap属性,配置resultMap标签(注意resultMap和resultType不能同时存在)
resultMap标签:
id属性 : 自定义映射别名,给select标签的resultMap属性使用的,且在SQL映射文件中,可以重复使用
type属性 : 最终映射的实体类的全类名
<id>子标签:自动完成主键列的属性映射
<result>子标签:自动完成普通列的映射
column属性:查询结果的列名
property属性:映射实体的属性名
当多表查询,数据库字段不能自动映射(列名和属性名不一致,没有起别名,没有驼峰等),建议使用自定义,意义:对实体属性的级联映射和延迟加载和分布查询支持
注意:
不是自定义映射resultMap指定哪些列,就只映射哪些列,会先自动映射(列名和属性名一致),如果映射不上,再通过自定义映射进行处理
一般使用自定义映射都是查询列全部自定义
如果使用了resultMap使用了嵌套映射,上面的自动就不能生效了,只能按照指定属性映射,要注意。
-->
2.9、多表查询
1)查询列可以允许冗余,可以将字段冗余到实体属性中,通过起别名的方式实现自动映射
2)如果查询的实体中,存在其他实体属性,可以使用级联属性赋值的方式
3)使用高级嵌套映射
2.10、高级用法:
association 映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
复杂的类型关联,一对一
内部嵌套 映射一个嵌套JavaBean属性
属性
property:映射数据库列的实体对象的属性
javaType:完整Java类名或者别名
resultMap:引用外部resultMap
子元素
id
result
property:映射数据库列的实体对象的属性
column:数据库列名或者别名
2.11、association的分步查询
分步查询:开发过程中,事先已经存在接口实现
select属性:执行关联查询SQL映射文件中的具体的select(内容namespace+id)
column属性:当前查询的列所对应的值作为参数传递到select属性指定的查询中
是延迟加载的前提条件,如果不是分布查询,延迟加载就无从谈起。
扩展:
association的属性fetchType="lazy",这个是代表默认支持延迟加载,如果需要单独配置某个查询不需要延迟加载,将fetchType改为:fetchType="eager"
2.12、association 分步查询使用延迟加载/懒加载:
在全局配置文件中加上两个settings设置:
改为true,代表是用延迟加载
<setting name="lazyLoadingEnabled" value="true"/>
这个属性是确定定义的属性是全部加载还是按需加载
按需加载(false)还是全部加载(true)
mybatis3.4.1版本及之前的版本,默认是全部加载(不支持按需加载,默认值是true),实体中定义的所有的属性默认都是全部加载(只要调用了实体的任何方法,所有的属性都会加载)
如果要支持按需加载,必须改为false,新版本mybatis(3.4.1之后)默认就支持按需加载(默认值为false)
<setting name="aggressiveLazyLoading" value="false"/>
2.13、Collection的用法
复杂类型集合,一对多
内部嵌套
映射一个嵌套结果集到一个列表
属性
property:映射数据库列的实体对象的属性
ofType:完整Java类名或者别名(集合所包括的类型)
resultMap:引用外部resultMap
子元素
id
result
property:映射数据库列的实体对象的属性
column:数据库列名或者别名
2.14、collection 分步查询:
collection 分步查询: 基本跟association一样
2.15、扩展:
1、分别查询传多个参数
如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成
Map来进行传递,语法如下: {k1=v1, k2=v2....}
在所调用的查询方,取值时就要参考Map的取值方式,需要严格的按照封装map时所用的key来取值.
2、association 或 collection的 fetchType属性
1) 在<association> 和<collection>标签中都可以设置fetchType,指定本次查询是否要使用延迟加载。默认为 fetchType=”lazy” ,如果本次的查询不想使用延迟加载,则可设置为
fetchType=”eager”.
2)fetchType可以灵活的设置查询是否需要使用延迟加载,而不需要因为某个查询不想使用延迟加载将全局的延迟加载设置关闭
2.16、sql片段:可重用
sql标签的用法
将公共的抽取可重用sql片段放到这个位置
<sql id="定义别名">
然后需要使用的地方 使用<include refid="sql的id别名"></include>
2.17、resultType和resultMap的区别
resultType :直接表示返回类型(结果集的封装类型)
基本数据类型
复杂数据类型
是标签属性
resultMap :对外部resultMap的引用,是单个标签
应用场景:
数据库字段信息与对象属性不一致
复杂的联合多表查询,自由控制映射结果
二者不能同时存在,本质上都是Map数据结构
除了全局的是否启用自动映射的配置外,还可以对特定的resultMap设置是否启用自动映射。这是通过resultMap的autoMapping属性配置的,可选值是true和false。定义在resultMap上的autoMapping的优先级比全局配置的优先级更高。
第三章:动态sql
1、MyBatis动态SQL简介
1) 动态 SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作
2) 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似
3) MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作
4) OGNL( Object Graph Navigation Language )对象图导航语言,这是一种强大的 表达式语言,通过它可以非常方便的来操作对象属性。 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
类似于我们的EL,JSTL等,这个不是重点,记住我写的用法就可以了
访问对象属性: person.name
调用方法: person.getName()
运算符: +,-*,/,%
逻辑运算符: in,not in,>,>=,<,<=,==,!=
注意:xml中特殊符号如”,>,<等这些都需要使用转义字符
2、实现动态SQL的元素主要有
if
where
trim
set
choose(when、otherwise)
foreach
2.1 if+where用法:
<!-- 在SQL语句中提供WHERE关键字, 自动增加where关键字,并且解决第一个出现的and 或者是 or的问题 -->
<where>
<if test="id!=null">
and id = #{id }
</if>
<if test="sex==0 or sex==1">
and sex = #{sex}
</if>
</where>
2.2 trim用法
属性
prefix 添加前缀
suffix 添加后缀
prefixOverrides 去掉一个前缀或者两个
suffixOverrides 去掉一个后缀
更灵活地去除多余关键字
替代where和set
2.3 set用法
主要用于修改,参数为null,则不需要更新,保持数据库原值,去除结尾多余的逗号
语法:
<update id="xx">
update table
<set>
<if test="条件1">
字段1 = #{值1} ,
</if>
<if test="条件2">
字段2 = #{值2}
</if>
</set>
where 字段3 = #{值3 }
</update>
if+trim 替代set 改造更新
<trim prefix="set" suffixOverrides="," suffix="where id = #{id}">...</trim>
2.4 choose用法
实现if+else
choose(when、otherwise)
相当于Java中switch语句
当when有条件满足的时候,就跳出choose
<choose>
<when test ="条件1"> …</when>
<when test ="条件2"> …</when>
<when test ="条件3"> …</when>
…
<otherwise>…</otherwise>
</choose>
2.5 foreach
迭代一个集合,通常用于in条件
属性
item:循环体中的具体对象,支持属性使用点 . 访问 必选
index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
collection:必须指定,要做foreach的对象
list、array、map-key
open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
close:foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
2.6 mybatis的批量处理
处理:
<!--
添加:insert into tbl_employee(x,x,x) values(?,?,?),(?,?,?),(?,?,?)
删除:delete from tbl_employee where id in(?,?,?)
修改: update user set last_name = #{lastName} ...where id = #{id};
update users set last_name = #{lastName} ...where id = #{id};
update user set last_name = #{lastName} ...where id = #{id};
默认情况下, JDBC不允许将多条SQL通过;拼成一个字符串。
可以在jdbc.properties连接的url后面加上一个参数: allowMultiQueries=true
-->
3、mybatis实现分页
方式1:根据pageNo计算起始行,传入接口参数
方式2:使用bind标签:
<bind name="fromIndex" value="(pageNo - 1) * pageSize"/>
方式3:使用$
limit ${(pageNo-1)*pageSize},#{pageSize}
4、详细案例见课堂代码
教育改变生活