Mybatis的配置文件可以看看:
https://mybatis.org/mybatis-3/zh/configuration.html。
在平常的项目中对于复杂的查询,我们现在就要使用到动态SQL,来定义 SQL 映射语句了。 首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等。下面的配置会告诉 MyBatis 去哪里找映射文件
2. SQL映射文件
cache – 该命名空间的缓存配置。
cache-ref – 引用其它命名空间的缓存配置。
resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
sql – 可被其它语句引用的可重用语句块。
insert – 映射插入语句。
update – 映射更新语句。
delete – 映射删除语句。
select – 映射查询语句。
简单的select
在Peison表中根据id查询一条Person数据,使用Person对象进行封装。
2.2. select常见的元素(1) id:在命名空间中唯一的标识符,可以被用来引用这条语句。
(2) parameterType:将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
(3) resultType:期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
(4) resultMap:结果映射是 MyBatis 最强大的特性,可以将查询到的复杂数据或者多表数据映射到一个结果集当中。
2.3. select映射拼接sql<--column属性:用于指定数据库列名。property属性:用于指定实体类属性-->
select映射查询语句
2.4. sql标签这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。此
2.5. 理解复杂select与sqlAND psn.serial_number LIKE #{pattern1} AND hi.imei LIKE #{pattern2} AND psn.production_batch = #{enquiryDto.productionBatch} AND psn.specification_model = #{enquiryDto.specificationModel} AND psn.status = #{enquiryDto.status} AND psn.type = #{enquiryDto.type}
DISTINCT, isnull()与CAST()函数
--内连接,INNER JOIN 与 JOIN 是相同的,显示相等的数据;
--左连接显示左表的所有数据,右连接显示右表的所有数据,全连接显示两个表的所有数据
INNER JOIN pur_purchase_detail pur_d ON pur_d.detail_id = che_d.purchase_detail_id AND pur_d.apply_id =
pur_a.apply_id
LEFT JOIN pur_check che ON che.check_id = che_d.check_id
FOR XML PATH ('')
--IN 操作符允许我们在 WHERe 子句中规定多个值,即查询的数据应满足IN中的内容
) AS checkInfo IN
#{applyId}
--动态SQL if标签我们的项目中模糊查询很多都用到了if,如果模糊条件不为空,则执行模糊查询,如果为空就到此为止
--动态SQL bind标签
--在进行模糊查询时,如果使用“${}”拼接字符串,会出现SQL注入问题。如果使用字符串拼接函数或连接符号,不同数据库的拼接函数或连接符号不同。例如 MySQL 的 concat 函数、Oracle 的连接符号“||”,不利于代码的移植。MyBatis 提供了 元素来解决这一问题。
--AND 和 OR 可在 WHERe 子语句中把两个或多个条件结合起来。
--如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
--如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录
OR equ_a.model_organ_id IN
#{organId}
INNER JOIN crm_contract_formal contract ON contract.contract_formal_id = pur_a.formal_contract_id
AND contract.title LIKE #{contractTitle}
--foreach的属性
foreach的属性:
item:表示集合中每个元素进行迭代时的别名。
open:表示该语句以什么开始(既然是in条件语句,所以必然以“(”开始)。
separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是in条件语句,所以必须以“.”,作为分隔符)。
close:表示该语句以什么语句结束(既然是in条件语句,所以必然是以“)”结束)。
collection:最关键并最容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的。主要有三种情况:
1. 若入参为单参数且参数类型是一个List的时候,collection属性值为list。
2. 若入参为单参数且参数类型是一个数组的时候,collection属性值为array(此处传入参数Integer[] rolelds为数组类型,故此处3. 3. collection属性值设为“array”)。
3. 若传入参数为多参数,就需要把他们封装为一个Map进行处理。select中返回的是一个resultMap(id=“userMapByRole”),该resultMap也进行相应的字段映射。
SQL Server中 join 等效于inner join
--利用Case When Then Else End 多条件判断,例如我们在数据库中查到的是类型代码1,2,3...通过类型代码转为相应表示的文本值;则case后面则是在数据库中查询到的类型代码,满足when条件则为then后面的结果值,如果为else后面的空值或异常值则结束比较。
SELECT DISTINCT
equ_d.apply_code + ',' +
case isnull(CAST (equ_a.use_type2 AS VARCHAR (1)),'')
when '1' then '生产'
when '2' then '试验'
when '3' then '销售'
when '4' then '公司自用'
else '' end
+ ';'
FROM
pur_equipment_detail equ_d
LEFT JOIN pur_equipment_apply equ_a ON equ_a.apply_id = equ_d.apply_id
LEFT JOIN pur_purchase_detail pur_d ON pur_d.apply_code = equ_d.apply_code
AND pur_d.model_id = equ_d.model_id
--Row_number()为pay表的每一行添加一个行号,给行号这一列取名’PAGE_ROW_NUMBER’ 在over()方法中将’PAGE_ROW_NUMBER’随机排序,order by rand()--随机抽取数据
–然后将’PAGE_ROW_NUMBER’列 与pay表的所有列 形成一个表PAGE_TABLE_ALIAS
–where条件。假如当前页(currentPage)是第2页,每页显示10个数据(pageSzie)。那么第一页的数据就是第11-20条
–所以为了显示第二页的数据,即显示第11-20条数据,那么就让PAGE_ROW_NUMBER大于 10*(2-1) 即:页大小*(当前页-1)
${iDisplayStart}:页大小*(当前页-1)
FROM
(
SELECt
ROW_NUMBER ( ) OVER ( ORDER BY RAND( ) ) PAGE_ROW_NUMBER,
amount,
totalPrice,
${key}
FROM
pay AS PAGE_TABLE_ALIAS ) AS PAGE_TABLE_ALIAS
WHERe
PAGE_ROW_NUMBER > ${iDisplayStart}
ORDER BY
PAGE_ROW_NUMBER
)
ORDER BY
${key}
标签组:也是一个用于条件判断的标签组,和的不同之处在于条件从进入,去匹配中的添加,一旦匹配马上结束;若到找不到匹配项,将执行中的语句;可以理解为是 && 关系 是 || 关系
INNER JOIN hwoa.dbo.cost_pay_record pay ON pay.module_id = 2 AND pay.module_data_id = pur_a.apply_id
AND pay.approval_state = #{req.payState}
AND pay.expected_pay_date >= #{req.payApplyBeginTime}
AND pay.expected_pay_date dateadd(DAY, 1, #{req.payApplyEndTime})
AND pay.real_pay_date >= #{req.payRealBeginTime}
AND pay.real_pay_date dateadd(DAY, 1, #{req.payRealEndTime})
AND pay.company_id = #{req.companyId}
AND pay.id = #{req.payId}
LEFT JOIN hwoa.dbo.cost_pay_record pay ON pay.module_id = 2 AND pay.module_data_id = pur_a.apply_id
ORDER BY
--ConVERT() 函数可以用不同的格式显示日期/时间数据。
--EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。
convert(varchar(10),a.review_time,120) pucharseReviewTime,
(
SELECT
cast(cd.check_id as varchar) + ';'
FROM
pur_check_detail cd
WHERe
cd.purchase_detail_id = d.detail_id
and exists(select 1 from pur_check c where c.check_id = cd.check_id and c.check_sate 8)
for xml path('')
) checkId,
--include 包含了id为purchaseGroupBefore的sql标签
SELECT COUNT (*)
FROM
( SELECt
${key}
FROM pay GROUP BY
${key}
) temp
--WITH AS短语,也叫做子查询部分(subquery factoring),可以定义一个SQL片断,该SQL片断会被整个SQL语句用到。可以使SQL语句的可读性更高,也可以在UNIOn ALL的不同部分,作为提供数据的部分。
--例如:with A as (select * from class)
--这个语句的意思就是,先执行select * from class 得到一个结果,将这个结果记录为A ,在执行select *from A 语句。A 表只是一个别名。
WITH detail AS (SELECt
ISNULL(rs.amount, 0) as amount, ISNULL(rs.avgPrice, 0) as avgPrice, ISNULL(rs.totalPrice, 0) as
totalPrice,
m.model_id as modelId, m.model_code as modelCode, m.model as modelName, m.model,
pt.type_id as parentTypeId, pt.type_name as parentTypeName, t.type_id as typeId, t.type_name as typeName,
pt.type_name + '-' + t.type_name + '-' + m.model AS material,
isnull( rs.customerName, '无供应商' ) AS customerName,
isnull( rs.organName, '无部门' ) AS organName,
isnull( rs.projectGroupName, '无项目群' ) AS projectGroupName,
isnull( rs.batchName, '无批次' ) AS batchName,
isnull( rs.projectName, '非项目' ) AS projectName
, rs.project_id as projectId, rs.project_name as projectName
, rs.contract_id as contractId, rs.contract_title as contractTitle
, rs.customer_id as customerId, rs.customer_name as customerName
FROM (
SELECt SUM(ptb.true_amount) as amount, avg(ptb.true_price) as avgPrice, SUM(ptb.true_total_price) as totalPrice,
etb.project_id, etb.project_name,
etb.contract_id, etb.contract_title,
etb.customer_id, etb.customer_name,
ptb.model_id,
ptb.customerName,
ptb.organName,
ptb.projectGroupName,
ptb.batchName,
ptb.projectName
from (
(
select a.apply_id, a.apply_code, d.model_id, d.project_id, d.project_name, d.contract_id, d.contract_title,
d.customer_id, d.customer_name from pur_equipment_detail d
left join pur_equipment_apply a on d.apply_id=a.apply_id where 1=1
and d.project_name like #{pattern}
and d.contract_title like #{pattern}
and d.customer_name like #{pattern}
) etb
inner join
(
select a.apply_id, a.process_time, d.detail_id, d.apply_code, d.model_id, d.true_amount, d.true_price,
d.true_total_price,
d.customer_name AS customerName,
org.name AS organName,
pg.name AS projectGroupName,
ba.name AS batchName,
pro.name AS projectName
from pur_purchase_detail d
LEFT JOIN pur_purchase_apply a ON d.apply_id=a.apply_id
LEFT JOIN hwoa.dbo.config_organ_v org ON org.id = d.organ_id
LEFT JOIN crm_project_group_v pg ON pg.group_id = a.project_group_id
LEFT JOIN crm_production_batch_v ba ON ba.batch_id = d.batch_id
LEFT JOIN crm_project_v pro ON pro.project_id = d.project_id
where 1=1
and a.is_delete=0
and a.apply_state in (2,7,8)
and a.process_time =]]> #{beginTime}
and a.process_time #{endTime}
) ptb on etb.apply_code=ptb.apply_code and etb.model_id=ptb.model_id
) group by ptb.model_id,
ptb.organName,
ptb.projectGroupName,
ptb.batchName,
ptb.projectName,
ptb.customerName
, etb.project_id, etb.project_name
, etb.contract_id, etb.contract_title
, etb.customer_id, etb.customer_name
) rs
inner join pur_goods_model m on m.model_id=rs.model_id
and m.model_id=#{modelId}
and m.model like #{pattern}
join pur_goods_type t on t.type_id=m.type_id
and t.type_id=#{typeId}
join pur_goods_type pt on pt.type_id=t.parent_id
and pt.type_id=#{parentId}
),
pay AS (
SELECT
${key}
SUM ( amount ) AS amount,
SUM ( totalPrice ) AS totalPrice
FROM
detail
GROUP BY
${key}
)



