版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jeffiny/article/details/81510554
1、数据库表的设计如下:
DROP TABLE IF EXISTS `crawler_device`;
CREATE TABLE `crawler_device` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`vendor_name` varchar(32) NOT NULL COMMENT '终端制造商名称',
`vendor_url` varchar(128) NOT NULL COMMENT '终端制造商页面',
`device_name` varchar(48) NOT NULL COMMENT '终端型号名称',
`device_format_name` varchar(48) DEFAULT NULL COMMENT '终端型号格式化名称',
`device_url` varchar(128) NOT NULL COMMENT '终端制造商页面',
`os_name` varchar(48) DEFAULT NULL COMMENT '操作系统名称',
`os_format_name` varchar(48) DEFAULT NULL COMMENT '操作系统格式化名称',
`price` varchar(32) NOT NULL COMMENT '价格或产品状态',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `device_url` (`device_url`)
) ENGINE=InnoDB AUTO_INCREMENT=11814 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
2、利用hibernate 对数据库进行操作;
按照ID和unique Key对数据进行更新;
package com.everdata.crawlers.main;
import java.io.IOException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Property;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.everdata.common.constant.CommonConstants;
import com.everdata.crawlers.dao.impl.CrawlerDeviceDaoImpl;
import com.everdata.crawlers.dao.impl.CrawlerVendorDaoImpl;
import com.everdata.crawlers.domain.CrawlerDevice;
import com.everdata.crawlers.domain.CrawlerVendor;
import com.everdata.crawlers.format.DeviceFormat;
import com.everdata.crawlers.vo.DeviceVo;
import com.everdata.crawlers.vo.VendorVo;
public void crawler() {
//获取所有的品牌;
List<VendorVo> list = getVendors();
CrawlerVendorDaoImpl manufDao = new CrawlerVendorDaoImpl();
CrawlerDeviceDaoImpl deviceDao = new CrawlerDeviceDaoImpl();
for (VendorVo vo : list) {
//DetachedCriteria:离线创建criteria 且好构建查询条件;DetachedCriteria类允许你在Hibernate的Session范围外创建一个查询,
//然后使用任意一个Session环境去执行它;
DetachedCriteria dc_manu = DetachedCriteria.forClass(CrawlerVendor.class);
//如果为空则保存到数据库;
String url = vo.getUrl();
DetachedCriteria dc = dc_manu.add(Property.forName("vendorUrl").eq(url));
List<CrawlerVendor> fdc = manufDao.findByDetachedCriteria(dc);
if (fdc.isEmpty()) {
System.out.println(vo);
manufDao.save(toCrawlerVendor(vo));
} else {
logger.info(vo.getVendor() + " :this vendor is exist!");
}
//获取每个品牌对应的型号;
List<DeviceVo> devices = getDevices(vo);
for (DeviceVo device : devices) {
DetachedCriteria dc_device = DetachedCriteria.forClass(CrawlerDevice.class);
List<CrawlerDevice> fd = deviceDao.findByDetachedCriteria(dc_device.add(Property.forName("deviceUrl").eq(device.getUrl())));
CrawlerDevice result = toCrawlerDevice(device);
if (fd.isEmpty()) {
deviceDao.save(result);
logger.info(result+ "saved");
} else {
String sql="update crawler_device set vendor_name=\""+result.getVendorName()
+", vendor_url="+result.getVendorUrl()
+", device_name="+result.getDeviceName()
+", device_format_name="+result.getDeviceFormatName()
+", os_name="+result.getOsName()
+", os_format_name="+result.getOsFormatName()
+", price="+result.getPrice()
+", update_time="+result.getUpdateTime()
+" where device_url="+result.getDeviceUrl()
+" and id="+fd.get(0).getId();
deviceDao.executeNativeSql(sql);
logger.info(result + " updated!");
}
}
}
}
3、报错具体如下:
Space is not allowed after parameter prefix ':'
4、解决方式
4.1 网上有很多的解决方式都是在“:”前加转义字符 \\;
4.2 我查看数据表的设计,所有的字段都设计为varchar;且报错的字段只与和URL相关的字段有关系;查看其执行过程:
update
crawler_device
set
vendor_name=魅蓝,
vendor_url=http://product.cnmo.com/pro_sub_manu/sub_57_manu_32909_1_2.shtml,
device_name=魅蓝U10(16GB),
device_format_name=魅蓝U10,
os_name=YunOS,
os_format_name=其他,
price=停产,
update_time=2018-08-08
where
device_url=http://product.cnmo.com/cell_phone/index1623436.shtml
and id=11111
发现很多字段应该为varchar 但是没有单引号或者双引号,因此很可能是因为没有双引号才导致在解析字段的时候把字符串没有当做一个整体;因此做如下测试,给varchar字段都加上双引号 “ " ”:
Hibernate:
update
crawler_device
set
vendor_name="魅蓝",
vendor_url="http://product.cnmo.com/pro_sub_manu/sub_57_manu_32909_1_2.shtml",
device_name="魅蓝Note5(64GB)",
device_format_name="魅蓝Note5",
os_name="Flyme 5",
os_format_name="Flyme",
price="停产",
update_time="2018-08-08"
where
device_url="http://product.cnmo.com/cell_phone/index1623567.shtml"
and id="11643"
4.3 结果
CRUD都不存在"Hibernate Space is not allowed after parameter prefix ':' "的错误,且能够正常的执行,查看数据库文件也正常;