一、简单结构,没有业务层
二、pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cfl</groupId>
<artifactId>MybatisElasticsearch</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j-version>1.7.19</slf4j-version>
<log4j-version>1.2.17</log4j-version>
<elasticsearch.version>6.4.2</elasticsearch.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- mybatis和spring的集成包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 阿里巴巴开发的数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>0.2.9</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- io工具 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.9</version>
</dependency>
<!-- es -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
</project>
三、配置
1、MyBatisConfig
package com.cfl.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
public class MyBatisConfig {
@Bean(destroyMethod="close")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
// 设置数据源
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
// 设置mybatis的主配置文件
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/cfl/dao/*.xml"));
return sqlSessionFactoryBean;
}
}
2、MapperScannerConfig
package com.cfl.config;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@AutoConfigureAfter(MyBatisConfig.class) //保证在MyBatisConfig实例化之后再实例化该类
public class MapperScannerConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() throws Exception {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.cfl.dao");
return mapperScannerConfigurer;
}
}
3、EsRestClientConfig
package com.cfl.config;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import java.util.Arrays;
import java.util.Objects;
@Configuration
@PropertySource(value={"classpath:config.properties"})
public class EsRestClientConfig {
private static final int ADDRESS_LENGTH = 2;
private static final String HTTP_SCHEME = "http";
/**
* 使用冒号隔开ip和端口1
*/
@Value("${elasticsearch.ip}")
String[] ipAddress;
@Bean
public RestClientBuilder restClientBuilder() {
HttpHost[] hosts = Arrays.stream(ipAddress)
.map(this::makeHttpHost)
.filter(Objects::nonNull)
.toArray(HttpHost[]::new);
return RestClient.builder(hosts);
}
private HttpHost makeHttpHost(String s) {
assert StringUtils.isNotEmpty(s);
String[] address = s.split(":");
if (address.length == ADDRESS_LENGTH) {
String ip = address[0];
int port = Integer.parseInt(address[1]);
return new HttpHost(ip, port, HTTP_SCHEME);
} else {
return null;
}
}
}
4、EsUtil
package com.cfl.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.cfl.model.base.BaseModel;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.SqlSessionFactory;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class EsUtil {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Autowired
private RestClient restClient;
/**
* 获取es数据
* @param tableName 表名称
* @param mappedStatement mybatis 中的方法(包名.方法名) 如:com.cfl.dao.UserDao.findByName
* @param paramMap 参数
* @return
* @throws Exception
*/
public BaseModel getEsData(String tableName, String mappedStatement, Map<String, Object> paramMap) throws Exception {
// 通过mybatis动态获取dsl
BoundSql bSql = sqlSessionFactory.getConfiguration().getMappedStatement(mappedStatement).getBoundSql(paramMap);
List<ParameterMapping> paramValues = bSql.getParameterMappings();
String sql = getEsSql(bSql.getSql(),paramValues,paramMap);
System.out.println("sql: \n" + sql);
// 通过dsl查询es
String method = "GET";
String endpoint = "/"+tableName+"/_search";
HttpEntity entity = new NStringEntity(sql, ContentType.APPLICATION_JSON);
Response response = restClient.performRequest(method, endpoint, Collections.emptyMap(), entity);
String responseJson = EntityUtils.toString(response.getEntity()).replace("WHERE","");
BaseModel<HashMap<String,Object>> baseModel = JSON.parseObject(responseJson, new TypeReference<BaseModel<HashMap<String,Object>>>(){});
return baseModel;
}
/**
* 获取可执行sql
* @param sql 获取的sql
* @param paramValues 动态参key
* @param map 动态参valur
* @return
*/
private String getEsSql(String sql, List<ParameterMapping> paramValues,Map map) {
while(sql.indexOf("?") != -1 && paramValues.size() > 0) {
String paramName = paramValues.get(0).getProperty();
String paramValue = map.get(paramName).toString();
String value = "";
if (paramValue instanceof String) {
value = "'" + paramValue + "'";
}
sql = sql.replaceFirst("\\?", value);
paramValues.remove(0);
}
return sql.replaceAll("[\\s\\t\\n\\r]", "").replace("'","\"").replace(",}","}").replace(",]","]");
}
}
5、application.yml
server:
port: 9010
servlet:
context-path: /
spring:
thymeleaf:
cache: false
6、config.properties
hibernate.dialect=org.hibernate.dialect.MySQLDialect
driverClassName=com.mysql.jdbc.Driver
validationQuery=SELECT 1
elasticsearch.ip=localhost:9200
五、模型:get、set因太长没有展示出来,需自己添加
1、BaseHits
public class BaseHits<T> {
private String _index;
private String _type;
private String _id;
private Integer _score;
private T _source;
}
2、BaseHitsCount
public class BaseHitsCount<T> {
private Integer total;
private Integer max_score;
private List<BaseHits<T>> hits;
}
3、BaseModel
public class BaseModel<T> {
private Integer took;
private Boolean timed_out;
private BaseShards _shards;
private BaseHitsCount<T> hits;
/**
* 获取返回内容
* @return
*/
public List<T> getContent() {
List<T> list = new ArrayList<T>();
for(BaseHits<T> hits : this.hits.getHits()) {
list.add(hits.get_source());
}
return list;
}
}
4、BaseShards
public class BaseShards {
private Integer total;
private Integer successful;
private Integer skipped;
private Integer failed;
}
5、User
public class User {
private Integer id;
private String name;
private String password;
private String head;
private String jobNumber;
private Integer roleId;
private Integer status;
private Date createDate;
}
六、其它
1、TestController
package com.cfl.controller;
import com.cfl.model.base.BaseModel;
import com.cfl.util.EsUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping(value = "/test/")
public class TestController {
@Autowired
private EsUtil esUtil;
@RequestMapping(value = "list")
public Object test(String oid, String pno, String source, String ios, Integer size) {
try {
Map<String, Object> paramMap = new HashMap<String,Object>();
if(StringUtils.isNotEmpty(oid)) {
paramMap.put("oid",oid);
}
if(StringUtils.isNotEmpty(pno)) {
paramMap.put("pno",pno);
}
if(StringUtils.isNotEmpty(source)) {
paramMap.put("source",source);
}
if(StringUtils.isNotEmpty(ios)) {
paramMap.put("ios",ios);
}
paramMap.put("size",size);
BaseModel baseModel = esUtil.getEsData("user_log","com.cfl.dao.UserDao.findByName",paramMap);
return baseModel.getContent();
}catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
2、UserDao
package com.cfl.dao;
import com.cfl.model.User;
import org.apache.ibatis.annotations.Param;
public interface UserDao {
User findByName(@Param("name") String name);
}
3、UserDao.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.cfl.dao.UserDao" >
<select id="findByName" parameterType="java.lang.String">
{
<if test="size != null">"size": #{size},</if>
<if test="size == null">"size": 10,</if>
"query": {
"bool": {
"must": [
<if test="oid != null">{"match": {"oid": #{oid}}},</if>
<if test="pno != null">{"match": {"pno": #{pno}}},</if>
<if test="source != null">{"match": {"source": #{source}}},</if>
<if test="ios != null">{"match": {"ios": #{ios}}},</if>
]
}
}
}
</select>
</mapper>
4、App
package com.cfl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@ComponentScan(basePackages = {"com.cfl"})
public class App
{
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
}