当前位置:   article > 正文

tkMybatis基本用法(二)_insertlist使用条件:实体必须包含"id"属性并且必须是自增列

insertlist使用条件:实体必须包含"id"属性并且必须是自增列

概述

考虑到基本数据类型在Java类中都有默认值,会导致Mybatis在执行相关操作时很难判断当前字段是否为null,所以在Mybatis环境下使用java实体类时尽量不要使用基本数据类型,都使用对应的包装类型。

环境搭建

参考:
tkMybatis与springboot整合(一)

常用注解

注解名称用法注意事项
@Table建立实体类和数据表之间的映射关系,在@Table注解的name属性中指定数据表的名称。如果@Table中不指定name,默认规则:实体类名首字母小写作为表名(Employee类对应employee表)
@Column建立实体类属性和表字段之间的映射关系,在@Column注解的name属性中指定表字段名。@Column不指定name,默认属性的驼峰命名对应表字段的“_",比如:parentId对应表字段parent_id。
@Id标识数据表的主键。作用于xxxByPrimaryKey(xxx)方法。
@GeneratedValue让tk在执行insert操作之后将数据库字段生成的主键值回写到实体类对象中。表中主键需要是自增主键、或序列主键。
@Transient用于标记不与数据表字段对应的实体类字段与数据表不相关,tk生成的动态sql不涉及该属性。

@Id注解

通用Mapper在执行xxxByPrimaryKey(param)方法时,有两种情况。

  1. 没有使用@Id注解明确指定主键字段。
select emp_id,emp_name,emp_salary from t_employee where emp_id = ? and emp_name = ? and emp_salary = ?
  • 1

之所以会生成上面这样的where子句是因为tk将实体类中的所有字段都拿来放在一起作为联合主键查询。

  1. 使用@Id注解明确标记和数据库表中主键字段对应的实体类属性
    例如注解在empId属性上:
select emp_id,emp_name,emp_salary from t_employee where emp_id = ?
  • 1

@GeneratedValue

作用:让通用Mapper在执行insert操作之后将数据库自动生成的主键值回写到实体类对象中。

  • 自增主键用法
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer empId;
  • 1
  • 2
  • 3
  • 序列主键用法
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY, generator = "select SEQ_ID.nextval from dual")
private Integer id;
  • 1
  • 2
  • 3

@Transient 主键

用于标记不与数据库表字段对应的实体类字段。

@Transient
private String otherThings; // 非数据库表中字段
  • 1
  • 2

设计演示使用的t_user表和实体类

t_user表

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`
(
    `id`        int NOT NULL AUTO_INCREMENT,
    `user_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `age`       int                                  DEFAULT NULL,
    `sex`       tinyint                              DEFAULT NULL COMMENT "0:男,1:女",
    `address`   varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
    `phone`     varchar(11)                          default null,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

映射t_user表的UserEntity实体类

@Data
@Accessors(chain = true)
@Table(name = "t_user")
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    private Integer id;

    @Column(name = "user_name")
    private String useName;

    private Integer sex;

    private Integer age;

    private String address;

    private String phone;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

基本的CRUD

查询

select

