使用MyBatis实现条件查询
1、SQL映射文件的几个顶级元素(按照定义的顺序)
-
mapper - namespace
- namespace:命名空间
- 作用 --
- 用于区别不同的namespace。
- 绑定DAO接口后,namespace的命名必须与某个接口同名(完全的包名)。
- 接口中的方法与映射文件中sql元素id一一对应。
-
select - 映射查询语句
- select是MyBatis最常用的元素之一
- 属性:id
- 接口中方法与映射文件中的SQL语句id一一对应
- 命名空间唯一的标识符
- 属性:resultType
- 表示返回的结果类型,值为SQL语句返回值类型的完整包名或别名。
- 返回的是基础数据类型或者复杂数据类型。比如:(int、String、map、javaBean)
- 属性:resultMap
- 表示对外部resultMap定义的引用,对应外部resultMap的id。
- 自由控制映射结果,返回结果到外部关联的resultMap上。
- 属性:parameterType
- 表示传入的参数的参数类型,包括基础类型和复杂类型。
- 对大小写不敏感。
-
insert - 映射插入语句
-
update - 映射更新语句
-
delete - 映射删除语句
- 增删改元素属性:id、parameterType。
- 这三个方法默认返回SQL影响的行数。
- 这三个均没有resultType、resultMap属性。
================下面示例:resultType入参类型、单参入参===============
<!--
基础数据类型入参 - - - int String Date
1、属性parameterType 表示传入的条件类型。
2、parameterType = “完全的限定名,或者别名”,对大小写不敏感。
3、在mapper文件中参数的《占位符》使用 #{DAO接口形参名称}。
4、#{}中的参数名和DAO接口定义的形参名称一致。
-->
<select id="selectByName" resultType="User" parameterType="String|string">
select * from smbms_user
where userName LIKE concat('%',#{userName},'%')
</select>
<!--
复杂数据类型入参 - - - 实体直接入参
parameterType的值就是实体类的名称,忽略大小写
占位符获取值#{属性名称}
-->
<select id="selectUserList" resultType="User" parameterType="user|User">
select * from smbms_user
where userName LIKE concat('%',#{userName},'%')
and userRole=#{userRole}
</select>
<!--
复杂数据类型入参 - - - Map入参
parameterType的值是类型map或者Map,忽略大小写
占位符通过#{key} 获取值。
-->
<select id="selectUserListMap" resultType="User" parameterType="map|Map">
select * from smbms_user
where userName LIKE concat('%',#{uName},'%')
and userRole=#{uRole}
</select>
=============下面示例:resultMap自由控制映射、注解多参入参============
DAO层:
/**
* 根据商品名称、供应商id、是否付款。查询订单表
* 注解:@Param可以实现Mybatis多参入参。
* 在Mapper文件中使用#{注解名},取入参值
* @return 返回一个商品列表
*/
List<Bill> FindByNameAndProviderId(@Param("proDuctName")String name,@Param("proId")Integer provider,@Param("isPay") Integer isPay);
--------------------------------------------------------------------------
Mapper文件:
<!--
多表联查使用resultMap映射。
使用注解多参数入参,而不用传入一个完整的实体。
一般实体类只需要4个包括其以下的时候最好多参入参。
具体情况具体使用。
-->
<select id="FindByNameAndProviderId" resultMap="getBillList">
select b.id as productId,b.billCode,b.productName,p.proName,b.totalPrice,b.isPayment,b.creationDate from smbms_bill b
join smbms_provider p on b.providerId = p.id
where b.productName like concat('%',#{proDuctName},'%')
and b.providerId = #{proId}
and b.isPayment = #{isPay}
</select>
<!--
使用resultMap自由控制映射
子节点 - - id: 一般用于数据库primary key 提高查询性能
子节点 - - result:表示映射结果
column: 表示查询出来的列名
property: 表示实体类私有的属性(不和数据库字段匹配的属性)
映射多出的私有属性,其他自动映射
如果想不自动映射其他属性,那么需要在mybatis核心配置文件中设置
<settings>
<setting name="autoMapperBehavior" value="NONE"/>
</settings>
-->
<resultMap id="getBillList" type="Bill">
<id property="id" column="productId"></id>
<-- 此时proName属于多表联查的字段 , viderName为实体多出的属性-->
<result property="viderName" column="proName"></result>
</resultMap>
-
sql - 可以重用的SQL块,也可以被其他语句引用
-
cache - 配置给定命名空间的缓存
- 属性:eviction -- 缓存方式 值--FiFO "先进先出"
- 属性:flushInterval -- 刷新时间 单位:毫秒
- 属性:size -- 缓存元素 单位:个
- 属性:readOnly -- 是否只读 值--boolean
-
cache-ref - 从其他命名空间引用缓存
-
resultMap - 用来描述数据库结果集和对象的对应关系
- 属性:id -- 表示唯一标识。
- 属性:type -- 表示该resultMap的映射结果类型。
- 子元素 --- id
- 一般对应数据库中该行的主键id,用于提高查询性能。
- 子元素 --- result
- 映射单列的值,简单的属性。
- 属性:property -- 表示映射的实体的属性。
- 属性:column -- 表示数据库查询出来的对应的字段名。
- 子元素 --- association
- 映射到JavaBean的某个"复杂类型"属性,一对一关系,内部嵌套。
- 比如:JavaBean类中内嵌了一个JavaBean类对象 。
- 属性
- property:映射数据库列的实体对象的属性。
- javaType:完整Java类名或者别名。
- resultMap:引用外部resultMap结果集。
- 子元素
- id
- result
- property:映射数据库列的实体对象的属性
- column:数据库列名或者别名
- 映射到JavaBean的某个"复杂类型"属性,一对一关系,内部嵌套。
<!--
association元素用于一对一映射
JaveBean中内嵌另外一个JaveBean
- - property 指定内嵌的javaBean的对象名
- - javaType 标识内嵌的javaBean,填写完整包名或者别名
- - resultMap 表示引用外部的resultMap结果集
!!!注意:一旦resultMap中指定了association。
!!!那么要映射的javaBean属性,必须声明result去进行映射。
!!!指定association后将不会自动映射javaBean的属性值了。
!!!不管autoMapperBehavior是否为PARTAIL
!!!解决方法autoMapperBehavior 设置为FULL
-->
<!-- 为Role类专门指定的resultMap -->
<resultMap id="role" type="Role">
<id property="id" column="rid"/>
<result property="roleCode" column="roleCode"/>
<result property="roleName" column="roleName"/>
</resultMap>
<!-- 为User类专门指定的resultMap,返回一个User类集合-->
<resultMap id="userRoleList" type="User">
<id property="id" column="id"/>
<result property="userName" column="userName"/>
<!-- role表示User类嵌套了一个role类对象,JavaType可以使用别名或者包名 -->
<association resultMap="role" property="role" javaType="Role"/>
</resultMap>
<!-- 多表联查 -->
<select id="getUserListByRoleId" resultMap="userRoleList" parameterType="Integer">
select u.*,r.id as rid,r.roleCode,r.roleName
from smbms_user u,smbms_role r
where u.userRole = r.id
and u.userRole = #{userRole}
</select>
-
- 子元素 --- collection
- 映射到JavaBean的某个"复杂类型"集合,一对多关系,内部嵌套。
- 比如:映射一个嵌套结果集到一个列表。
- 属性
- property:映射数据库列的实体对象的属性
- ofType:完整Jave类名或者别名(集合所包含的类型)
- resultMap:引用外部resultMap结果集
- 子元素
- id
- result
- property:映射数据库列的实体对象的属性
- column:数据库列名或者别名
- 映射到JavaBean的某个"复杂类型"集合,一对多关系,内部嵌套。
- 子元素 --- collection
<!-- 外部的resultMap可以达到复用的目的 -->
<resultMap id="addressMap" type="Address">
<id property="id" column="id"/>
<result property="contact" column="contact"/>
<result property="addressDesc" column="addressDesc"/>
</resultMap>
<!-- 引用的结果集 -->
<resultMap id="AddressList" type="User">
<id property="id" column="uid"/>
<result property="userName" column="userName"/>
<!--
一对多,为List中的Address映射值,
User里存有一个Address的addressList集合对象
集合类型addressList集合的类型为Address
-->
<collection property="addressList" ofType="Address" resultMap="addressMap"/>
</resultMap>
<select id="getAddressByUserId" parameterType="Integer" resultMap="AddressList">
select u.id as uid,u.userName,a.id,a.contact,a.addressDesc
FROM smbms_user u,smbms_address a
where a.userId = u.id
and u.id = #{userId}
</select>
resultMap自动映射级别(autoMapperBehavior)的三个映射级别
- NONE:禁止自动匹配。
- PARTIAL(默认):自动匹配所有属性,内部嵌套除外。
- FULL:自动匹配所有。
基础数据类型
1、int、String、Date等
2、只能传入一个,通过#{参数名}即可获取值。
复杂数据类型
1、Java实体类、Map等
2、通过#{属性名} 或者#{Map的key}即可获取值。
ResultMap应用场景:
1、数据库字段名与对象属性名不一致
2、复杂的联合查询,自由控制映射场景
3、resultType与resultMap不能同时存在。
如果不想自动映射pojo实体类,需要配置核心文件:
<settings>
<!-- 设置日志文件输出 -->
<setting name="logImpl" value="LOG4J"/>
<!-- autoMappingBehavior属性的作用是是否自动映射属性值
自动映射级别:
NONE禁止。
PARTIAL自动匹配,内嵌除外。
FULL全局自动匹配。
-->
<setting name="autoMappingBehavior" value="FULL"/>
</settings>
Mybatis缓存:
一级缓存:
一级缓存是Mybatis自带的HashMap本地缓存;作用域为session域内,
当session flush或者close之后,该session所有的cache就会被清除。
二级缓存:
二级缓存global caching,它超出session之外,可以被所有sqlsession共享,
开启它只需要在MyBatis核心文件的Settings设置即可。
一级缓存缓存的是SQL语句,二级缓存缓存的是结果对象。
配置全局二级缓存:
<settings>
<!-- 配置全局的二级缓存,二级缓存缓存结果对象。 -->
<setting name="cacheEnabled" value="true"/>
</settings>
单独Mapper文件配置二级缓存:
<mapper namespace="dao.user.userMapper">
<!--
缓存方式:FIFO-先进先出
flushInterval-刷新时间
size-缓存个数
readOnly-是否只读
-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
.......
.......
</mapper>