【Mybatis】SP02 通用Mapper 基础CRUD

编写Mapper测试类:

@Test
public void selectOneTest() {
    // 查询一个记录,居然需要提供一个实例
    // 实例的各个属性即筛选的要求
    Employee employee = new Employee(2,null,null,null);
    employee = employeeMapper.selectOne(employee);
    log.info(employee.toString());
}

结果很正常的就报错了,因为一开始我们的数据库表名称并没有在Java中绑定注释

报错信息:

Caused by: java.sql.SQLSyntaxErrorException: Table 'common_mapper.employee' doesn't exist

解决办法是使用JPA规范提供的@Table注解

import javax.persistence.Table;

然后注解在实体类上面:

再次测试发现有报错了。。。原来表名创建的时候写歪了我日:

 

然后再次更改,测试:

总算成功了

DEBUG [main] - ==>  Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp WHERE emp_id = ?
DEBUG [main] - ==> Parameters: 2(Integer)
DEBUG [main] - <==      Total: 1
DEBUG [main] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@53dbe163]
 INFO [main] - Employee(emp_id=2, emp_name=jerry, emp_salary=6635.42, emp_age=38)

 

除了@Table注解,JPA规范还提供了@Column注解,用于绑定字段名称

再次测试查看结果:结果是依然可以的

DEBUG [main] - ==>  Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp WHERE emp_id = ?
DEBUG [main] - ==> Parameters: 2(Integer)
DEBUG [main] - <==      Total: 1
DEBUG [main] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1b835480]
DEBUG [HikariPool-1 housekeeper] - HikariPool-1 - Pool stats (total=1, active=1, idle=0, waiting=0)
 INFO [main] - Employee(id=2, name=jerry, salary=6635.42, age=38)

 

selectByPrimaryKey();

@Test
public void selectOneByPrimaryKeyTest() {
    Employee employee = employeeMapper.selectByPrimaryKey(1);
    log.info(employee.toString());
}

查询结果发现空指针:

java.lang.NullPointerException

这时在查看上面打印的SQL语句:

可这并不是我们希望的样子

DEBUG [main] - ==>  Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp WHERE emp_id = ? AND emp_name = ? AND emp_salary = ? AND emp_age = ?
DEBUG [main] - ==> Parameters: 1(Integer), 1(Integer), 1(Integer), 1(Integer)
DEBUG [main] - <==      Total: 0

问题的原因通用Mapper 将实体类中的所有字段都拿来放在一起作为联合主键

 

解决方案居然是使用@Id注解标明数据表的主键字段

再次测试成功:

DEBUG [main] - ==>  Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp WHERE emp_id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
DEBUG [main] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3549bca9]
 INFO [main] - Employee(id=1, name=tom, salary=1254.37, age=27)

 

用来判断提供的主键是否存在:

@Test
public void selectOneByPrimaryKeyTest2() {
    boolean isExist = employeeMapper.existsWithPrimaryKey(5);
    Boolean wrapperResult = isExist;
    log.info(wrapperResult.toString());
}

测试结果:

DEBUG [main] - ==>  Preparing: SELECT CASE WHEN COUNT(emp_id) > 0 THEN 1 ELSE 0 END AS result FROM tabple_emp WHERE emp_id = ?
DEBUG [main] - ==> Parameters: 5(Integer)
DEBUG [main] - <==      Total: 1

 

插入实体实例操作:

@Test
public void insertTest() {
    Employee employee = new Employee(null, "杰哥", 3300.00, 24);
    int insert = employeeMapper.insert(employee);
    log.info("操作结果:" + insert);
}

测试结果:

DEBUG [main] - ==>  Preparing: INSERT INTO tabple_emp ( emp_id,emp_name,emp_salary,emp_age ) VALUES( ?,?,?,? )
DEBUG [main] - ==> Parameters: null, 杰哥(String), 3300.0(Double), 24(Integer)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3549bca9]
 INFO [main] - 操作结果:1

除了操作插入之外,还很贴心的给我们提供了返回自增主键的功能

但是需要注解设置:

获取方式:

@Test
public void insertTest() {
    Employee employee = new Employee(null, "阿伟", 9300.00, 21);
    int insert = employeeMapper.insert(employee);
    Integer id = employee.getId();
    log.info("操作结果:" + insert);
    log.info("自增返回的主键:" + id);
}

