• SpringBoot框架之通用mapper插件(tk.mybatis)


    一.Tkmybatis的好处

    Tkmybatis是在mybatis框架的基础上提供了很多工具,让开发更加高效。这个插件里面封装好了我们需要用到的很多sql语句,不过这个插件是通过我们去调用它封装的各种方法来实现sql语句的效果。对于单表查询不需要写SQL语句,这样就不用像mybatis那样每次写一个接口就要写一条sql语句。这样大大减少了我们的工作量。

    拓展:IDEA中使用mybatis-generator自动生成mapper和pojo文件

    使用maven命令即可使用:mvn mybatis-generator:generate

    二.搭建与使用

    1、首先我们添加tk.mybatis的依赖包

    1.  
      <!--通用Mapper-->
    2.  
      <dependency>
    3.  
      <groupId>tk.mybatis</groupId>
    4.  
      <artifactId>mapper</artifactId>
    5.  
      <version>3.3.9</version>
    6.  
      </dependency>

    2、然后去添加一个UserInfo实体类

    1.  
      //注解声明数据库某表明
    2.  
      @Table(name = "USER")//如果实体类名字与数据库不一致又不使用注解会报错
    3.  
      public class UserInfo {
    4.  
      @Id
    5.  
      @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SELECT LAST_INSERT_ID()")
    6.  
      @Column(name = "id")// 注解声明该表的字段名
    7.  
      private Integer id;
    8.  
      @Column(name = "code")//如果实体类变量与数据库列名不一致又不使用注解会报错
    9.  
      private String code;
    10.  
       
    11.  
      //添加get,set方法
    12.  
      }

    拓展:SpringBoot的@GeneratedValue的参数设置

    默认是可以不加参数的,但是如果数据库控制主键自增(auto_increment), 不加参数就会报错。

    @GeneratedValue(strategy=GenerationType.IDENINY)

    PS:@GeneratedValue注解的strategy属性提供四种值:

    -AUTO主键由程序控制, 是默认选项 ,不设置就是这个

    -IDENTITY 主键由数据库生成, 采用数据库自增长, Oracle不支持这种方式

    -SEQUENCE 通过数据库的序列产生主键, MYSQL  不支持

    3、有两种方式可以扫描文件

    (1)新建配置扫描类文件

    MyBatisConfig.class:

    1.  
      package com.lkt.Professional.mapper.mybatis;
    2.  
      import org.apache.ibatis.session.SqlSessionFactory;
    3.  
      import org.mybatis.spring.SqlSessionFactoryBean;
    4.  
      import org.springframework.context.annotation.Bean;
    5.  
      public class MyBatisConfig {
    6.  
      @Bean(name = "sqlSessionFactory")
    7.  
      public SqlSessionFactory sqlSessionFactoryBean(){
    8.  
      SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    9.  
      // bean.setDataSource(dataSource());
    10.  
      bean.setTypeAliasesPackage("com.lkt.Professional.entity");
    11.  
      try {
    12.  
      //基于注解扫描Mapper,不需配置xml路径
    13.  
      //bean.setMapperLocations(resolver.getResources("classpath:mappers/*.xml"));
    14.  
      return bean.getObject();
    15.  
      } catch (Exception e) {
    16.  
      // TODO Auto-generated catch block
    17.  
      e.printStackTrace();
    18.  
      throw new RuntimeException(e);
    19.  
      }
    20.  
      }
    21.  
      }

    MyBatisMapperScannerConfig.class:

    1.  
      package com.lkt.Professional.mapper.mybatis;
    2.  
      import java.util.Properties;
    3.  
      import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    4.  
      import org.springframework.context.annotation.Bean;
    5.  
      import org.springframework.context.annotation.Configuration;
    6.  
      import com.lkt.Professional.MyMappers.MyMapper;
    7.  
      import tk.mybatis.spring.mapper.MapperScannerConfigurer;
    8.  
      @Configuration
    9.  
      //必须在MyBatisConfig注册后再加载MapperScannerConfigurer,否则会报错
    10.  
      @AutoConfigureAfter(MyBatisConfig.class)
    11.  
      public class MyBatisMapperScannerConfig {
    12.  
      @Bean
    13.  
      public MapperScannerConfigurer mapperScannerConfigurer(){
    14.  
      MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
    15.  
      mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
    16.  
      mapperScannerConfigurer.setBasePackage("com.lkt.Professional.mapper.mybatis");
    17.  
      Properties properties = new Properties();
    18.  
      properties.setProperty("mappers", MyMapper.class.getName());//MyMapper这个类接下来会创建
    19.  
      properties.setProperty("notEmpty", "false");
    20.  
      properties.setProperty("IDENTITY", "MYSQL");
    21.  
      //特别注意mapperScannerConfigurer的引入import tk.mybatis.spring.mapper.MapperScannerConfigurer;引入错误则没下面这个方法
    22.  
      mapperScannerConfigurer.setProperties(properties);
    23.  
      return mapperScannerConfigurer;
    24.  
      }
    25.  
      }

    (2)在启动类中设置扫描

    1.  
      package com.java.aney;
    2.  
       
    3.  
      import javax.sql.DataSource;
    4.  
       
    5.  
      import org.apache.ibatis.session.SqlSessionFactory;
    6.  
      import org.mybatis.spring.SqlSessionFactoryBean;
    7.  
      import tk.mybatis.spring.annotation.MapperScan;
    8.  
      import org.slf4j.Logger;
    9.  
      import org.slf4j.LoggerFactory;
    10.  
      import org.springframework.boot.SpringApplication;
    11.  
      import org.springframework.boot.autoconfigure.SpringBootApplication;
    12.  
      import org.springframework.boot.builder.SpringApplicationBuilder;
    13.  
      import org.springframework.boot.context.properties.ConfigurationProperties;
    14.  
      import org.springframework.boot.web.servlet.ServletComponentScan;
    15.  
      import org.springframework.context.annotation.Bean;
    16.  
      import org.springframework.core.io.DefaultResourceLoader;
    17.  
      import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    18.  
       
    19.  
       
    20.  
      @SpringBootApplication
    21.  
      @ServletComponentScan //使用注解注册Servlet
    22.  
      @MapperScan("com.java.aney.mapper") //通过使用@MapperScan可以指定要扫描的Mapper类的包的路径
    23.  
      public class Application {
    24.  
      private static Logger logger = LoggerFactory.getLogger(Application.class);
    25.  
       
    26.  
      protected SpringApplicationBuilder configure(
    27.  
      SpringApplicationBuilder application) {
    28.  
      return application.sources(Application.class);
    29.  
      }
    30.  
       
    31.  
      @Bean
    32.  
      @ConfigurationProperties(prefix = "spring.datasource")
    33.  
      public DataSource dataSource() {
    34.  
      return new org.apache.tomcat.jdbc.pool.DataSource();
    35.  
      }
    36.  
       
    37.  
      @Bean
    38.  
      public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
    39.  
      SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    40.  
      sqlSessionFactoryBean.setDataSource(dataSource());
    41.  
      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    42.  
      sqlSessionFactoryBean.setMapperLocations(resolver
    43.  
      .getResources("classpath:/mybatis/*.xml"));
    44.  
      // 加载全局的配置文件
    45.  
      sqlSessionFactoryBean.setConfigLocation(
    46.  
      new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));
    47.  
      return sqlSessionFactoryBean.getObject();
    48.  
      }
    49.  
       
    50.  
      public static void main(String[] args) {
    51.  
      SpringApplication.run(Application.class);
    52.  
      logger.info("服务成功启动");
    53.  
      }
    54.  
      }

    4、新建公共父类BaseService

    BaseService:(把BaseService文件存放在mapper文件夹的同级目录或者上级目录,如果扫描到了BaseService会出现报错)

    1.  
      package com.java.aney.service;
    2.  
       
    3.  
      import java.util.List;
    4.  
       
    5.  
      import com.github.pagehelper.PageInfo;
    6.  
      import com.java.aney.model.QueryExample;
    7.  
       
    8.  
      import tk.mybatis.mapper.entity.Example;
    9.  
       
    10.  
      public interface BaseServices<T, ID> {
    11.  
       
    12.  
      /**
    13.  
      * 保存一个实体,null的属性不会保存,会使用数据库默认值
    14.  
      *
    15.  
      * @param t
    16.  
      * @return
    17.  
      */
    18.  
      Integer add(T t);
    19.  
       
    20.  
      /**
    21.  
      * 保存一个list实体,null的属性不会保存,会使用数据库默认值
    22.  
      *
    23.  
      * @param list
    24.  
      * @return
    25.  
      */
    26.  
      Integer batchAdd(List<T> list);
    27.  
       
    28.  
      /**
    29.  
      * 根据id删除
    30.  
      *
    31.  
      * @param id
    32.  
      * @return
    33.  
      */
    34.  
      Integer deleteById(ID id);
    35.  
       
    36.  
      /**
    37.  
      * 根据实体属性作为条件进行删除,查询条件使用等号
    38.  
      *
    39.  
      * @param t
    40.  
      * @return
    41.  
      */
    42.  
      Integer delete(T t);
    43.  
       
    44.  
      /**
    45.  
      * 根据主键更新属性不为null的值
    46.  
      *
    47.  
      * @param t
    48.  
      * @return
    49.  
      */
    50.  
      Integer updateByPrimaryKey(T t);
    51.  
       
    52.  
      /**
    53.  
      * 根据主键更新属性不为null的值
    54.  
      *
    55.  
      * @param list
    56.  
      * @return
    57.  
      */
    58.  
      Integer batchUpdateByPrimaryKey(List<T> list);
    59.  
       
    60.  
      /**
    61.  
      * 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
    62.  
      *
    63.  
      * @param t
    64.  
      * @return
    65.  
      */
    66.  
      T findOne(T t);
    67.  
       
    68.  
      /**
    69.  
      * 查询全部结果
    70.  
      *
    71.  
      * @return
    72.  
      */
    73.  
      List<T> findAll();
    74.  
       
    75.  
      /**
    76.  
      * 根据主键查询
    77.  
      *
    78.  
      * @param id
    79.  
      * @return
    80.  
      */
    81.  
      T findById(ID id);
    82.  
       
    83.  
      /**
    84.  
      * 根据实体中的属性值进行查询,查询条件使用等号
    85.  
      *
    86.  
      * @param t
    87.  
      * @return
    88.  
      */
    89.  
      List<T> find(T t);
    90.  
       
    91.  
      /**
    92.  
      * 根据Example条件更新实体`record`包含的不是null的属性值
    93.  
      *
    94.  
      * @return
    95.  
      */
    96.  
      Integer updateByExampleSelective(QueryExample<T> queryExample);
    97.  
       
    98.  
      /**
    99.  
      * 根据实体中的属性值进行分页查询,查询条件使用等号
    100.  
      *
    101.  
      * @param t
    102.  
      * @param pageNum
    103.  
      * @param pageSize
    104.  
      * @return
    105.  
      */
    106.  
      PageInfo<T> findPage(T t, Integer pageNum, Integer pageSize);
    107.  
       
    108.  
      List<T> findByExample(Example example);
    109.  
       
    110.  
      /**
    111.  
      * 根据query条件更新record数据
    112.  
      *
    113.  
      * @param record 要更新的数据
    114.  
      * @param query 查询条件
    115.  
      * @return
    116.  
      */
    117.  
      Integer updateByExampleSelective(T record, Example query);
    118.  
       
    119.  
      /**
    120.  
      * 根据query条件更新record数据
    121.  
      *
    122.  
      * @param record 要更新的数据
    123.  
      * @param query 查询条件
    124.  
      * @return
    125.  
      */
    126.  
      Integer updateByExampleSelective(T record, T query);
    127.  
       
    128.  
      /**
    129.  
      * 查询数量
    130.  
      *
    131.  
      * @param record
    132.  
      * @return
    133.  
      */
    134.  
      Integer findCount(T record);
    135.  
       
    136.  
      /**
    137.  
      * 查询数量
    138.  
      *
    139.  
      * @param query
    140.  
      * @return
    141.  
      */
    142.  
      Integer findCountByExample(Example query);
    143.  
      }

    5、新建公共封装SQL语句条件类

    1.  
      package com.java.aney.model;
    2.  
       
    3.  
      public class QueryExample<T> {
    4.  
       
    5.  
      // @ApiModelProperty(value = "将查询到的数据更新成实体非null属性")
    6.  
      private T record;
    7.  
      // @ApiModelProperty(value = "example查询条件")
    8.  
      private Object example;
    9.  
       
    10.  
      public T getRecord() {
    11.  
      return record;
    12.  
      }
    13.  
       
    14.  
      public void setRecord(T record) {
    15.  
      this.record = record;
    16.  
      }
    17.  
       
    18.  
      public Object getExample() {
    19.  
      return example;
    20.  
      }
    21.  
       
    22.  
      public void setExample(Object example) {
    23.  
      this.example = example;
    24.  
      }
    25.  
      }

    6、新建BaseServicesImpl实现父类BaseService

    1.  
      package com.java.aney.service;
    2.  
       
    3.  
      public abstract class BaseServicesImpl<T, ID> implements BaseServices<T, ID> {
    4.  
       
    5.  
      protected final Logger logger = LoggerFactory.getLogger(getClass());
    6.  
       
    7.  
      public abstract Mapper<T> getMapper();
    8.  
       
    9.  
      @Override
    10.  
      @Transactional(rollbackFor = Exception.class) //事务回滚
    11.  
      public Integer add(T t) {
    12.  
      return getMapper().insertSelective(t); //封装单表操作方法
    13.  
      }
    14.  
       
    15.  
      @Override
    16.  
      @Transactional(rollbackFor = Exception.class)
    17.  
      public Integer deleteById(ID id) {
    18.  
      return getMapper().deleteByPrimaryKey(id);
    19.  
      }
    20.  
      。。。
    21.  
      }

    拓展:tk.mybatis单表条件拼装SQL

    链接:mybatis Example条件查询

    tk mybatis update 各种类型

    demo见方法如下:

    1.  
      //分页查询1
    2.  
      @RequestMapping(value="bootgridpage",produces="application/json;charset=UTF-8")
    3.  
      @ResponseBody
    4.  
      public BootgridPageInfoSet fenye(int current,int rowCount,String sort,String nane,String ph ){
    5.  
      PageHelper.startPage(current,rowCount);//分页
    6.  
      Example example = new Example(CcompareccicModel.class); //定义对象CcompareccicModel
    7.  
      String by=Jsonutil.getsortby(sort);//解析字段
    8.  
      example.setOrderByClause(by); //排序那个字段
    9.  
      Example.Criteria criteria = example.createCriteria();//拼接SQL条件语句
    10.  
      if (StringUtil.isNotEmpty(nane)) {
    11.  
      criteria.andLike("xm", "%" + nane + "%");
    12.  
      }
    13.  
      // criteria.andEqualTo("xm", "崔颖");//条件相等
    14.  
      // criteria.andGreaterThan("xb", "1");//大于
    15.  
      // criteria.andLessThan("xb", "2");//小于
    16.  
      // criteria.andIsNotNull("xm");//is not null
    17.  
      // criteria.andCondition("xzdqh=","110104");//加各种条件都可以 = like <,可以代替全部的
    18.  
      // List<String> values=new ArrayList<String>();
    19.  
      // values.add("110104");
    20.  
      // criteria.andIn("xzdqh", values);//in()
    21.  
      // criteria.andBetween("csrq", "1956/01/08", "1966/10/21");//时间相隔
    22.  
      // Example.Criteria criteria2 = example.createCriteria();
    23.  
      // criteria2.andCondition("xzdqh=","220104");
    24.  
      // example.or().andCondition("xzdqh=","220104");//or
    25.  
      // example.or(criteria2);//or
    26.  
      List<CcompareccicModel> list=service.selectByExample(example);
    27.  
      new BootgridPageInfoSet<CcompareccicModel>(list);
    28.  
      return new BootgridPageInfoSet<CcompareccicModel>(list);
    29.  
      }

    7、新建子类UserService继承BaseServicesImpl<AccountUser, Integer>,并重写方法

    1.  
      @Service("userService")
    2.  
      public class UserService extends BaseServicesImpl<User, Integer> {
    3.  
       
    4.  
      @Resource
    5.  
      private UserMapper userMapper;
    6.  
       
    7.  
      @Override
    8.  
      public Mapper<AccountUser> getMapper() {
    9.  
      return userMapper;
    10.  
      }
    11.  
       
    12.  
      public AccountUser queryUserName(String userName) {
    13.  
      AccountUser user = userMapper.selectUserName(userName);
    14.  
      return user;
    15.  
      }
    16.  
      。。。
    17.  
      }
    18.  

    8、新建mapper接口继承父接口Mapper<T>

    1.  
      @Repository
    2.  
      public interface UserMapper extends Mapper<User> {
    3.  
       
    4.  
      /**
    5.  
      * 通过用户昵称查询用户信息
    6.  
      * @param userName
    7.  
      * @return
    8.  
      */
    9.  
      public User selectUserName(String userName);
    10.  
      }

    拓展:Mapper接口的声明如下,可以看到Mapper接口实现了所有常用的方法:

    1.  
      public interface Mapper<T> extends
    2.  
      BaseMapper<T>,
    3.  
      ExampleMapper<T>,
    4.  
      RowBoundsMapper<T>,
    5.  
      Marker {
    6.  
       
    7.  
      }

    9、新建mapper.xml

    1.  
      <?xml version="1.0" encoding="UTF-8"?>
    2.  
      <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3.  
      <mapper namespace="com.lkt.Professional.UserMapper">
    4.  
      <resultMap id="BaseResultMap" type="com.model.User">
    5.  
      <id column="id" jdbcType="VARCHAR" property="id"/>
    6.  
      <result column="code" jdbcType="VARCHAR" property="code"/>
    7.  
      <result column="user_name" jdbcType="INTEGER" property="UserName"/>
    8.  
      <result column="initime" jdbcType="TIMESTAMP" property="initime"/>
    9.  
      <association property="userIdMap" column="user_id" foreignColumn="id" notNullColumn="user_name" javaType="map">
    10.  
      <id column="id" property="id"/>
    11.  
      <result column="user_name" property="name"/>
    12.  
      </association>
    13.  
      </resultMap>
    14.  
       
    15.  
      <select id="getUserDetail" resultMap="BaseResultMap" parameterType="String">
    16.  
       
    17.  
      </select>
    18.  
      </mapper>

    注意:右击application跑起来,如果报出有关mysql或者sql语句的错误

    (1)检查application.properties文件数据库配置是否正确;

    (2)检查bean(实体类)的类名是否与数据库表名一致,不一致是否添加@Table(name = "表名")注解声明;

    (3)检查bean的变量名是否与该表名的列名一致,不一致是否添加@Column(name = "列名")注解声明。

  • 相关阅读:
    openpose_caffe_to_rknn.py
    ncnn的完整编译过程
    We Need More Bosses CodeForces
    Yet Another Problem On a Subsequence CodeForces
    牛客 82E 无向图中的最短距离 (bitset,bfs)
    Largest Submatrix 3 CodeForces
    bzoj 4245 [ONTAK2015]OR-XOR (贪心)
    BZOJ 2836 魔法树 链剖裸题~~
    BZOJ 3083 遥远的国度 树链剖分+脑子
    Luogu P1471 方差 线段树
  • 原文地址:https://www.cnblogs.com/exmyth/p/11305818.html
Copyright © 2020-2023  润新知