springboot tkmybatis 通用service

方便日后快速搭建项目,记录下。

1. 首先创建springboot项目,略过。

2. 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.sosmmh</groupId>
	<artifactId>tkmybatis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>tkmybatis</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.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>
	</properties>

	<dependencies>
		<!--web层-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!--mysql数据库驱动-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--mybatis-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.0</version>
		</dependency>

		<!--分页插件-->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.2.1</version>
		</dependency>

		<!--数据库连接池-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.29</version>
		</dependency>

		<!--tkmybatis-->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>1.1.4</version>
		</dependency>

		<!-- 单元测试 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

3. 目录如下,注意通用MyMapper接口不能被扫描,所以不能跟具体的mapper放在同一目录。


从上往下介绍下每个类的作用:

MybatisConfigurer:主要配置sqlSessionFactoryBean、分页插件、mapper.xml目录、Mapper接口、通用Mapper接口。

MyMapper:通用mapper接口

ProjectConstant:包名

BaseService:通用service接口

AbStractService:抽象service实现类

4. 具体类代码 

MybatisConfigurer.java

package com.sosmmh.tkmybatis.configurer;

import com.github.pagehelper.PageHelper;
import com.sosmmh.tkmybatis.core.ProjectConstant;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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 tk.mybatis.spring.mapper.MapperScannerConfigurer;

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

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:27
 * @Description:
 */
@Configuration
public class MybatisConfigurer {

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE);

        //配置分页插件,详情请查阅官方文档
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("pageSizeZero", "true");//分页尺寸为0时查询所有纪录不再执行分页
        properties.setProperty("reasonable", "true");//页码<=0 查询第一页,页码>=总页数查询最后一页
        properties.setProperty("supportMethodsArguments", "true");//支持通过 Mapper 接口参数来传递分页参数
        pageHelper.setProperties(properties);

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

        //添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factory.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
        return factory.getObject();
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        //Mapper接口目录,具体的mapper
        mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE);

        //配置通用Mapper,详情请查阅官方文档
        Properties properties = new Properties();
        properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE);
        properties.setProperty("notEmpty", "false");//insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
        properties.setProperty("IDENTITY", "MYSQL");
        mapperScannerConfigurer.setProperties(properties);

        return mapperScannerConfigurer;
    }
}

MyMapper.java

package com.sosmmh.tkmybatis.core;

import tk.mybatis.mapper.common.BaseMapper;
import tk.mybatis.mapper.common.ConditionMapper;
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.special.InsertListMapper;

/**
 * 定制版MyBatis Mapper插件接口,如需其他接口参考官方文档自行添加。
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:35
 * @Description:
 */
public interface MyMapper<T>
        extends
        BaseMapper<T>,
        ConditionMapper<T>,
        IdsMapper<T>,
        InsertListMapper<T> {
}
ProjectConstant.java
package com.sosmmh.tkmybatis.core;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:27
 * @Description: 项目名常量
 */
public final class ProjectConstant {
    public static final String BASE_PACKAGE = "com.sosmmh.tkmybatis";	//项目基础包名称,根据自己公司的项目修改

    public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";	//Model所在包
    public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";	//Mapper所在包
    public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";	//Service所在包
    public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";	//ServiceImpl所在包
    public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".controller";	//Controller所在包

    public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.MyMapper";	//Mapper插件基础接口的完全限定名
}

5. 配置好基础的通用mapper接口后,具体的接口实现

package com.sosmmh.tkmybatis.mapper;

import com.sosmmh.tkmybatis.core.MyMapper;
import com.sosmmh.tkmybatis.model.User;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:21
 * @Description:
 */
public interface UserMapper extends MyMapper<User>{

}

6. User.java

package com.sosmmh.tkmybatis.model;


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

/**
 * @Auther: sosmmh
 * @Date: 2018/4/19 16:53
 * @Description:
 */
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;

    private String password;

    private String name;

    private Integer age;

get set ...省略
}

7. 单元测试,idea:选择类名->点击右键->Test->Create New Test ...


注意在单元测试时,给类加上注解。Assert.assertEquals用于判断结果与期待的是否相等。成功没问题后,到这里通用mapper就已经完成了。

