项目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; } }