一、springboot整合tkMybatis

1、springboot整合tkMybatis

(1)、添加依赖:mapper-spring-boot-starter

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>
    <properties>
        <mysql.version>8.0.11</mysql.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 通用Mapper启动器 -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.4</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

注意:tk.mybatis的版本为<version>2.0.4</version>,条件查询用的时ExamplerMapper。

mapper接口

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

(2)、配置连接数据库的四个参数

server.port=8081
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/zwhxpp?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

mybatis.type-aliases-package=com.zwh.entity

因为用了Common Mapper,所以要指定别名包的扫描

(3)、编写启动类,在启动类中通过@MapperScan配置包扫描,扫描mapper包中的UserMapper接口

@SpringBootApplication
@MapperScan("com.zwh.dao")
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

注意:@MapperScan是tk.mybatis包下的。import tk.mybatis.spring.annotation.MapperScan;

(4)、编写实体类

@Data
@Table(name = "tab_user")
public class User{
    @Id
    @KeySql(useGeneratedKeys = true)//开启主键自动回填
    private Integer uid;
    private String username;// 用户名
    private String password;// 密码
    private String name;// 姓名
    private String sex;// 性别,1男性,2女性
    private Date birthday; // 出生日期
}

由于是直接与数据库交互,所以要用到Common Mapper中的注解:@Table、@Id、@KeySQL

import tk.mybatis.mapper.annotation.KeySql;

@KeySql(useGeneratedKeys = true)//开启主键自动回填

当主键是自增的情况下,添加一条记录的同时,其主键是不能使用的,但是有时我们需要该主键,我们设置useGeneratedKeys="true",这样在之后的java代码中我们就可以获取该主键对应的对象的属性值。useGeneratedKeys 取值范围true|false 默认值是:false。 含义:设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。

在springboot项目中相应的配置为:

#允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false
mybatis.configuration.use-generated-keys=true

(5)、编写UserMapper接口,去操作数据库

import com.zwh.entity.User;
import tk.mybatis.mapper.common.Mapper;

public interface UserMapper extends Mapper<User> {
}

(6)、编写UserService类,调用Mapper接口的方法进行数据库操作

@Service
public class UserService {
    @Resource
    private UserMapper userMapper;
    public User queryById(Integer id){
        User user = userMapper.selectByPrimaryKey(id);
        System.out.println(user);
        return user;
    }
}

(7)、编写UserController

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public User queryById(@PathVariable Integer id){
        User user = userService.queryById(id);
        return user;
    }
}

(8)、启动项目,浏览器访问:http://localhost:8081/user/1,结果如下:

{"uid":1,"username":"zhangsan","password":"123456","name":"张三","sex":"","birthday":"2020-11-10T16:00:00.000+0000"}

2、自定义通用基类

(1)、自定义通用基类

import tk.mybatis.mapper.common.ConditionMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T>, ConditionMapper<T>{
}

注意:自定义通用基类MyMapper不能被扫描到,否则会报错。

(2)、配置文件中指定通用基类MyMapper

mapper.mappers=com.zwh.config.mapper.MyMapper

(3)、dao接口使用自定义通用基类

import com.zwh.config.mapper.MyMapper;
import com.zwh.entity.User;

public interface UserMapper extends MyMapper<User> {
}

 

二、插入数据后返回ID的方法(通用mapper主键策略)

通用Mapper还提供了序列(支持Oracle)、UUID(任意数据库,字段长度32)、主键自增(类似Mysql,Hsqldb)三种方式,其中序列和UUID可以配置多个,主键自增只能配置一个

首先主键策略和数据库关系很大,有些数据库(如mysql、sqlserver)支持主键自增,而有些数据库(如oracle)只能通过序列来获得。

新增的@KeySql 注解用于替换 @GeneratedValue 注解

