Mybatis Flex 常见用法
2023-12-22 15:07:04
Mybatis Flex 常见用法
一、枚举
-
枚举类
@Getter @AllArgsConstructor public enum GradeEnum { UNKNOWN(0, "未知"), SECONDARY(2, "中学"), PRIMARY(1, "小学"), HIGH(3, "高中"); @EnumValue // 数据库存储字段 private final Integer code; @JsonValue // 转 Json 字段 private final String name; }
-
使用
@Data @Table(value = "t_student") public class Student { @Id(keyType = KeyType.Auto) private Integer id; // 枚举 private GradeEnum grade; }
二、自动填充
2.1 方式一:@Table 配置
-
监听器
public class AutoFillListener implements InsertListener, UpdateListener { @Override public void onInsert(Object o) { BaseEntity baseEntity = (BaseEntity) o; // TODO 获取当前用户 String username = "测试用户"; Date now = new Date(); baseEntity.setCreatedBy(username); baseEntity.setCreatedTime(now); baseEntity.setUpdatedBy(username); baseEntity.setUpdatedTime(now); } @Override public void onUpdate(Object o) { BaseEntity baseEntity = (BaseEntity) o; // TODO 获取当前用户 String username = "测试用户"; Date now = new Date(); baseEntity.setUpdatedBy(username); baseEntity.setUpdatedTime(now); } }
-
注解配置
@EqualsAndHashCode(callSuper = true) @Data @Table(value = "t_product", onInsert = AutoFillListener.class, onUpdate = AutoFillListener.class) public class Product extends BaseEntity { @Id(keyType = KeyType.Auto) private Integer id; private String name; private GradeEnum grade; } @Data public abstract class BaseEntity implements Serializable { // 创建人 private String createdBy; // 创建时间 private Date createdTime; // 更新人 private String updatedBy; // 更新时间 private Date updatedTime; }
2.2 方式二:@Column 配置
@Data
public abstract class BaseEntity implements Serializable {
@Column(onInsertValue = "'测试'")
// 创建人
private String createdBy;
// 创建时间
@Column(onInsertValue = "now()")
private Date createdTime;
// 更新人
@Column(onInsertValue = "'测试'", onUpdateValue = "'测试'")
private String updatedBy;
// 更新时间
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private Date updatedTime;
}
三、分页
3.1 分页统一接口
public interface AppPage<T> {
/**
* 当前页页码
*/
long getPageNum();
/**
* 每页条数
*/
long getPageSize();
/**
* 总条数
*/
long getTotal();
/**
* 总页数
*/
long getTotalPages();
/**
* 分页对象记录
*/
List<T> getItems();
}
3.2 实现分页接口
@AllArgsConstructor
public class MybatisFlexPageImpl<T> implements AppPage<T> {
private Page<T> page;
@Override
public long getPageNum() {
if (page == null) return 0;
return page.getPageNumber();
}
@Override
public long getPageSize() {
if (page == null ) return 0;
return page.getPageSize();
}
@Override
public long getTotal() {
if (page == null ) return 0;
return page.getTotalRow();
}
@Override
public long getTotalPages() {
if (page == null ) return 0;
return page.getTotalPage();
}
@Override
public List<T> getItems() {
return page.getRecords();
}
}
3.3 使用
@RestController
@RequestMapping("product")
public class ProductController {
@GetMapping("page")
public AppPage<Product> page (){
Page<Product> paginate = productRepo.paginate(1, 2, QueryCondition.createEmpty());
return new MybatisFlexPageImpl<Product>(paginate);
}
}
四、关联查询
4.1 @RelationOneToOne:一对一
4.1.1 单向关联
-
User
@Data @Table(value = "t_user") public class User { @Id(keyType = KeyType.Auto) private Integer id; @RelationOneToOne(selfField = "id", targetField = "userId") // selfField 为主键可省略 private UserInfo userInfo; }
-
UserInfo
@Data @Table(value = "t_user_info") public class UserInfo { @Id(keyType = KeyType.Auto) private Integer id; private Integer userId; // 一对一关系,对应的关联字段 }
4.1.2 双向关联
-
User
@Data @Table(value = "t_user") public class User { @Id(keyType = KeyType.Auto) private Integer id; @RelationOneToOne(selfField = "id", targetField = "userId") // selfField 为主键可省略 private UserInfo userInfo; }
-
UserInfo
@Data @Table(value = "t_user_info") public class UserInfo { @Id(keyType = KeyType.Auto) private Integer id; @RelationOneToOne(selfField = "userId", targetField = "id") private User user; private Integer userId; }
4.2 @RelationOneToMany && @RelationManyToOne:一对多 和 多对一
4.2.1 单向关联
-
@RelationOneToMany
Group
@Data @Table(value = "t_group") public class Group { @Id(keyType = KeyType.Auto) private Integer id; // 单向关联 @RelationOneToMany(selfField = "id", targetField = "groupId") List<Student> studentList; }
Student
@Data @Table(value = "t_student") public class Student { @Id(keyType = KeyType.Auto) private Integer id; private Integer groupId; // 单向关联字段 }
-
@RelationManyToOne
Student
@Data @Table(value = "t_student") public class Student { @Id(keyType = KeyType.Auto) private Integer id; // 单向关联 @RelationManyToOne(selfField = "groupId", targetField = "id") private Group group; private Integer groupId; }
Group
@Data @Table(value = "t_group") public class Group { @Id(keyType = KeyType.Auto) private Integer id; }
4.2.2 双向关联
-
Student
@Data @Table(value = "t_student") public class Student { @Id(keyType = KeyType.Auto) private Integer id; // 双向关联 @RelationManyToOne(selfField = "groupId", targetField = "id") private Group group; private Integer groupId; }
-
Group
@Data @Table(value = "t_group") public class Group { @Id(keyType = KeyType.Auto) private Integer id; // 单向关联 @RelationOneToMany(selfField = "id", targetField = "groupId") List<Student> studentList; }
4.3 @RelationManyToMany:多对多
4.3.1 单向关联
@Data
@Table(value = "t_user")
public class User {
@Id(keyType = KeyType.Auto)
private Integer id;
@RelationManyToMany(joinTable = "t_user_role", // 中间表
selfField = "id", joinSelfColumn = "user_id", // selfField 为主键时可省略
targetField = "id", joinTargetColumn = "role_id") // targetField 为主键时可省略
private List<Role> roles;
}
4…3.2 双向关联
-
User
@Data @Table(value = "t_user") public class User { @Id(keyType = KeyType.Auto) private Integer id; @RelationManyToMany(joinTable = "t_user_role", // 中间表 selfField = "id", joinSelfColumn = "user_id", // selfField 为主键时可省略 targetField = "id", joinTargetColumn = "role_id") // targetField 为主键时可省略 private List<Role> roles; }
-
Role
@Data @Table(value = "t_role") public class Role { @Id(keyType = KeyType.Auto) private Integer id; @RelationManyToMany(joinTable = "t_user_role", joinSelfColumn = "role_id", joinTargetColumn = "user_id") private List<User> userList; }
4.4 ByQuery
@SpringBootTest
public class TableAssociation {
@Autowired
private StudentMapper studentMapper;
@Autowired
private GroupMapper groupMapper;
@Test // 关联查询
public void associationQuery() {
// 查询 Student 及对应的 Group
List<Student> students = studentMapper.selectListByQuery(QueryWrapper.create(),
fb -> fb.field(Student::getGroup)
.queryWrapper(student ->{
Group group = new Group();
group.setId(student.getId());
return QueryWrapper.create(group);
})
);
System.out.println(students);
// 查询 Group 及对应的 Student
List<Group> groups = groupMapper.selectListByQuery(QueryWrapper.create(),
f -> f.field(Group::getStudentList)
.queryWrapper(group -> {
Student student = new Student();
student.setGroupId(group.getId());
return QueryWrapper.create(student);
}));
System.out.println(groups);
}
}
五、多数据源
DataSourceKey.use() > @UseDataSource()在方法上 > @UseDataSource()在类上 >@Table(dataSource=“…”)
5.1 配置
5.1.1 application.yml (必须)
mybatis-flex:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
datasource:
master:
url: jdbc:mysql://localhost:3336/test?serverTimezone=UTC
username: root
password: 123456
slave01:
url: jdbc:mysql://localhost:3337/test?serverTimezone=UTC
username: root
password: 123456
5.1.2 @Table(dataSource = “slave01”)(选择配置)
@Data
@Table(value = "t_student",dataSource = "slave01")
public class Student {}
5.1.2 @UseDataSource(选择配置)
@Mapper
@UseDataSource("slave01") // 用于类
public interface GroupMapper extends BaseMapper<Group> {}
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
@UseDataSource("master") // 用于方法
@Select("select * from t_product")
List<Product> findAll();
}
5.3 使用
@SpringBootTest
public class MoreSourceTest {
@Autowired
private StudentMapper studentMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private GroupMapper groupMapper;
/**
* 使用 @Table(dataSource = "master")
*/
@Test
public void get() {
List<Student> students = studentMapper.selectAll();
System.out.println(students);
List<User> users = userMapper.selectAll();
System.out.println(users);
}
/**
* 使用 @UseDataSource("master")
*/
@Test
public void get2 (){
List<Group> groups = groupMapper.selectAll();
System.out.println(groups);
}
/**
* 使用 DataSourceKey.use("master")
*/
@Test
public void get3 (){
List<Group> groups = groupMapper.selectAll();
System.out.println(groups);
try {
DataSourceKey.use("master");
List<Row> rows = Db.selectAll("t_Group");
List<Group> groupList = rows.stream().map(e -> {
Group group = new Group();
BeanUtil.copyProperties(e, group);
return group;
}).toList();
System.out.println(groupList);
}finally {
DataSourceKey.clear();
}
}
}
六、读写分离
6.1 读写分离策略
@Slf4j
public class ReaderAndWriterStrategy implements DataSourceShardingStrategy {
private static final String MASTER = "master";
private static final String SLAVE = "slave*";
@Override
public String doSharding(String currentDataSourceKey, Object mapper, Method mapperMethod, Object[] methodArgs) {
// 增删改 用 master
if (StringUtil.startsWithAny(mapperMethod.getName(),"insert","delete","update")){
return MASTER;
}
// 其他场景使用 slave开头 的数据源进行负载均衡
return SLAVE;
}
}
6.2 配置
@Configuration
public class ReaderAndWriterConfig {
@Bean
public DataSourceManager dataSourceManager(){
DataSourceManager dataSourceManager = new DataSourceManager();
dataSourceManager.setDataSourceShardingStrategy(new ReaderAndWriterStrategy());
return dataSourceManager;
}
}
七、其他
5.1 逻辑删除
@Data
@Table(value = "t_student")
public class Student {
@Id(keyType = KeyType.Auto)
private Integer id;
@Column(isLogicDelete = true)
private boolean deleted;
}
5.2 数据脱敏
@Data
@Table(value = "t_student")
public class Student {
@Id(keyType = KeyType.Auto)
private Integer id;
@ColumnMask(Masks.CHINESE_NAME) // 自带脱敏
private String name;
@ColumnMask("sexMask") // 自定义脱敏
private String sex;
static { // 自定义脱敏逻辑
MaskManager.registerMaskProcessor("sexMask", data -> "*");
}
}
文章来源:https://blog.csdn.net/qq_42151956/article/details/135150899
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!