package com.sosmmh.tkmybatis.mapper;

import com.sosmmh.tkmybatis.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:23
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void findAllTest() {
        System.out.println(userMapper.selectAll());
    }

    @Test
    public void insertTest() {
        User user = new User();
        user.setUsername("[email protected]");
        user.setPassword("1234");
        user.setAge(14);
        user.setName("土豆16");

        Assert.assertEquals(1,userMapper.insert(user));
    }

    @Test
    public void updateTest() {
        User user = userMapper.selectByPrimaryKey(17);
        user.setName("土豆17");
        Assert.assertEquals(1,userMapper.updateByPrimaryKey(user));
    }

    @Test
    public void delTest() {
        Assert.assertEquals(1, userMapper.deleteByPrimaryKey(17));
    }

    @Test
    public void conditionTest() {
    }
}

8. 通用service接口,主要要加上泛型

package com.sosmmh.tkmybatis.service;

import org.apache.ibatis.exceptions.TooManyResultsException;
import tk.mybatis.mapper.entity.Condition;

import java.util.List;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 09:35
 * @Description: Service 层 基础接口,其他Service 接口 请继承该接口
 * @param <T>
 */
public interface BaseService<T> {
    void save(T model);//持久化
    void save(List<T> models);//批量持久化
    void deleteById(Integer id);//通过主鍵刪除
    void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”
    void update(T model);//更新
    T findById(Integer id);//通过ID查找
    T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束
    List<T> findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4”
    List<T> findByCondition(Condition condition);//根据条件查找
    List<T> findAll();//获取所有
}

9. 抽象类实现通用service

package com.sosmmh.tkmybatis.service.impl;


import com.sosmmh.tkmybatis.core.MyMapper;
import com.sosmmh.tkmybatis.service.BaseService;
import exception.ServiceException;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Condition;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 基于通用MyBatis Mapper插件的Service接口的实现
 */
public abstract class AbstractService<T> implements BaseService<T> {

    @Autowired
    protected MyMapper<T> mapper;

    private Class<T> modelClass;    // 当前泛型真实类型的Class

    public AbstractService() {
        // 获得具体model,通过反射来根据属性条件查找数据
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public void save(T model) {
        mapper.insertSelective(model);
    }

    @Override
    public void save(List<T> models) {
        mapper.insertList(models);
    }

    @Override
    public void deleteById(Integer id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByIds(String ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public void update(T model) {
        mapper.updateByPrimaryKeySelective(model);
    }

    @Override
    public T findById(Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public T findBy(String fieldName, Object value) throws TooManyResultsException {
        try {
            T model = modelClass.newInstance();
            Field field = modelClass.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(model, value);
            return mapper.selectOne(model);
        } catch (ReflectiveOperationException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    @Override
    public List<T> findByIds(String ids) {
        return mapper.selectByIds(ids);
    }

    @Override
    public List<T> findByCondition(Condition condition) {
        return mapper.selectByCondition(condition);
    }

    @Override
    public List<T> findAll() {
        System.out.println(mapper);
        return mapper.selectAll();
    }
}

10. 具体service接口(继承基础service)及实现service(继承抽象service以及实现具体service接口),注意别少了@Service注解

package com.sosmmh.tkmybatis.service;

import com.sosmmh.tkmybatis.model.User;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 10:19
 * @Description:
 */
public interface UserService extends BaseService<User> {
}
package com.sosmmh.tkmybatis.service.impl;

import com.sosmmh.tkmybatis.model.User;
import com.sosmmh.tkmybatis.service.UserService;
import org.springframework.stereotype.Service;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 10:20
 * @Description:
 */
@Service
public class UserServiceImpl extends AbstractService<User> implements UserService {
}

11. service单元测试

package com.sosmmh.tkmybatis.service.impl;

import com.sosmmh.tkmybatis.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @Auther: sosmmh
 * @Date: 2018/4/23 10:21
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceImplTest {

    @Autowired
    private UserService userService;

    @Test
    public void findByIdTest() {
        System.out.println(userService.findAll());
    }
}










猜你喜欢

转载自blog.csdn.net/sosmmh/article/details/80047492