TkMybatis 笔记


1 通用TkMybatis笔记
1 引入
1.1作用
 替我们生成常用增删改查操作的SQL 语句。
1.2代码官方发布地址

https://gitee.com/free
https://gitee.com/free/Mapper/wikis/1.1-java?parent=1.integration


1.3前置知识
MyBatis
Spring
2 快速入门
2.1创建测试数据
 SQL 语句

CREATE TABLE `tabple_emp` (
`emp_id` int NOT NULL AUTO_INCREMENT ,
`emp_name` varchar(500) NULL ,
`emp_salary` double(15,5) NULL ,
`emp_age` int NULL ,
PRIMARY KEY (`emp_id`)
);
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('tom', '1254.37', '27');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('jerry', '6635.42', '38');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('bob', '5560.11', '40');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('kate', '2209.11', '22');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('justin', '4203.15', '30');


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

public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
public Employee() {
}
public Employee(Integer empId, String empName, Double empSalary, Integer empAge) {
super();
this.empId = empId;
this.empName = empName;
this.empSalary = empSalary;
this.empAge = empAge;
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + ", empSalary=" + empSalary + ", empAge=" + empAge
+ "]";
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Double getEmpSalary() {

return empSalary;
}
public void setEmpSalary(Double empSalary) {
this.empSalary = empSalary;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
}


2.2搭建MyBatis+Spring 开发环境
2.3集成Mapper
 加入Maven 依赖信息


tk.mybatis
mapper
4.0.0-beta3


 修改Spring 配置文件







2.4第一个操作

/**
* 具体操作数据库的Mapper 接口, 需要继承通用Mapper 提供的核心接口:
Mapper
* 泛型类型就是实体类的类型
* @author Lenovo
*/
public interface EmployeeMapper extends Mapper {
}


3 常用注解
3.1@Table 注解
作用:建立实体类和数据库表之间的对应关系。
默认规则:实体类类名首字母小写作为表名。Employee 类→employee 表。
用法:在@Table 注解的name 属性中指定目标数据库表的表名
3.2@Column 注解
作用:建立实体类字段和数据库表字段之间的对应关系。
默认规则:
实体类字段:驼峰式命名
数据库表字段:使用“_”区分各个单词
用法:在@Column 注解的name 属性中指定目标字段的字段名
3.3@Id 注解
通用Mapper 在执行xxxByPrimaryKey(key)方法时,有两种情况。
情况1:没有使用@Id 注解明确指定主键字段

SELECT emp_id,emp_name,emp_salary_apple,emp_age FROM tabple_emp WHERE emp_id = ?
AND emp_name = ? AND emp_salary_apple = ? AND emp_age = ?


之所以会生成上面这样的WHERE 子句是因为通用Mapper 将实体类中的所有
字段都拿来放在一起作为联合主键。
情况2:使用@Id 主键明确标记和数据库表中主键字段对应的实体类字段。
3.4@GeneratedValue 注解
作用:让通用Mapper 在执行insert 操作之后将数据库自动生成的主键值回写到实
体类对象中。
自增主键用法:
序列主键用法:
应用场景:购物车结账
 增加商品销量...
 减少商品库存...
 生成订单数据→封装到Order 对象中→保存Order 对象→数据库自动生成主键
值→回写到实体类对象Order 中
 生成一系列订单详情数据→List→在每一个OrderItem 中设置
Order 对象的主键值作为外键→批量保存List
……
3.5@Transient 主键
用于标记不与数据库表字段对应的实体类字段。

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


4 常用方法
4.1selectOne 方法
 通用Mapper 替我们自动生成的SQL 语句情况
 实体类封装查询条件生成WHERE 子句的规则
 使用非空的值生成WHERE 子句
 在条件表达式中使用“=”进行比较
 要求必须返回一个实体类结果,如果有多个,则会抛出异常

4.2xxxByPrimaryKey 方法
需要使用@Id 主键明确标记和数据库表主键字段对应的实体类字段,否则通用
Mapper 会将所有实体类字段作为联合主键。
4.3xxxSelective 方法
非主键字段如果为null 值,则不加入到SQL 语句中。
5 QBC 查询
5.1概念
Query By Criteria
Criteria 是Criterion 的复数形式。意思是:规则、标准、准则。在SQL 语句中相当
于查询条件。
QBC 查询是将查询条件通过Java 对象进行模块化封装。
5.2示例代码

//目标:WHERE (emp_salary>? AND emp_age?)
//1.创建Example 对象
Example example = new Example(Employee.class);
//***********************
//i.设置排序信息
example.orderBy("empSalary").asc().orderBy("empAge").desc();
//ii.设置“去重”
example.setDistinct(true);
//iii.设置select 字段
example.selectProperties("empName","empSalary");
//***********************
//2.通过Example 对象创建Criteria 对象
Criteria criteria01 = example.createCriteria();
Criteria criteria02 = example.createCriteria();
//3.在两个Criteria 对象中分别设置查询条件
//property 参数:实体类的属性名
//value 参数:实体类的属性值
criteria01.andGreaterThan("empSalary", 3000)
.andLessThan("empAge", 25);
criteria02.andLessThan("empSalary", 5000)
.andGreaterThan("empAge", 30);
//4.使用OR 关键词组装两个Criteria 对象
example.or(criteria02);
//5.执行查询
List empList = employeeService.getEmpListByExample(example);
for (Employee employee : empList) {
System.out.println(employee);
}


6 逆向工程
6.1原生MyBatis 逆向工程和通用Mapper 逆向工程对比
6.2参考文档地址
https://github.com/abel533/Mapper/wiki/4.1.mappergenerator
7 自定义Mapper接口
7.1用途
让我们可以根据开发的实际需要对Mapper接口进行定制。
7.2创建自定义Mapper接口
7.3配置MapperScannerConfigurer 注册MyMapper





mappers=com.atguigu.mapper.mine_mappers.MyMapper



8 通用Mapper 接口扩展
8.1说明
这里的扩展是指增加通用Mapper 没有提供的功能。
8.2举例
通用Mapper 官方文档中使用一个批量insert 作为扩展功能的例子:

tk.mybatis.mapper.additional.insert.InsertListMapper
tk.mybatis.mapper.additional.insert.InsertListProvider


我们来仿照写一个批量update。假设我们想生成下面这样的SQL 语句:

UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
……


为了生成上面那样的SQL 语句,我们需要使用到MyBatis 的foreach 标签。


UPDATE tabple_emp
SET emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salary=#{record.empSalary}
where emp_id=#{record.empId}


8.3我们需要提供的接口和实现类


8.4参考代码


9 二级缓存
9.1MyBatis 配置文件开启二级缓存功能




9.2在XxxMapper 接口上使用@CacheNamespace 注解

@CacheNamespace
public interface EmployeeMapper extends MyMapper {
}


10 类型处理器:TypeHandler
10.1简单类型和复杂类型
基本数据类型byte short int long double float char boolean
引用数据类型类、接口、数组、枚举……
简单类型只有一个值的类型
复杂类型有多个值的类型
※通用Mapper 默认情况下会忽略复杂类型,对复杂类型不进行“从类到表”的映
射。
10.2Address 处理
10.2.1 自定义类型转换器
10.2.2 TypeHandler 接口

public interface TypeHandler {
//将parameter 设置到ps 对象中,位置是i
//在这个方法中将parameter 转换为字符串
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws
SQLException;
//根据列名从ResultSet 中获取数据,通常是字符串形式
//将字符串还原为Java 对象,以T 类型返回
T getResult(ResultSet rs, String columnName) throws SQLException;
T getResult(ResultSet rs, int columnIndex) throws SQLException;
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
10.2.3 继承树
10.2.4 BaseTypeHandler 类中的抽象方法说明
//将parameter 对象转换为字符串存入到ps 对象的i 位置
public abstract void setNonNullParameter(
PreparedStatement ps,
int i,
T parameter,
JdbcType jdbcType) throws SQLException;
//从结果集中获取数据库对应查询结果
//将字符串还原为原始的T 类型对象
public abstract T getNullableResult(
ResultSet rs,
String columnName) throws SQLException;
public abstract T getNullableResult(
ResultSet rs,
int columnIndex) throws SQLException;
public abstract T getNullableResult(
CallableStatement cs,
int columnIndex) throws SQLException;
10.2.5 自定义类型转换器类
public class AddressTypeHandler extends BaseTypeHandler
{ ……


10.2.6 注册自定义类型转换器
 方法一字段级别:@ColumnType 注解
 方法二全局级别:在MyBatis 配置文件中配置typeHandlers

10.3枚举类型
10.3.1 办法一:让通用Mapper 把枚举类型作为简单类型处理
 增加一个通用Mapper 的配置项
在Spring 配置文件中找到MapperScannerConfigurer
 本质
使用了org.apache.ibatis.type.EnumTypeHandler
10.3.2 办法二:为枚举类型配置对应的类型处理器
 类型处理器
 内置
 org.apache.ibatis.type.EnumTypeHandler
 在数据库中存储枚举值本身
 org.apache.ibatis.type.EnumOrdinalTypeHandler
 在数据库中仅仅存储枚举值的索引
 自定义
 内置枚举类型处理器注册
 不能使用@ColumnType 注解
 需要在MyBatis 配置文件中配置专门的类型处理器并在字段上使用


@Column 注解
※注意:加@Column 注解的作用是让通用Mapper 不忽略枚举类型。

你可能感兴趣的:(html,jsp,js,java,javaScript,Jquery)