1. 程式人生 > >SpringBoot框架之通用mapper外掛(tk.mybatis)

SpringBoot框架之通用mapper外掛(tk.mybatis)

一.Tkmybatis的好處

Tkmybatis是在mybatis框架的基礎上提供了很多工具,讓開發更加高效。這個外掛裡面封裝好了我們需要用到的很多sql語句,不過這個外掛是通過我們去呼叫它封裝的各種方法來實現sql語句的效果對於單表查詢不需要寫SQL語句,這樣就不用像mybatis那樣每次寫一個介面就要寫一條sql語句。這樣大大減少了我們的工作量。

自動生成mapper和entity檔案:mybatis-generator外掛和TKmybatis的結合使用

二.搭建與使用

1、首先我們新增tk.mybatis的依賴包

<!--通用Mapper-->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>3.3.9</version>
</dependency>

2、然後去新增一個UserInfo實體類

​//註解宣告資料庫某表明
@Table(name = "USER")//如果實體類名字與資料庫不一致又不使用註解會報錯
public class UserInfo {
	@Id
      @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SELECT LAST_INSERT_ID()")
	@Column(name = "id")// 註解宣告該表的欄位名
	private Integer id;
	@Column(name = "code")//如果實體類變數與資料庫列名不一致又不使用註解會報錯
	private String code;

	//新增get,set方法
}

拓展:SpringBoot的@GeneratedValue的引數設定

預設是可以不加引數的,但是如果資料庫控制主鍵自增(auto_increment), 不加引數就會報錯。

@GeneratedValue(strategy=GenerationType.IDENINY)

PS:@GeneratedValue註解的strategy屬性提供四種值:

-AUTO主鍵由程式控制, 是預設選項 ,不設定就是這個

-IDENTITY 主鍵由資料庫生成, 採用資料庫自增長, Oracle不支援這種方式

-SEQUENCE 通過資料庫的序列產生主鍵, MYSQL  不支援

3、有兩種方式可以掃描檔案

(1)新建配置掃描類檔案

MyBatisConfig.class:

package com.lkt.Professional.mapper.mybatis;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
public class MyBatisConfig {
	@Bean(name = "sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactoryBean(){
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
	//  bean.setDataSource(dataSource());
		bean.setTypeAliasesPackage("com.lkt.Professional.entity");
		try {
		//基於註解掃描Mapper,不需配置xml路徑
	        //bean.setMapperLocations(resolver.getResources("classpath:mappers/*.xml"));
			return bean.getObject();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}

MyBatisMapperScannerConfig.class:

package com.lkt.Professional.mapper.mybatis;
import java.util.Properties;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.lkt.Professional.MyMappers.MyMapper;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
@Configuration
//必須在MyBatisConfig註冊後再載入MapperScannerConfigurer,否則會報錯
@AutoConfigureAfter(MyBatisConfig.class)
public class MyBatisMapperScannerConfig {
	@Bean
	public MapperScannerConfigurer mapperScannerConfigurer(){
		MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
		mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
		mapperScannerConfigurer.setBasePackage("com.lkt.Professional.mapper.mybatis");	
		Properties properties = new Properties();
	    properties.setProperty("mappers", MyMapper.class.getName());//MyMapper這個類接下來會建立
	    properties.setProperty("notEmpty", "false");
	    properties.setProperty("IDENTITY", "MYSQL");
	    //特別注意mapperScannerConfigurer的引入import tk.mybatis.spring.mapper.MapperScannerConfigurer;引入錯誤則沒下面這個方法	
	    mapperScannerConfigurer.setProperties(properties);
	    return mapperScannerConfigurer;
	}
}

(2)在啟動類中設定掃描

package com.java.aney;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import tk.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;


@SpringBootApplication
@ServletComponentScan //使用註解註冊Servlet
@MapperScan("com.java.aney.mapper") //通過使用@MapperScan可以指定要掃描的Mapper類的包的路徑
public class Application {
	private static Logger logger = LoggerFactory.getLogger(Application.class);

	protected SpringApplicationBuilder configure(
			SpringApplicationBuilder application) {
		return application.sources(Application.class);
	}

	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DataSource dataSource() {
		return new org.apache.tomcat.jdbc.pool.DataSource();
	}

	@Bean
	public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource());
		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		sqlSessionFactoryBean.setMapperLocations(resolver
				.getResources("classpath:/mybatis/*.xml"));
		// 載入全域性的配置檔案
		sqlSessionFactoryBean.setConfigLocation(
                new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
		return sqlSessionFactoryBean.getObject();
	}

	public static void main(String[] args) {
		SpringApplication.run(Application.class);
		logger.info("服務成功啟動");
	}
}

4、新建公共父類BaseService

BaseService:(把BaseService檔案存放在mapper資料夾的同級目錄或者上級目錄,如果掃描到了BaseService會出現報錯)

package com.java.aney.service;

import java.util.List;

import com.github.pagehelper.PageInfo;
import com.java.aney.model.QueryExample;

import tk.mybatis.mapper.entity.Example;

public interface BaseServices<T, ID> {

