添加pom依赖
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
之前用的druid依赖不是boot的,报错 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
改为:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
依赖后ok
spring boot 2.0.0 + mybatis 报:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required 无法启动
google baidu了一番,多数都提示缺少:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
其实最重要的应该是缺少如下数据库连接池的包,我这里用的druid,这里要添加druid for spring boot依赖,如下:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
添加上后项目启动正常。
数据源配置类:
package com.tencent.weather.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import javax.sql.DataSource;
import java.util.Map;
import java.util.Properties;
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.druid.url}")
String url;
@Value("${spring.datasource.druid.username}")
String username;
@Value("${spring.datasource.druid.password}")
String password;
@Value("${spring.datasource.druid.driver-class-name}")
String driverClassName;
@Bean
public DataSource dataSource(StandardEnvironment env) {
Properties properties = new Properties();
DruidDataSource druidDataSource = new DruidDataSource();
PropertySource<?> appProperties = env.getPropertySources().get("applicationConfig: [classpath:/application.yml]");
Map<String, Object> source = (Map<String, Object>) appProperties.getSource();
properties.putAll(source);
druidDataSource.configFromPropety(properties);
druidDataSource.setUrl(url);
druidDataSource.setPassword(password);
druidDataSource.setUsername(username);
druidDataSource.setDriverClassName(driverClassName);
return druidDataSource;
}
}
application.yml的配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/weather?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
username: root
password: root
initialize: true
## 该配置节点为独立的节点,有很多同学容易将这个配置放在spring的节点下,导致配置无法被识别
mybatis:
mapper-locations: classpath:mapper/*.xml #注意:一定要对应mapper映射xml文件的所在路径
type-aliases-package: com.tencent.weather.model # 注意:对应实体类的路径
#mybatis.configuration.map-underscore-to-camel-case=true开启驼峰命名识别
configuration:
map-underscore-to-camel-case: true
项目截图:
mybatis的配置接口类:
package com.tencent.weather.mapper;
import com.tencent.weather.model.UserCity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface WeatherMapper {
UserCity findByCityName(String cityCode);
}
在启动类中最好加上@MapperScan("mapper所在的包名"),其实这个注解和@Mapper二者只要有一个就可以了,都加上也可以,一般如果要省略一个的话,最好不要省略@MapperScan这个注解,还是都加上吧
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@MapperScan("com.tencent.weather.mapper")
public class MyWeatherApplication{
public static void main(String[] args) {
SpringApplication.run(MyWeatherApplication.class, args);
}
}
配置接口类对于的xml配置:
<?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="com.tencent.weather.mapper.WeatherMapper">
<select id="findByCityName" resultType="com.tencent.weather.model.UserCity" parameterType="string">
SELECT
id,
city_id,
city,
parent,
province
from my_weather
WHERE city like concat("%",#{cityId},"%")
</select>
</mapper>
远程调用RestTemplate工具类:
package com.tencent.weather.utils;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
public class HttpClient {
/**
* post请求
* @param url url
* @param params 参数
* @return String 接收参数
*/
public static String sendPostRequest(String url, MultiValueMap<String, String> params){
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
HttpMethod method = HttpMethod.POST;
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params,headers);
ResponseEntity<String> response = client.exchange(url, method, requestEntity,String .class);
return response.getBody();
}
/**
* get请求
* @param url url
* @param params 参数
* @param headers 请求头
* @return String 接收参数
*/
public static String sendGetRequest(String url, MultiValueMap<String,String> params, HttpHeaders headers){
RestTemplate client = new RestTemplate();
HttpMethod method = HttpMethod.GET;
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params,headers);
ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);
return response.getBody();
}
}
复杂json的结构:
json解析和数据获取的类:
package com.tencent.weather.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencent.weather.mapper.WeatherMapper;
import com.tencent.weather.model.CityInfo;
import com.tencent.weather.model.Data;
import com.tencent.weather.model.ResultData;
import com.tencent.weather.model.UserCity;
import com.tencent.weather.service.WeatherService;
import com.tencent.weather.utils.HttpClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.io.IOException;
@Service
@Slf4j
public class WeatherServiceImpl implements WeatherService {
@Autowired
private WeatherMapper weatherMapper;
static HttpHeaders httpHeaders = null;
static MultiValueMap<String,String> paramMap = null;
static String urlPrefix = "http://t.weather.sojson.com/api/weather/city/";
static ObjectMapper mapper = null;
@PostConstruct
public void init(){
mapper = new ObjectMapper();
paramMap = new LinkedMultiValueMap<>();
httpHeaders = new HttpHeaders();
}
@Override
public ResultData getCityWeather(String code) {
ResultData resultData = null;
String url = urlPrefix +code;
String json = HttpClient.sendGetRequest(url, paramMap, httpHeaders);
try {
resultData = parseData(mapper, json);
} catch (Exception e) {
log.error("getCityWeather<|>city_code:"+code,e.getMessage(),e);
}
return resultData;
}
@Override
public ResultData queryWeatherByName(String city) {
UserCity userCity = weatherMapper.findByCityName(city);
if(null == userCity){
log.error("city is not found:"+city);
throw new RuntimeException();
}
String url = urlPrefix + userCity.getCityId();
String json = HttpClient.sendGetRequest(url, paramMap, httpHeaders);
ResultData resultData = parseData(mapper,json);
return resultData;
}
/**
* 解析数据
* @param mapper
* @param json
* @return
*/
public ResultData parseData(ObjectMapper mapper,String json){
JsonNode jsonNode = null;
ResultData resultData = new ResultData();
try {
jsonNode = mapper.readTree(json);
//解析城市的数据
JsonNode city = jsonNode.get("cityInfo");
CityInfo cityInfo = mapper.readValue(city.toString(), CityInfo.class);
//解析data对象的数据
JsonNode dataJson = jsonNode.get("data");
Data data = mapper.readValue(dataJson.toString(), Data.class);
String date = jsonNode.get("date").toString();
String message = jsonNode.get("message").toString();
int status = Integer.parseInt(jsonNode.get("status").toString());
String time = jsonNode.get("time").toString();
resultData.setCityInfo(cityInfo);
resultData.setData(date);
resultData.setDataObj(data);
resultData.setMessage(message);
resultData.setStatus(status);
resultData.setTime(time);
} catch (IOException e) {
log.error("parse is error<|>jsonNode:"+jsonNode.toString(),e.getMessage(),e);
}
return resultData;
}
}
spring boot的启动类,需要排除掉自带的数据源:
package com.tencent.weather;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@MapperScan("com.tencent.weather.mapper")
public class MyWeatherApplication {
public static void main(String[] args) {
SpringApplication.run(MyWeatherApplication.class, args);
}
}
mybatis