原创

Spring Boot (二)集成Mybatis、Druid


项目GitHub地址 :

https://github.com/FrameReserve/TrainingBoot


Spring Boot (二)集成Mybatis、Druid,标记地址:

https://github.com/FrameReserve/TrainingBoot/releases/tag/0.0.2



pom.xml

<?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.training</groupId>
	<artifactId>TrainingBoot</artifactId>
	<version>1.0.0</version>
	<packaging>war</packaging>

	<name>TrainingBoot</name>
	<description>The first Spring Boot project</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<!--  依赖版本  -->
		<mybatis.version>3.4.1</mybatis.version>
		<mybatis.spring.version>1.3.0</mybatis.spring.version>
	</properties>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
		
		<resources>  
    
	    	<resource>
		  		<directory>src/main/java</directory>
		  		<includes>
		  			<include>**/*.properties</include>
		  			<include>**/*.xml</include>
		  		</includes>
		  		<!-- 是否替换资源中的属性-->
		  		<filtering>false</filtering>
	  		</resource>
	  		
	  		<resource>
	  			<directory>src/main/resources</directory>
	  			
	            <!-- 是否替换资源中的属性-->
	            <filtering>true</filtering>          
	        </resource>
	  		
	    </resources>
    
	</build>
	
	

	<dependencies>
	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</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-web</artifactId>
		</dependency>
		
		<dependency>  
	        <groupId>org.springframework.boot</groupId>  
	        <artifactId>spring-boot-starter-tomcat</artifactId>  
	        <scope>provided</scope>  
	    </dependency>
	    
	    <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
	    
	    <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		
	    <!-- mysql -->
	    <dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.25</version>
		</dependency>

		<!--Mybatis-->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>

		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis.spring.version}</version>
		</dependency>

		<!--通用MAPPER-->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper</artifactId>
			<version>3.3.7</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.1.6</version>
		</dependency>
		
		<!-- swagger -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.2.2</version>
		</dependency>
		
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.2.2</version>
		</dependency>
		
		<!-- Apache Commons Lang -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		
		<!-- Gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.2</version>
        </dependency>
        
        <!-- utils -->
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-core</artifactId>
            <version>3.4.2</version>
        </dependency>
		
	</dependencies>

</project>


src/main/resources/application.yml

spring:
    datasource:
        name: dataSource 
        url: jdbc:mysql://192.168.2.63:3306/training 
        username: root 
        password: 123 
        # 使用druid数据源 
        type: com.alibaba.druid.pool.DruidDataSource 
        driver-class-name: com.mysql.jdbc.Driver 
#        filters: stat
#        maxActive: 20
#        initialSize: 1
#        maxWait: 60000
#        minIdle: 1
#        timeBetweenEvictionRunsMillis: 60000
#        minEvictableIdleTimeMillis: 300000
#        validationQuery: select 'x'
#        testWhileIdle: true
#        testOnBorrow: false
#        testOnReturn: false
#        poolPreparedStatements: true
#        maxOpenPreparedStatements: 20



MyBatis配置类:

src/main/java/com/training/core/mybatis/MyBatisConfig.java

package com.training.core.mybatis;

import com.github.pagehelper.PageHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created by Athos on 2016-10-13.
 */
@Configuration
@EnableTransactionManagement
public class MyBatisConfig implements TransactionManagementConfigurer {

    @Autowired
    private DataSource dataSource;

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean() {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage("com.training");

        //分页插件
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("returnPageInfo", "check");
        properties.setProperty("params", "count=countSql");
        pageHelper.setProperties(properties);

        //添加插件
        bean.setPlugins(new Interceptor[]{pageHelper});

        //添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            bean.setMapperLocations(resolver.getResources("classpath:**/mapper/*.xml"));
            return bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
}


src/main/java/com/training/core/mybatis/MyBatisMapperScannerConfig.java

package com.training.core.mybatis;

import java.util.Properties;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;


/**
 * Created by Athos on 2016-10-06.
 */
@Configuration
//TODO 注意,由于MapperScannerConfigurer执行的比较早,所以必须有下面的注解
@AutoConfigureAfter(MyBatisConfig.class)
public class MyBatisMapperScannerConfig {
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        //这里的BasePackage 不能写com.training,估计跟spring 的扫描冲突,会实例化两个service,应该需要重构目录
        mapperScannerConfigurer.setBasePackage("com.training.*.mapper");
        Properties properties = new Properties();
        properties.setProperty("mappers", Mapper.class.getName());
        properties.setProperty("notEmpty", "false");
        properties.setProperty("IDENTITY", "MYSQL");
        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }
}