    /**
     * 儲存一個實體,null的屬性不會儲存,會使用資料庫預設值
     *
     * @param t
     * @return
     */
    Integer add(T t);

    /**
     * 儲存一個list實體,null的屬性不會儲存,會使用資料庫預設值
     *
     * @param list
     * @return
     */
    Integer batchAdd(List<T> list);

    /**
     * 根據id刪除
     *
     * @param id
     * @return
     */
    Integer deleteById(ID id);

    /**
     * 根據實體屬性作為條件進行刪除,查詢條件使用等號
     *
     * @param t
     * @return
     */
    Integer delete(T t);

    /**
     * 根據主鍵更新屬性不為null的值
     *
     * @param t
     * @return
     */
    Integer updateByPrimaryKey(T t);

    /**
     * 根據主鍵更新屬性不為null的值
     *
     * @param list
     * @return
     */
    Integer batchUpdateByPrimaryKey(List<T> list);

    /**
     * 根據實體中的屬性進行查詢,只能有一個返回值,有多個結果是丟擲異常,查詢條件使用等號
     *
     * @param t
     * @return
     */
    T findOne(T t);

    /**
     * 查詢全部結果
     *
     * @return
     */
    List<T> findAll();

    /**
     * 根據主鍵查詢
     *
     * @param id
     * @return
     */
    T findById(ID id);

    /**
     * 根據實體中的屬性值進行查詢,查詢條件使用等號
     *
     * @param t
     * @return
     */
    List<T> find(T t);

    /**
     * 根據Example條件更新實體`record`包含的不是null的屬性值
     *
     * @return
     */
    Integer updateByExampleSelective(QueryExample<T> queryExample);

    /**
     * 根據實體中的屬性值進行分頁查詢,查詢條件使用等號
     *
     * @param t
     * @param pageNum
     * @param pageSize
     * @return
     */
    PageInfo<T> findPage(T t, Integer pageNum, Integer pageSize);

    List<T> findByExample(Example example);

    /**
     * 根據query條件更新record資料
     *
     * @param record 要更新的資料
     * @param query  查詢條件
     * @return
     */
    Integer updateByExampleSelective(T record, Example query);

    /**
     * 根據query條件更新record資料
     *
     * @param record 要更新的資料
     * @param query  查詢條件
     * @return
     */
    Integer updateByExampleSelective(T record, T query);

    /**
     * 查詢數量
     *
     * @param record
     * @return
     */
    Integer findCount(T record);

    /**
     * 查詢數量
     *
     * @param query
     * @return
     */
    Integer findCountByExample(Example query);
}

5、新建公共封裝SQL語句條件類

package com.java.aney.model;

public class QueryExample<T> {

    //    @ApiModelProperty(value = "將查詢到的資料更新成實體非null屬性")
    private T record;
    //    @ApiModelProperty(value = "example查詢條件")
    private Object example;

    public T getRecord() {
        return record;
    }

    public void setRecord(T record) {
        this.record = record;
    }

    public Object getExample() {
        return example;
    }

    public void setExample(Object example) {
        this.example = example;
    }
}

6、新建BaseServicesImpl實現父類BaseService

​package com.java.aney.service;

public abstract class BaseServicesImpl<T, ID> implements BaseServices<T, ID> {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    public abstract Mapper<T> getMapper();