tkmapper使用实体类中的非null字段作为查询条件。

  1. 测试实例
    @Test
    public void testSelect() {
        UserEntity userEntity = new UserEntity();
        userEntity.setUseName("张三");
        userEntity.setPhone("");
        userEntity.setAddress(null);
        System.out.println(userMapper.select(userEntity));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. sql语句
==>  Preparing: SELECT id,user_name,sex,age,address,phone FROM t_user WHERE user_name = ? AND phone = ? 
==> Parameters: 张三(String), (String)
  • 1
  • 2

selectOne方法

通用Mapper替我们自动生成的SQL语句情况。
在这里插入图片描述

  1. 实体类封装查询条件生成where子句的规则。
    • 使用非null的值生成where子句。
    • 在条件表达式中使用 “=” 进行比较。
  2. 要求必须返回一个实体类结果,如果有多个,则会抛出异常。
    在这里插入图片描述

xxxByPrimaryKey方法

需要使用@Id主键明确标记和数据库表主键字段对应的实体类字段,否则通用Mapper会将所有实体类字段作为联合主键。

xxxSelective方法

非主键字段如果为null值,则不加入sql语句中(包括返回字段和查询条件)。

插入

insert

tkmapper插入表中所以字段,没有赋值的字段使用null值。

  1. 测试示例
    @Test
    public void testInsert() {
        UserEntity userEntity = new UserEntity();
        userEntity.setUseName("张三1");
        userEntity.setPhone("");
        userEntity.setAddress(null);
        userMapper.insert(userEntity);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. sql语句
==>  Preparing: INSERT INTO t_user ( id,user_name,sex,age,address,phone ) VALUES( ?,?,?,?,?,? ) 
==> Parameters: null, 张三1(String), null, null, null, (String)
<==    Updates: 1
  • 1
  • 2
  • 3

insertList

批量插入数据,tkmapper插入表中所以字段,没有赋值的字段使用null值。
插入条件:限制实体包含id属性并且必须为自增列。
测试示例:

        List<Person> personEntities = new ArrayList<>();
        ...
        if (CollectionUtils.isNotEmpty(personEntities )) {
            personMapper.insertList(personEntities);
        }
  • 1
  • 2
  • 3
  • 4
  • 5

insertSelective

如果字段为null值(“”或者其它空值会参与sql构造),则不加入sql语句中,也就是非null的字段参与sql语句构造。

  1. 代码中只设置的useName,age,address,sex其他都为默认值null。
        UserEntity userEntity = new UserEntity();
        userEntity.setUseName("李思").setAge(18).setAddress("南京").setSex(1);
  • 1
  • 2
==>  Preparing: INSERT INTO t_user ( user_name,sex,age,address ) VALUES( ?,?,?,? ) 
==> Parameters: 李思(String), 1(Integer), 18(Integer), 南京(String)
<==    Updates: 1
  • 1
  • 2
  • 3

更新

updateByPrimaryKey

通过主键更新对应记录中的除主键外的所有字段。

  1. 代码示例
    @Test
    public void testUpdate() {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1).setAddress("洛阳").setUseName("小华");
        userMapper.updateByPrimaryKey(userEntity);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 动态sql
==>  Preparing: UPDATE t_user SET user_name = ?,sex = ?,age = ?,address = ?,phone = ? WHERE id = ? 
==> Parameters: 小华(String), null, null, 洛阳(String), null, 1(Integer)
  • 1
  • 2

updateByPrimaryKeySelective

通过主键更新对应记录中的非null字段的值,null字段不参与sql构造。

  1. 代码示例
    @Test
    public void testUpdateSelective() {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(40).setAddress("").setUseName("小华");
        userMapper.updateByPrimaryKeySelective(userEntity);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 动态sql
==>  Preparing: UPDATE t_user SET user_name = ?,address = ? WHERE id = ? 
==> Parameters: 小华(String), (String), 40(Integer)
  • 1
  • 2

删除

delete

tkmapper使用非null字段作为删除条件。

  1. 代码示例
    @Test
    public void testDelete() {
        UserEntity userEntity = new UserEntity();
        userEntity.setUseName("").setAge(18);
        userMapper.delete(userEntity);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 动态sql
==>  Preparing: DELETE FROM t_user WHERE user_name = ? AND age = ? 
==> Parameters: (String), 18(Integer)
  • 1
  • 2

deleteByPrimaryKey

可以直接使用主键值或者实体类作为参数。

  1. 代码示例
    @Test
    public void testDeleteByPrimaryKey() {
        UserEntity userEntity = new UserEntity();
        userEntity.setAge(18).setId(1);
        // 使用实体类作为参数
        userMapper.deleteByPrimaryKey(userEntity);

        // 使用主键值作为参数
        userMapper.deleteByPrimaryKey(1);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 动态sql
==>  Preparing: DELETE FROM t_user WHERE id = ? 
==> Parameters: 1(Integer)
  • 1
  • 2

QBC查询(条件Example用法)

上面都是单表最简单的CRUD,但是稍微复杂一些的单表查询无能为力了,这时候是条件查询Example大显身手的时候了。
查询原理:通过实体类属性名称反查出数据表对于的column字段,然后用这些column字段作为查询条件构成动态sql。

概念

Query By Criteria:通过条件查询。
criteria是Criterion的复数形式。意思是:规则、标准、准则。在SQL语句中相当于查询条件。
QBC查询是将查询条件通过java对象进行模块化封装。

andGreaterThan方法

该方法是大于特定值,某字段大于特定值并与上之前的查询条件,参数是实体类的某属性字段名、某属性字段值。

  1. 测试示例
    @Test
    public void testExample1() {
        Example example = new Example(UserEntity.class);
        example.createCriteria().andGreaterThan("useName", "张");
        userMapper.selectByExample(example);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 动态sql
==>  Preparing: SELECT id,user_name,sex,age,address,phone FROM t_user WHERE ( ( user_name > ? ) ) 
==> Parameters: 张(String)
  • 1
  • 2

QBC拼装 where (age > 18 and sex = 1) or ( age < 30 and sex = 0)

  1. 示例代码
    @Test
    public void testCriteria1() {
        Example example = new Example(UserEntity.class);
        // 新增条件1
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andGreaterThan("age", 18).andEqualTo("sex", 1);
        // 新增条件2
        Example.Criteria criteria2 = example.createCriteria();
        criteria2.andLessThan("age", 30).andEqualTo("sex", 0);

        // 设计不是很合理,example不应该代表criteria1与criteria2进行逻辑OR
        example.or(criteria2);
        userMapper.selectByExample(example);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 动态sql
==>  Preparing: SELECT id,user_name,sex,age,address,phone FROM t_user WHERE ( ( age > ? and sex = ? ) or ( age < ? and sex = ? ) ) 
==> Parameters: 18(Integer), 1(Integer), 30(Integer), 0(Integer)
  • 1
  • 2

sql排序、去重、设置select字段

  1. 代码示例
    @Test
    public void testExample() {
        Example example = new Example(UserEntity.class);
        // 设置排序字段
        example.orderBy("age").asc().orderBy("useName").desc();
        // 设置去重
        example.setDistinct(true);
        // 设置select 子句的字段
        example.selectProperties("age", "useName");

        userMapper.selectByExample(example);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. 动态sql
==>  Preparing: SELECT distinct age , user_name FROM t_user order by age ASC,user_name DESC 
==> Parameters: 
  • 1
  • 2

分页查询

通过RowBounds来实现分页查询,指定开始和分页大小。

  1. 代码示例
public Result getPageByEvent(Paging paging, String eventId) {
        // 这是分页
        RowBounds rowBounds = new RowBounds(paging.getPageNum(), paging.getPageSize());
        // new一个Example
        Example example = new Example(Prize.class);
        // 排序
        example.orderBy("singleCont").asc();
        // 添加条件
        Example.Criteria criteria = example.createCriteria();
        // 前面 一个参数对应实体类的 属性,后一个对应 要传的值
        criteria.andEqualTo("eventId", eventId);
        List<Prize> prizes = prizeMapper.selectByExampleAndRowBounds(example, rowBounds);
        return Result.success(new PageInfo<Prize>(prizes));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 动态sql
SELECT prize FROM t_prize order by ? LIMIT ?, ?
==> Parameters: singleCont(String), 1(Integer), 10(Integer)
  • 1
  • 2

方法总结

参考

TkMybatis笔记

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/66300
推荐阅读
相关标签
  

闽ICP备14008679号