//--------------------------------------------- 业务代码 -------------------------------------------------------------------------------------


定义BaseEntity,方便后期反射,统一增删改查

package com.training.core.entity;

import java.io.Serializable;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonProperty;
import tk.mybatis.mapper.annotation.NameStyle;
import tk.mybatis.mapper.code.Style;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@NameStyle(value = Style.camelhumpAndLowercase)
public class BaseEntity implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonProperty("id")
    private Integer id;

	/**
	 * 创建时间
	 */
	@Column
	private Date createTime;
	
	/**
	 * 最后修改时间
	 */
	@Column
	private Date lastModifyTime;
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Date getLastModifyTime() {
		return lastModifyTime;
	}

	public void setLastModifyTime(Date lastModifyTime) {
		this.lastModifyTime = lastModifyTime;
	}
}



BaseDao统一增删改查接口:

src/main/java/com/training/core/dao/BaseDao.java

package com.training.core.dao;

import java.util.List;

import tk.mybatis.mapper.entity.Example;

import com.training.core.dto.FlexiPageDto;
import com.training.core.entity.BaseEntity;

public interface BaseDao<T extends BaseEntity> {

	/**
	 * 根据Id查询实体
	 */
	public T getEntityById(final Class<T> cls, final Integer id);
	
	/**
	 * 新增实体
	 */
	public void addEntity(final T entity);
	
	/**
	 * 更新实体
	 */
	public void updateEntity(final T entity);
	
	/**
	 * 根据Id删除实体
	 */
	public void deleteEntityById(final Class<T> cls, final Integer id);

	/**
	 * 查询全部
     */
	public List<T> selectAll(Class<T> cls);
	
	/**
	 * 单表模糊查询
	 */
	public List<T> findByLike(Example example);
	
	/**
	 * 根据模糊分页查询
	 */
	public List<T> findByPage(Example example, FlexiPageDto flexiPageDto);
	
	/**
	 * 单表模糊查询总记录数
	 */
	public int findRowCount(Example example);
	
	
}

BaseDao统一增删改查实现:

src/main/java/com/training/core/dao/impl/MyBatisBaseDaoImpl.java

package com.training.core.dao.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import com.training.core.annotation.MapperClass;
import com.training.core.dao.BaseDao;
import com.training.core.dto.FlexiPageDto;
import com.training.core.entity.BaseEntity;

@Repository("myBatisBaseDao")
@SuppressWarnings("unchecked")
public class MyBatisBaseDaoImpl<T extends BaseEntity> implements BaseDao<T> {
    
    @Resource
    @Qualifier("sessionFactory")
    private SqlSessionFactory sqlSessionFactory;
    
    private SqlSession sqlSession;
    
    @SuppressWarnings("rawtypes")
    public <M extends Mapper<T>> M getMapper(Class cls){
        MapperClass mapperClass = (MapperClass) cls.getAnnotation(MapperClass.class);
        if(null == mapperClass){
            throw new RuntimeException("没有注解MapperClass");
        }
             return (M) getSqlSession().getMapper(mapperClass.value());
    }

    @Override
    public T getEntityById(Class<T> cls, Integer id) {
        return this.getMapper(cls).selectByPrimaryKey(id);
    }

    @Override
    public void addEntity(T entity) {
        this.getMapper(entity.getClass()).insert(entity);
    }

    @Override
    public void updateEntity(T entity) {
        this.getMapper(entity.getClass()).updateByPrimaryKey(entity);
    }

    @Override
    public void deleteEntityById(Class<T> cls, Integer id) {
        this.getMapper(cls).deleteByPrimaryKey(id);
    }

    @Override
    public List<T> selectAll(Class<T> cls) {
        return this.getMapper(cls).selectAll();
    }

    @Override
    public List<T> findByLike(Example example) {
        return this.getMapper(example.getEntityClass()).selectByExample(example);
    }

    @Override
    public List<T> findByPage(Example example, FlexiPageDto flexiPageDto) {
        
        RowBounds rowBounds = new RowBounds(flexiPageDto.getOffset(), flexiPageDto.getRp());
        return this.getMapper(example.getEntityClass()).selectByExampleAndRowBounds(example, rowBounds);
    }

    @Override
    public int findRowCount(Example example) {
        return this.getMapper(example.getEntityClass()).selectCountByExample(example);
    }
    