    @Override
    @Transactional(rollbackFor = Exception.class) //事務回滾
    public Integer add(T t) {
        return getMapper().insertSelective(t); //封裝單表操作方法
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteById(ID id) {
        return getMapper().deleteByPrimaryKey(id);
    }
    。。。
}

拓展:tk.mybatis單表條件拼裝SQL

連結:mybatis Example條件查詢

tk mybatis update 各種型別

demo見方法如下:

//分頁查詢1
        @RequestMapping(value="bootgridpage",produces="application/json;charset=UTF-8")
        @ResponseBody
        public BootgridPageInfoSet fenye(int current,int rowCount,String sort,String nane,String ph ){          
            PageHelper.startPage(current,rowCount);//分頁
            Example example = new Example(CcompareccicModel.class); //定義物件CcompareccicModel
            String by=Jsonutil.getsortby(sort);//解析欄位
            example.setOrderByClause(by);   //排序那個欄位
            Example.Criteria criteria = example.createCriteria();//拼接SQL條件語句
                 if (StringUtil.isNotEmpty(nane)) {
                     criteria.andLike("xm", "%" + nane + "%");
                 }
        // criteria.andEqualTo("xm", "崔穎");//條件相等
        // criteria.andGreaterThan("xb", "1");//大於
        // criteria.andLessThan("xb", "2");//小於
        // criteria.andIsNotNull("xm");//is not null
        // criteria.andCondition("xzdqh=","110104");//加各種條件都可以 = like <,可以代替全部的
        // List<String> values=new ArrayList<String>();
        // values.add("110104");
        // criteria.andIn("xzdqh", values);//in()
        // criteria.andBetween("csrq", "1956/01/08", "1966/10/21");//時間相隔
        // Example.Criteria criteria2 = example.createCriteria();
        // criteria2.andCondition("xzdqh=","220104");
        // example.or().andCondition("xzdqh=","220104");//or
        // example.or(criteria2);//or
            List<CcompareccicModel> list=service.selectByExample(example);  
            new BootgridPageInfoSet<CcompareccicModel>(list);
            return new BootgridPageInfoSet<CcompareccicModel>(list);
        }

7、新建子類UserService繼承BaseServicesImpl<AccountUser, Integer>,並重寫方法

​@Service("userService")
public class UserService extends BaseServicesImpl<User, Integer> {

    @Resource
	private UserMapper userMapper;
    
    @Override
	public Mapper<AccountUser> getMapper() {
		return userMapper;
	}

    public AccountUser queryUserName(String userName) {
		AccountUser user = userMapper.selectUserName(userName);
		return user;
	}
    。。。
}
​

8、新建mapper介面繼承父介面Mapper<T>

@Repository
public interface UserMapper extends Mapper<User> {

    /**
	 * 通過使用者暱稱查詢使用者資訊
	 * @param userName
	 * @return
	 */
	public User selectUserName(String userName);
}

拓展:Mapper介面的宣告如下,可以看到Mapper介面實現了所有常用的方法:

public interface Mapper<T> extends
        BaseMapper<T>,
        ExampleMapper<T>,
        RowBoundsMapper<T>,
        Marker {

}

9、新建mapper.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.lkt.Professional.UserMapper">
    <resultMap id="BaseResultMap" type="com.model.User">
        <id column="id" jdbcType="VARCHAR" property="id"/>
        <result column="code" jdbcType="VARCHAR" property="code"/>
        <result column="user_name" jdbcType="INTEGER" property="UserName"/>
        <result column="initime" jdbcType="TIMESTAMP" property="initime"/>
        <association property="userIdMap" column="user_id" foreignColumn="id" notNullColumn="user_name" javaType="map">
            <id column="id" property="id"/>
            <result column="user_name" property="name"/>
        </association>
    </resultMap>

    <select id="getUserDetail" resultMap="BaseResultMap" parameterType="String">
        
    </select>
</mapper>

注意:右擊application跑起來,如果報出有關mysql或者sql語句的錯誤

(1)檢查application.properties檔案資料庫配置是否正確;

(2)檢查bean(實體類)的類名是否與資料庫表名一致,不一致是否新增@Table(name = "表名")註解宣告;

(3)檢查bean的變數名是否與該表名的列名一致,不一致是否新增@Column(name = "列名")註解宣告。