@KeySql 介绍

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface KeySql {
  // 是否使用JDBC方式获取主键,优先级最高,设置为true后不对其他配置校验 boolean useGeneratedKeys() default false;   // 优先级第二,根据配置的数据库类型取回主键,忽略其他配置 IdentityDialect dialect() default IdentityDialect.NULL;   // 取主键的sql,序列或uuid,优先级第三 String sql() default ""; Class<? extends GenSql> genSql() default NULL.class;   // 和sql配合使用,默认使用全局配置中的ORDER ORDER order() default ORDER.DEFAULT;   // java方式生成主键,优先级最低 Class<? extends GenId> genId() default tk.mybatis.mapper.genid.GenId.NULL.class; }

通过上面的注释,大家可以看到主要的 3 个参数的优先级,useGeneratedKeys 优先级最高,其次是 dialect,最后是 sql。其中 order 只对 sql 方式有效。

useGeneratedKeys 和 dialect 相当于预设的基本用法,和数据库以及驱动紧密相关。sql 和 order 更灵活。

1、使用 JDBC 方式获取主键(优先级最高)

即配置@KeySql(useGeneratedKeys = true)或@GeneratedValue(generator = "JDBC")

JDBC 支持通过 getGeneratedKeys 方法取回主键的情况。

常见的如 MySql,SqlServer 支持这种模式。

boolean useGeneratedKeys() default false;

是否使用 JDBC 方式获取主键,优先级最高,设置为 true 后,不对其他配置校验

这种情况下,配置主键策略最简单。

@Id
@KeySql(useGeneratedKeys = true)
private Long id;

@Id
@GeneratedValue(generator = "JDBC")
private Long id;

为了让大家容易理解这里配置和 MyBatis 写法的关系,大家可以看看对应生成的 XML 代码:

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
    insert into country (id, countryname, countrycode)
    values (#{id},#{countryname},#{countrycode})
</insert>

2、数据库支持自增(优先级第二)

支持自增数据库列表如下(共9种):

注意:没有oracle

@KeySql(dialect = IdentityDialect.MYSQL)或@GeneratedValue(strategy = GenerationType.IDENTITY)

@Id
//DEFAULT 需要配合 IDENTITY 参数(ORDER默认AFTER)
@KeySql(dialect = IdentityDialect.DEFAULT)
private Integer id;
//建议直接指定数据库
@Id
@KeySql(dialect = IdentityDialect.MYSQL)
private Integer id;

或:

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

 使用GenerationType.IDENTITY需要在全局配置中配置IDENTITY的参数值,并且需要根据数库配置ORDER属性。

mapper.identity=mysql
mapper.order=AFTER
//或者
#mapper.before=false

 IDENTITY 参数以及 ORDER 参数会决定 selectKey 中的 SQL 和 order 属性的值(这里是 AFTER)。order="AFTER"  mysql 自增长ID    先保存的数据 再生成的ID   

对应的xml形式

<insert id="saveUser" parameterType="USER">
  <!-- 配置保存时获取插入的 id --> 
  <selectKey keyColumn="id" keyProperty="id" resultType="int">     select last_insert_id();   </selectKey>   insert into user(username,birthday,sex,address)   values(#{username},#{birthday},#{sex},#{address}) </insert>

 新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相当于我们要在新增后将自动增长 auto_increment 的值返回。

3、通过 SQL 获取主键值(优先级第三)

(1)、oracle通过序列获取主键

像 Oracle 中通过序列获取主键就属于这种情况,除了类似序列获取值外,还可以是获取 UUID 的 SQL 语句,例如 select uuid()。

mapper.identity=select uuid()
mapper.before=true

自增主键和非自增主键 的区别主要在于,自增主键 是插入表之后才有 id 的值(mapper.before=false),非自增主键是插入数据库前需要获取一个值作为主键(mapper.before=true)。

order()和取主键的 SQL配合使用

String sql() default "";
ORDER order() default ORDER.DEFAULT;

在 Oracle 中,我们可以用下面的方式进行配置:

@KeySql(sql = "select OUTPUT_SEQ.nextval from dual", order = ORDER.BEFORE)

或:

@Id
@GeneratedValue(
  strategy = GenerationType.IDENTITY,
  generator = "select SEQ_ID.nextval from dual")
private Integer id;

使用 @GeneratedValue 时也要配置一个 ORDER 全局参数

xml的方式

<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select SEQ_ID.nextval from dual
  </selectKey>
  insert into country (id, countryname, countrycode)
  values (#{id},#{countryname},#{countrycode})
</insert>

order="BEFORE"  oracle  自增长  UUID  先生成ID 再保存数据

(2)、获取mysql UUID 的 SQL 语句

order="BEFORE"  mysql UUID  先生成ID 再保存数据

除了 Oracle 这种外,还有一种更普遍的用法,就是使用 UUID。

例如下面的配置:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select uuid()")
private String id;

注意: SQL 返回值类型和这里接收的类型(String)一致。

也可以自定义取回主键的方式:

CREATE DEFINER=`ip`@`%` FUNCTION `sys_guid`() RETURNS varchar(255) CHARSET utf8
BEGIN
    DECLARE uuid VARCHAR(32) DEFAULT '';
  SET uuid = replace(uuid(),'-','');
    RETURN uuid;
END

对于主键类型为varchar的,可以通过预定义的默认生成策略来生成主键(推荐)

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

目前的生成策略为通过获得数据库生成的UUID来作为主键

mapper.identity=select sys_guid() from dual

同样对于varchar类型的主键,也可以直接使用系统生成的UUID,这个方式与GenerationType.IDENTITY的区别就是通过GenerationType.IDENTITY生成的主键能够在保存操作后,返回到实体中;而这种方式则不会

@GeneratedValue("UUID")
private String id;

4、genId方式生成主键(优先级最低)

为了方便使用全局主键(例如:Vesta 是一款通用的ID产生器,互联网俗称统一发号器),通用 Mapper 4.0.2 版本增加了新的控制主键生成的策略。

@KeySql 注解增加了下面的方法:

/**
 * Java 方式生成主键,可以和发号器一类的服务配合使用
 *
 * @return
 */
Class<? extends GenId> genId() default GenId.NULL.class;

使用该功能的时候,需要配置 genId 属性。 由于生成主键的方式通常和使用环境有关,因此通用 Mapper 没有提供默认的实现。

GenId 接口如下:

public interface GenId<T> {
    class NULL implements GenId {
        @Override
        public Object genId(String table, String column) {
            throw new UnsupportedOperationException();
        }
    }
 
    T genId(String table, String column);
}

 通过接口方法可以看出,在生成 Id 时,可以得到当前的表名和列名,我们可以使用这两个信息生成和表字段相关的 Id 信息。也可以完全不使用这两个信息,生成全局的 Id。

(1)、使用 UUID 方式

首先我们需要提供一个能产生 UUID 的实现类:

public class UUIdGenId implements GenId<String> {
    @Override
    public String genId(String table, String column) {
        return UUID.randomUUID().toString();
    }
}

使用:

public class User {
    @Id
    @KeySql(genId = UUIdGenId.class)
    private String id;
 
}

注意:我们只需要在注解中配置 @KeySql(genId = UUIdGenId.class) 即可,需要注意的是,如果你使用了 @KeySql 提供的其他方式,genId 就不会生效,genId 是所有方式中优先级最低的。

(2)、简单的全局时序ID

public class SimpleGenId implements GenId<Long> {
    private Long    time;
    private Integer seq;
 
    @Override
    public synchronized Long genId(String table, String column) {
        long current = System.currentTimeMillis();
        if (time == null || time != current) {
            time = current;
            seq = 1;
        } else if (current == time) {
            seq++;
        }
        return (time << 20) | seq;
    }
}

(3)、基于 Vesta 的实现 

public class VestaGenId implement GenId<Long> {
   public Long genId(String table, String column){
       //ApplicationUtil.getBean 需要自己实现
        //IdService 是Vesta中的接口
       IdService idService = ApplicationUtil.getBean(IdService.class);
       return idService.genId();
   }
}
 
@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationContextRegister.class);
    private static ApplicationContext APPLICATION_CONTEXT;
 
    /**
     * 设置spring上下文  *  * @param applicationContext spring上下文  * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        LOGGER.debug("ApplicationContext registed-->{}", applicationContext);
        APPLICATION_CONTEXT = applicationContext;
    }
 
    public static ApplicationContext getApplicationContext() {
        return APPLICATION_CONTEXT;
    }
}

(4)、InsertListMapper 特殊支持

通用 Mapper 提供了好几个 InsertListMapper 接口,最早提供的都是和数据库相关的方法,所以在 Id 策略上都有和数据库相关的限制。

最新增加的 tk.mybatis.mapper.additional.insert.InsertListMapper 接口是一个和数据库无关的方法,他不支持任何的主键策略。但是有了 genId 方式后,这个接口增加了对 @KeySql 注解 genId 方法的支持。

import tk.mybatis.mapper.additional.insert.InsertListMapper;
 
public interface UserMapper extends InsertListMapper<User> {
 
}
 
 
@Test
public void testInsertList() {
    SqlSession sqlSession = getSqlSession();
    try {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = new ArrayList<User>(countries.length);
        for (int i = 0; i < countries.length; i++) {
            userList.add(new User(countries[i][0], countries[i][1]));
        }
        Assert.assertEquals(countries.length, mapper.insertList(userList));
        for (User user : userList) {
            Assert.assertNotNull(user.getId());
            System.out.println(user.getId());
        }
    } finally {
        sqlSession.close();
    }
}

通过 genId 方式可以批量插入,并且可以回写 ID。

三、通用Mapper的方法

1、BaseMapper

@RegisterMapper
public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker {
}
@RegisterMapper
public interface BaseMapper<T> extends BaseSelectMapper<T>, BaseInsertMapper<T>, BaseUpdateMapper<T>, BaseDeleteMapper<T> {
}
@RegisterMapper
public interface BaseSelectMapper<T> extends SelectOneMapper<T>, SelectMapper<T>, SelectAllMapper<T>, 、SelectCountMapper<T>,
SelectByPrimaryKeyMapper<T>,ExistsWithPrimaryKeyMapper<T> {
}

在BaseMapper的增删改查方法中,insert和update时一般使用带selective的方法。select和delete可以根据主键进行查询或删除,也可以根据一个对象进行查询或删除。

(1)、BaseSelectMapper的方法:

Mapper继承BaseMapper(基础Mapper),BaseMapper继承BaseSelectMapper(基础selectMapper)

1)、接口:`SelectByPrimaryKeyMapper<T>`

方法:`T selectByPrimaryKey(Object key);`

说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号(参数为主键,只能查出一条记录)

User _user = (User) _rs.getData();
            Enterprise enterprise = enterpriseMapper.selectByPrimaryKey(u.getEnterpriseId());

2)、接口:`SelectMapper<T>`

方法:`List<T> select(T record);`

说明:根据实体中的属性值进行查询,查询条件使用等号(参数为对象,可以查出多条记录)

User user1 = new User();
                user1.setEnterpriseId(user.getEnterpriseId());
                user1.setDelFlag(0);
                List<User> list1 = userMapper.select(user1);

3)、接口:`SelectAllMapper<T>`

方法:`List<T> selectAll();`

说明:查询全部结果select(null)方法能达到同样的效果(五参数,查询所有记录)

public List<User> getUsers() {
        return userMapper.selectAll();
    }

4)、接口:`SelectOneMapper<T>`

方法:`T selectOne(T record);`

说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号(参数为对象,只能查出一条记录)

Output output = new Output();
                output.setEnterpriseId(p.getEnterpriseId());
                output.setMesNodeNo(materialType);
                Output selectOne = traceabilityOutputMapper.selectOne(output);

5)、接口:`SelectCountMapper<T>`

方法:`int selectCount(T record);`

说明:根据实体中的属性查询总数,查询条件使用等号(参数为对象)

ProductFeedBK checkExisted = new ProductFeedBK();
                checkExisted.setTransactionId(productFeedERPDetailInfo.getTransactionId());
                if (org.apache.commons.lang3.StringUtils.isNotBlank(productFeedERPDetailInfo.getInLotNum())) {
                    checkExisted.setInLotNum(productFeedERPDetailInfo.getInLotNum());
                }

                if (org.apache.commons.lang3.StringUtils.isNotBlank(productFeedERPDetailInfo.getOutLotNum())) {
                    checkExisted.setOutLotNum(productFeedERPDetailInfo.getOutLotNum());
                }
                int count = productFeedBKMapper.selectCount(checkExisted);

(2)、BaseInsertMapper的方法:

Mapper继承BaseMapper(基础Mapper),BaseMapper继承BaseInsertMapper(基础InsertMapper)

1)、接口:`InsertMapper<T>`

方法:`int insert(T record);`

说明:保存一个实体,null的属性也会保存,不会使用数据库默认值

2)、接口:`InsertSelectiveMapper<T>`

方法:`int insertSelective(T record);`(参数为对象)

UserRole userRole = new UserRole();
            userRole.setDelFlag(0);
            userRole.setCreateBy(user.getUserName());
            userRole.setCreateTime(new Date());
            userRole.setRoleId(Integer.parseInt(list.get(i).toString()));
            userRole.setUserId(user.getUserId());
            userRoleMapper.insertSelective(userRole);

说明:保存一个实体,null的属性不会保存,会使用数据库默认值。

(3)、BaseUpdateMapper的方法:

1)、接口:`UpdateByPrimaryKeyMapper<T>`

方法:`int updateByPrimaryKey(T record);`

说明:根据主键更新实体全部字段,null值会被更新

2)、接口:`UpdateByPrimaryKeySelectiveMapper<T>`

方法:`int updateByPrimaryKeySelective(T record);`

说明:根据主键更新属性不为null的值(参数为对象,除了有主键作为一个条件外,还需要其他属性作为条件)

public boolean changePassword(Integer userId) {
        User user = new User();
        user.setUserId(userId);
        user.setPwdUpdateFlag("1");
        int i = userMapper.updateByPrimaryKeySelective(user);
        if (i != 0) {
            return true;
        }
        return false;
    }

(4)、BaseDeleteMapper的方法

1)、接口:`DeleteMapper<T>`

方法:`int delete(T record);`

说明:根据实体属性作为条件进行删除,查询条件使用等号

ExtractProduct tmp = new ExtractProduct();
            tmp.setProductId(traceabilityProduct.getId());
            extractProductMap.delete(tmp);

2)、接口:`DeleteByPrimaryKeyMapper<T>`

方法:`int deleteByPrimaryKey(Object key);`

说明:根据主键字段进行删除,方法参数必须包含完整的主键属性(参数为对象,主键作为唯一条件)

AtomicInteger a = new AtomicInteger();
        String[] idArr = ids.split(",");
        for (int i = 0; i < idArr.length; i++) {
            ErpProductInfo productInfo = new ErpProductInfo();
            productInfo.setProductId(Integer.parseInt(idArr[i]));
            a.set(productMapper.deleteByPrimaryKey(productInfo));
        }

2、ExampleMapper

@RegisterMapper
public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker {
}
@RegisterMapper
public interface ExampleMapper<T> extends SelectByExampleMapper<T>, SelectOneByExampleMapper<T>, SelectCountByExampleMapper<T>,
DeleteByExampleMapper<T>,UpdateByExampleMapper<T>, UpdateByExampleSelectiveMapper<T> {
}

示例:

Example placeExample = new Example(Place.class);
                Example.Criteria placeCriteria = placeExample.createCriteria();
                placeCriteria.andEqualTo("delFlag", "0");
                List<Place> places = placeMapper.selectByExample(placeExample);

常用selectByExample、updateByExampleSelective、deleteByExample这三个方法,没有insertByExample。

ExampleMapper的方法:

1)、接口:`SelectByExampleMapper<T>`

方法:`List<T> selectByExample(Object example);`

说明:根据Example条件进行查询

重点:这个查询支持通过`Example`类指定查询列,通过`selectProperties`方法指定查询列

Example example = new Example(IntelDrugStore.class);
                                    example.createCriteria().andEqualTo("equipmentCode", equipmentCode1)
                                            .andEqualTo("equipmentType",equipmentType)
                                            .andEqualTo("hospitalName",hospitalName);
                                    intelDrugStores = intelDrugStoreMapper.selectByExample(example);

2)、接口:`SelectOneByExampleMapper<T>`

方法:`T selectOneByExample(Object example);`

说明:根据Example条件进行查询一条记录

Example example = new Example(User.class);
        example.createCriteria()
                .andEqualTo("userName", user.getUserName())
                .andEqualTo("delFlag", 0);
        User curUser = userMapper.selectOneByExample(example);
        if (null == curUser) {
            rs.setSuccess(false);
            rs.setMsg("用户名不存在!");
            rs.setCode(ResultCode.SUCCESS);
            return rs;
        }

3)、接口:`SelectCountByExampleMapper<T>`

方法:`int selectCountByExample(Object example);`

说明:根据Example条件进行查询总数

public int queryCount(String enterpiseType, String enterpriseName, String enterpiseCode, String organizationCode) {

        Example example = new Example(Enterprise.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("delFlag", 0);
        if (!StringUtils.isEmpty(enterpiseType)) {
            criteria.andEqualTo("enterpiseType", enterpiseType);
        }
        if (!StringUtils.isEmpty(enterpriseName)) {
            criteria.andLike("enterpriseName", "%" + enterpriseName + "%");
        }
        if (!StringUtils.isEmpty(enterpiseCode)) {
            criteria.andLike("enterpiseCode", "%" + enterpiseCode + "%");
        }
        if (!StringUtils.isEmpty(organizationCode)) {
            criteria.andLike("organizationCode", "%" + organizationCode + "%");
        }
        return enterpriseMapper.selectCountByExample(example);
    }

4)、接口:`UpdateByExampleMapper<T>`

方法:`int updateByExample(@Param("record") T record, @Param("example") Object example);`

说明:根据Example条件更新实体`record`包含的全部属性,null值会被更新

5)、接口:`UpdateByExampleSelectiveMapper<T>`

方法:`int updateByExampleSelective(@Param("record") T record, @Param("example") Object example);`

说明:根据Example条件更新实体`record`包含的不是null的属性值

TraceabilityExtract traceabilityExtract = new TraceabilityExtract();
        traceabilityExtract.setMaterialName(medSeed.getMaterialCommonName());
        Example example = new Example(TraceabilityExtract.class);
        example.createCriteria().andEqualTo("materialCode", medSeed.getMaterialCode());
        traceabilityExtractMapper.updateByExampleSelective(traceabilityExtract, example);

6)、接口:`DeleteByExampleMapper<T>`

方法:`int deleteByExample(Object example);`

说明:根据Example条件删除数据

//查询设备名称1是否存在,如果存在则删除,如果不存在则新增
                List<IntelDrugStore> intelDrugStoreList1 = new ArrayList<>();

                Example example = new Example(IntelDrugStore.class);
                example.createCriteria().andEqualTo("equipmentCode", equipmentCode1)
                        .andEqualTo("equipmentType",equipmentType)
                        .andEqualTo("hospitalName",hospitalName);
                intelDrugStoreList1 = intelDrugStoreMapper.selectByExample(example);
                if(CollectionUtils.isNotEmpty(intelDrugStoreList1)){
                    intelDrugStoreMapper.deleteByExample(example);
                }

3、RowBoundsMapper

@RegisterMapper
public interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker {
}
@RegisterMapper
public interface RowBoundsMapper<T> extends SelectByExampleRowBoundsMapper<T>, SelectRowBoundsMapper<T> {
}

1)、接口:`SelectRowBoundsMapper<T>`

方法:`List<T> selectByRowBounds(T record, RowBounds rowBounds);`

说明:根据实体属性和RowBounds进行分页查询

2)、接口:`SelectByExampleRowBoundsMapper<T>`

方法:`List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds);`

说明:根据example条件和RowBounds进行分页查询

控制返回条数(limit)

Example example = new Example(AppFeedback.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        example.orderBy("submitTime").desc();
        RowBounds rowBounds = new RowBounds(0, 3); // 每次查询3条
        List<AppFeedback> appFeedbacks = appFeedbackMapper.selectByExampleAndRowBounds(example, rowBounds);
        return appFeedbacks;

4、CoditionMapper

当tk.mybatis的版本为2.0.1时,没有ExampleMapper,而是ConditionMapper

<dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.1</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.persistence</groupId>
                    <artifactId>persistence-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

这个版本的条件查询使用的是CondtionMapper,不是ExampleMapper。

Mapper接口:

public interface Mapper<T> extends BaseMapper<T>, ConditionMapper<T>, IdsMapper<T>, InsertListMapper<T> {
}

ConditionMapper

@RegisterMapper
public interface ConditionMapper<T> extends SelectByConditionMapper<T>, SelectCountByConditionMapper<T>, DeleteByConditionMapper<T>, UpdateByConditionMapper<T>, UpdateByConditionSelectiveMapper<T> {
}

Condition方法

接口:SelectByConditionMapper<T>
方法:List<T> selectByCondition(Object condition);
说明:根据Condition条件进行查询

接口:SelectCountByConditionMapper<T>
方法:int selectCountByCondition(Object condition);
说明:根据Condition条件进行查询总数

接口:UpdateByConditionMapper<T>
方法:int updateByCondition(@Param("record") T record, @Param("example") Object condition);
说明:根据Condition条件更新实体record包含的全部属性,null值会被更新

接口:UpdateByConditionSelectiveMapper<T>
方法:int updateByConditionSelective(@Param("record") T record, @Param("example") Object condition);
说明:根据Condition条件更新实体record包含的不是null的属性值

接口:DeleteByConditionMapper<T>
方法:int deleteByCondition(Object condition);
说明:根据Condition条件删除数据

代码示例:

controller

@PostMapping("/datalist")
    public Object datalist(ProduceEnterpriseyp produceEnterpriseyp) {
        Map<String, Object> result = new HashMap<>();

        PageHelper.startPage(produceEnterpriseyp.getPageNumber(), produceEnterpriseyp.getPageSize());
        List<ProduceEnterpriseyp> list = produceEnterpriseypService.selectByCon(produceEnterpriseyp);
        PageInfo<ProduceEnterpriseyp> pageInfo = new PageInfo<>(list);
        if (list.size() > 0) {
            result.put("success", true);
            result.put("rows", list);
            result.put("total", pageInfo.getTotal());
        } else {
            result.put("success", false);
        }
        return result;
    }

service接口

public interface ProduceEnterpriseypService extends Service<ProduceEnterpriseyp> {
    List<ProduceEnterpriseyp> selectByCon(ProduceEnterpriseyp produceEnterpriseyp);
}

service实现类

@Service
public class ProduceEnterpriseypServiceImpl extends AbstractService<ProduceEnterpriseyp> implements ProduceEnterpriseypService {

    @Resource
    private ProduceEnterpriseypMapper produceEnterpriseypMapper;

    @Override
    public List<ProduceEnterpriseyp> selectByCon(ProduceEnterpriseyp produceEnterpriseyp) {
        return produceEnterpriseypMapper.selectByCondition(getCondition(produceEnterpriseyp));
    }

  private Condition getCondition(ProduceEnterpriseyp produceEnterpriseyp){ Condition condition = new Condition(ProduceEnterpriseyp.class); Example.Criteria criteria = condition.createCriteria(); if(StringUtils.isNotBlank(produceEnterpriseyp.getCocode())){ criteria.andLike("cocode",produceEnterpriseyp.getCocode()); } if(StringUtils.isNotBlank(produceEnterpriseyp.getConame())){ criteria.andLike("coname",produceEnterpriseyp.getConame()); } return condition; } }

dao接口

public interface ProduceEnterpriseypMapper extends Mapper<ProduceEnterpriseyp> {
}

 

posted on 2021-02-27 12:15  周文豪  阅读(3253)  评论(0编辑  收藏  举报