测试结果:

DEBUG [main] - ==>  Preparing: INSERT INTO tabple_emp ( emp_id,emp_name,emp_salary,emp_age ) VALUES( ?,?,?,? )
DEBUG [main] - ==> Parameters: null, 阿伟(String), 9300.0(Double), 21(Integer)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - ==>  Executing: SELECT LAST_INSERT_ID()
DEBUG [main] - <==      Total: 1
DEBUG [main] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4748a0f9]
 INFO [main] - 操作结果:1
 INFO [main] - 自增返回的主键:8

 

但是像Oracle采用序列主键的话,就需要单独再设置:

 

 

insertSelective方法:

带选择性的插入,所谓的选择性,就是一些字段值为NULL,SQL语句干脆就不注入这个字段

案例:

@Test
public void selectiveInsertTest() {
    int insertSelective = employeeMapper.insertSelective(new Employee());
}

结果,除了主键的NULL注入,其他属性一律就没写给SQL中

DEBUG [main] - ==>  Preparing: INSERT INTO tabple_emp ( emp_id ) VALUES( ? )
DEBUG [main] - ==> Parameters: null
DEBUG [main] - <==    Updates: 1
DEBUG [main] - ==>  Executing: SELECT LAST_INSERT_ID()
DEBUG [main] - <==      Total: 1

我的演示可能不恰当,准且来说应该使用这个才对:

@Test
public void selectiveInsertTest() {
    int insertSelective = employeeMapper.insertSelective(new Employee(null, null, null, null));
}

updateSelective方法:

上述的这种插入方法再这个修改的案例中,能体现的更为明显,

例如现在我们修改一条记录:

当前主键为8的记录的员工名称是阿伟,而我们希望改变成其他名称

 

这是我们的测试方法:

@Test
public void selectiveUpdateTest() {
    int update = employeeMapper.updateByPrimaryKeySelective(new Employee(8, "空条承太郎", null, null));
}

后面的两个字段没有赋值,都为null,按照通常的理解,SQL语句的执行将会把这些为NULL的值也注入

那么来看结果:

DEBUG [main] - ==>  Preparing: UPDATE tabple_emp SET emp_id = emp_id,emp_name = ? WHERE emp_id = ?
DEBUG [main] - ==> Parameters: 空条承太郎(String), 8(Integer)
DEBUG [main] - <==    Updates: 1

实际改变的只有名称字段,那么这么做的好处,就是在编写修改操作的业务时,我们不需要携带记录的完整信息,

 

我们修改业务: 根据主键查询需要修改的记录,然后渲染在修改页上面,用户提交修改信息,再把完整的记录信息带回后台处理

如果有这样智能选择的操作,就只需要提供的必要的修改信息和主键就够了,又能少搬些砖了

deleteByPrimaryKey方法

使用DELETE方法注入NULL将会删除表的所有记录,切记

@Test
public void deleteOneByPrimaryKey() {
    // 这样表示删除所有记录
    int i = employeeMapper.delete(null);
}

按主键删除:如果为空,筛选条件将不匹配

@Test
public void deleteOneByPrimaryKey2() {
    int i = employeeMapper.deleteByPrimaryKey(null);
}

 

 

selectRowBounds方法:

这个方法的限制查询非常与众不同,

先看测试类:

@Test
public void selectByRowBounds() {
    int startingPosition = 3;
    int sizeLimitation = 10;
    RowBounds rowBounds = new RowBounds(startingPosition, sizeLimitation);
    List<Employee> employeeList = employeeMapper.selectByRowBounds(new Employee(), rowBounds);
    for (Employee employee : employeeList) {
        log.info(employee.toString());
    }
}

结果:

DEBUG [main] - ==>  Preparing: SELECT emp_id,emp_name,emp_salary,emp_age FROM tabple_emp
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 5
 INFO [main] - Employee(id=4, name=kate, salary=2209.11, age=22)
 INFO [main] - Employee(id=5, name=justin, salary=4203.15, age=30)

说明这个查询会从SQL中查询所有,再到程序中按照限制条件返回

 

 

@Transient注解用于排除非数据库表的字段属性

 

posted @ 2020-08-27 13:52  emdzz  阅读(253)  评论(0)    收藏  举报