在报表类应用中,通常需要根据不同的维度去组合复杂的查询条件,然后构造SQL去执行查询。如果只是通过在程序中简单地拼接SQL语句,工作量会非常大,而且代码可能也非常难以维护。Mybatis支持动态SQL查询功能,可以通过配置动态的SQL来简化程序代码中复杂性,通过XML来处理复杂的数据判断、循环的功能,其实也很好理解。
**
- 准备工作
**
下面,我们首先创建一个MySQL示例表,如下所示:
CREATE TABLE `traffic_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domain` varchar(64) NOT NULL,
`traffic_host` varchar(64) NOT NULL,
`month` varchar(8) NOT NULL,
`monthly_traffic` int(11) DEFAULT '0',
`global_traffic_rank` int(11) DEFAULT '0',
`native_traffic_rank` int(11) DEFAULT '0',
`rank_in_country` varchar(64) DEFAULT NULL,
`address` varchar(200) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`traffic_type` int(2) DEFAULT '-1',
`status` int(2) DEFAULT '0',
`created_at` date DEFAULT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`f1` varchar(255) DEFAULT NULL,
`f2` varchar(255) DEFAULT NULL,
`f3` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_traffic` (`domain`,`month`,`traffic_type`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
这个表用来存储域名的流量信息,流量信息我们从互联网上像Alexa、Compete、Quantcast等提供商获取,通过Crawler抓取的方式实现。我们先从简单的查询做起,只是根据某个字段进行查询,说明如何配置使用Mybatis,这里面也包含如何与Spring进行集成。
**
- 配置实践
**
下面是用到的一些资源的定义:
org.shirdrn.mybatis.TrafficInfo类
该类对应于traffic_info表中一条记录的数据,我们简单取几个字段,如下所示:
package org.shirdrn.mybatis;
import java.io.Serializable;
public class TrafficInfo implements Serializable {
private static final long serialVersionUID = -8696613205078899594L;
int id;
String domain;
String month;
int monthlyTraffic;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public int getMonthlyTraffic() {
return monthlyTraffic;
}
public void setMonthlyTraffic(int monthlyTraffic) {
this.monthlyTraffic = monthlyTraffic;
}
@Override
public String toString() {
return "[id=" + id + ", domain=" + domain + ", month=" +
month + ", monthlyTraffic=" + monthlyTraffic + "]";
}
}
org.shirdrn.mybatis.mapper.TrafficInfoMapper接口类
该类定义了一个与SQL配置进行映射的基本操作,实际的SQL配置有专门的XML文件来进行配置。该接口定义了如下操作:
package org.shirdrn.mybatis.mapper;
import java.util.List;
import java.util.Map;
import org.shirdrn.mybatis.TrafficInfo;
public interface TrafficInfoMapper {
/**
* 根据指定id去查询记录,结果至多只有一条
* @param id
* @return
*/
TrafficInfo getTrafficInfo(int id);
/**
* 根据指定的domain参数查询记录,返回一个记录的列表
* @param domain
* @return
*/
List<TrafficInfo> getTrafficInfoList(String domain);
/**
* 根据一个 字段domain进行查询,但是存在多个domain的值,传入一个数组
* @param domains
* @return
*/
List<TrafficInfo> getMultiConditionsList(String[] domains);
/**
* 根据多个字段进行查询,每个字段可能有多个值,所以参数是Map类型
* @param conditions
* @return
*/
List<TrafficInfo> getMapConditionsList(Map<String, Object> conditions);
}
上面接口中定义的操作,一个比一个复杂,我们通过这一系列操作来说明在Mybatis中如果使用各种查询功能。
org/shirdrn/mybatis/mapper/TrafficInfoMapper.xml映射配置文件
这个文件TrafficInfoMapper.xml对应了上面的org.shirdrn.mybatis.mapper.TrafficInfoMapper中定义的操作,通过XML的方式将对应的SQL查询构造出来,这个是Mybatis的核心功能。该文件的内容示例如下所示:
<?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">
<mapper namespace="org.shirdrn.mybatis.mapper.TrafficInfoMapper">
<resultMap type="TrafficInfo" id="tfMap">
<id property="id" column="id" />
<result property="domain" column="domain" />
<result property="month" column="month" />
<result property="monthlyTraffic" column="monthlyTraffic" />
</resultMap>
<select id="getTrafficInfo" resultType="TrafficInfo" para