    public SqlSession getSqlSession(){
        if (null == sqlSession){
            synchronized (MyBatisBaseDaoImpl.class) {
                this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
            }
        }
        return this.sqlSession;
    }
    
}




工具类、辅助类:


1. 自定义注解,指定Mapper Class。方便后期实现统一增删改查。

src/main/java/com/training/core/annotation/MapperClass.java

package com.training.core.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by Athos on 2016-07-04.
 */
@SuppressWarnings("unchecked")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MapperClass{
	/**
	 *指定 MapperClass
	 */
    Class value();
}


2. 分页工具类

src/main/java/com/training/core/dto/FlexiPageDto.java

package com.training.core.dto;


public class FlexiPageDto {

	public static final Integer MAX_PAGE_SIZE=3000;
	public static final Integer SHORT_PAGE_SIZE=5;
	
	public FlexiPageDto() {
		super();
	}

	public FlexiPageDto(Integer page, Integer rp) {
		super();
		this.page = page;
		this.rp = rp;
	}

	public FlexiPageDto(Integer page, Integer rp, String sortName) {
		super();
		this.page = page;
		this.rp = rp;
		this.sortName = sortName;
	}

	public FlexiPageDto(Integer page, Integer rp, String sortName, String sortOrder) {
		super();
		this.page = page;
		this.rp = rp;
		this.sortName = sortName;
		this.sortOrder = sortOrder;
	}
	
	public static FlexiPageDto createMaxPageDto(){
		FlexiPageDto flexiPageDto=new FlexiPageDto();
		flexiPageDto.setRp(MAX_PAGE_SIZE).setPage(1);
		return flexiPageDto;
	}
	public static FlexiPageDto generateFlexiPageDto(Integer page, Integer rp, String orderBy) {
		FlexiPageDto flexiPageDto = new FlexiPageDto(page, rp);
		if (null != orderBy && "" != orderBy.trim()) {
			String[] orderBys = orderBy.split("_");
			flexiPageDto.setSortName(orderBys[0]);
			flexiPageDto.setSortOrder(orderBys[1]);
		}
		return flexiPageDto;
	}

	/**
	 * 当前页
	 */
	private Integer page;
	
	/**
	 * 每页显示,默认:10
	 */
	private Integer rp = 10;
	
	/**
	 * 总记录数
	 */
	private Integer rowCount;
	
	/**
	 * 排序字段
	 */
	private String sortName;
	
	/**
	 * 排序(asc/desc)
	 */
	private String sortOrder = "desc";
	
	public static final String SORTORDER_ACS = "asc";
	
	/**
	 * 数据开始坐标,Mysql从0开始
	 */
	public Integer getOffset(){
		return (this.getPage()-1)*this.getRp();
	}
	
	/**
	 * 总页数
	 */
	public Integer getTotalPage() {
		if (null == rowCount) {
			return 0;
		}
		int totalPage = (rowCount / rp);
		int remainder = rowCount % rp;
		if (rowCount > 0 && totalPage == 0) {
			totalPage = 1;
			return totalPage;
		}
		if (remainder > 0) {
			totalPage++;
			return totalPage;
		}
		return totalPage;		
	}

	// -------------------------- getter and setter -----------------------------
	public Integer getRp() {
		return rp;
	}

	public FlexiPageDto setRp(Integer rp) {
		this.rp = rp;
		return this;
	}

	public Integer getPage() {
		return page;
	}

	public FlexiPageDto setPage(Integer page) {
		this.page = page;
		return this;
	}

	public String getSortName() {
		return sortName;
	}

	public FlexiPageDto setSortName(String sortName) {
		this.sortName = sortName;
		return this;
	}

	public String getSortOrder() {
		return sortOrder;
	}

	public FlexiPageDto setSortOrder(String sortOrder) {
		this.sortOrder = sortOrder;
		return this;
	}

	public Integer getRowCount() {
		return rowCount;
	}

	public FlexiPageDto setRowCount(Integer rowCount) {
		
		this.rowCount = rowCount;
		return this;
	}
	
	public String getSortString(){
		
		if (null == sortName) {
			return null;
		}
		String[] fields = this.getSortName().split("_");
		String[] fieldsorts = this.getSortOrder().split("_");
		if(fields.length!=fieldsorts.length){
			throw new RuntimeException("排序规则不一致");
		}
		
		String sql = "";
		for(int index=0;index<fields.length;index++){
			sql = sql+" "+fields[index]+" "+fieldsorts[index];
		}
		
		return sql;
	}

}







































正文到此结束
Loading...