1、看包:
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
tk.mybatis
mapper-spring-boot-starter
2.1.5
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.12
2、看配置文件:
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username = root
spring.datasource.password = root
3、看实体注解:
@Data //lombok注解
@Table(name = "tb_student") //映射表注解
public class Student implements Serializable {
@Id
@Column(insertable = false)
//因为用的PGSQL,这里一定要写明查询序列语句,坑点较多
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select nextval('student_id_seq'::regclass)")
private Integer id;
private String name; //如果不使用@Column或者下划线转换等,则需要和数据库字段保持一致
private String address;
}
4、看通用mapper
public interface MyMapper extends Mapper,InsertListMapper {
}
这里有个坑...,只需要继承就行了,不需要写其他东西,记得别忘了保持泛型
5、看通用service,可选,通用mapper可以直接通过@Autowired直接装配使用了,不过最好定义一个通用service
public interface BaseService {
void save(T model);//持久化
void save(List models);//批量持久化
void deleteById(TD id);//通过主鍵刪除
void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4” //这里有个坑
void update(T model);//更新
T findById(TD id);//通过ID查找
T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束
List findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4” //这里有个坑
List findByCondition(Condition condition);//根据条件查找
List findAll();//获取所有
}
6、看Service实现
public class AbstractService implements BaseService {
@Autowired
private MyMapper mapper;
private Class clazz;
public AbstractService(){
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); //获取超类类型,带泛型
clazz = (Class) pt.getActualTypeArguments()[0]; //获取泛型类型,就一个泛型,取数组第一个就行了
}
@Override
public void save(T model) {
mapper.insertSelective(model);
}
@Override
public void save(List models) {
mapper.insertList(models);
}
@Override
public void deleteById(TD id) {
mapper.deleteByPrimaryKey(id);
}
@Override
public void deleteByIds(String ids) {
mapper.deleteByIds(ids);
}
@Override
public void update(T model) {
mapper.updateByPrimaryKeySelective(model);
}
@Override
public T findById(TD id) {
return mapper.selectByPrimaryKey(id);
}
@Override
public T findBy(String fieldName, Object value) throws TooManyResultsException {
T model = null;
try {
model = clazz.newInstance(); //实例化对象
Field field = clazz.getDeclaredField(fieldName); //获取属性
field.setAccessible(true); //暴力破解private
field.set(model, value); //属性赋值
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return mapper.selectOne(model); //查询
}
@Override
public List findByIds(String ids) {
return mapper.selectByIds(ids);
}
@Override
public List findByCondition(Condition condition) {
return mapper.selectByCondition(condition);
}
@Override
public List findAll() {
return mapper.selectAll();
}
}
PS:如果是tk.mapper需要获取泛型的话,涉及到了动态代理,需要子类teacherMapper.getClass.getInterfaces()[0].getGenericInterfaces()[0]
//动态代理获取到的class不是teacherMapper,需要先获取接口
//getGenericInterfaces()[0]:获取直接父接口的第一个接口
7、看PageHelper的基本使用
PageHelper.startPage(1,1); //设置分页数据,该方法之后的第一个select方法会进行分页
PageInfo page = PageInfo.of(service.findAll()); //获得page数据
PS:PageHelper在面对连表查询的时候会出现总记录数错乱,例如A表中的属性包含了N个B表,解决方法是在xml中分表,使用
8、添加一个bean,摒弃注解扫描mapper
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
//自己的mapper位置
mapperScannerConfigurer.setBasePackage("com.fengwuJ.tkmybatis.mymapper");
Properties propertiesMapper = new Properties();
// 通用mapper位置,接口全路径
propertiesMapper.setProperty("mappers", "com.fengwuJ.tkmybatis.basemapper.MyMapper");
propertiesMapper.setProperty("notEmpty", "false");
//主键UUID回写方法执行顺序,默认AFTER,可选值为(BEFORE|AFTER)
propertiesMapper.setProperty("ORDER", "BEFORE");
mapperScannerConfigurer.setProperties(propertiesMapper);
return mapperScannerConfigurer;
}
插入
SqlServerMapper—>InsertMapperàSqlServerProvideràinsert:
INSERT INTO tb_teacher ( name,update_time,is_deleted ) VALUES ( ?,?,? )
直接跳过了id的拼接
@Options(
useGeneratedKeys = true
)
@InsertProvider(
type = SqlServerProvider.class,
method = "dynamicSQL"
)
int insert(T var1);
使用@Options(useGeneratedKeys = true) 回显主键
@Id:指定主键
@Column:指定数据库查询出来的记录字段(也可以是别名)与实体属性的映射关系,不配置则默认相同名称映射
InsertMappeàInsertMapperà BaseInsertProvideràinsert
PS: insertable:默认为true,设置为false时不会拼接该字段