整合一些工具类,如代码生成器、bena复制、对象联表查询、阻塞同步修改数值等。
<dependency>
<groupId>io.gitee.laoshirenggo</groupId>
<artifactId>mybatis-plus</artifactId>
<version>1.3</version>
</dependency>
这块来源于其他开源项目,我这里只做一个文档化和简化配置,扩展的mybatis-plus,拥有plus一切功能,不影响原本任何业务代码,并扩展了基于实体对象关联查询,支持避免使用xml硬编码,减少代码量,整合仅需如下三步
整合例子:
/**
* 数据库实体类
*/
@Data
@Accessors(chain = true)
public class Demo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
}
/**
* mapper
*/
public interface DemoMapper extends JoinBaseMapper<Demo> {
}
/**
* 接口
*/
public interface DemoService extends JoinIService<Demo> {
}
/**
* 接口实现
*/
@Service
public class DemoServiceIMpl extends JoinServiceImpl<DemoMapper, Demo> implements DemoService {
}
好了,可以愉快的使用所有mybatis-plus已有的功能了~
api如下:
joinCount(Wrapper<E> wrapper) 关联查询数量
joinGetOne(Wrapper<E> wrapper, Class<EV> clz) 关联查询对象
joinList(Wrapper<E> wrapper, Class<EV> clz) 关联查询集合
joinPage(E page, Wrapper<C> wrapper, Class<EV> clz) 关联查询分页
实体对象相关
/**
* 数据库实体类demo
*/
@Data
public class Demo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
}
/**
* 数据库实体类test
*/
@Data
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
}
/**
* 连表结果实体
*/
@Data
public static class DemoVo3 extends Demo {
private String testId;
private String testName;
private String demoId;
}
关联代码
@Service
public class DemoServiceIMpl extends JoinServiceImpl<DemoMapper, Demo> implements DemoService {
public List<DemoVo3> join() {
JoinLambdaWrapper<Demo> demoJoinLambdaWrapper = new JoinLambdaWrapper<>(Demo.class)
//和LambdaQueryWrapper一样可以指定主表需要查询的字段,默认全部
//.select(Demo::getId)
//.selectAll()
//和LambdaQueryWrapper一样可以拼装主表查询条件
//.eq(Demo::getId, 1)
//内联查询,参数1:需要关联的表对象class,参数2:从表on条件属性名,参数3:主表on条件属性名
.innerJoin(Test.class, Test::getDemoId, Demo::getId)
//从表需要查询的字段,默认无
.selectAs(cb -> {
//因为Demo和Test两个实体属性名一样,所以要取别名区分,参数1:表字段名,参数2:别名,参数3:实体属性名
cb.add(Test::getId, "test_id", TestVo::getTestId);
cb.add(Test::getName, "test_name", TestVo::getTestName);
//关联表属性名没有相同无需取别名赋值
cb.add(Test::getDemoId);
})
//和LambdaQueryWrapper一样可以拼装从表查询条件
//.eq(Test::getId, 2)
//和LambdaQueryWrapper一样可以指定从表需要查询的字段,默认无
//.selectAll()
.end();
//调用关联查询
List<DemoVo3> demos = joinList(demoJoinLambdaWrapper, DemoVo3.class);
return demos;
}
}
实体对象相关
/**
* 子表结果实体 必须继承数据库实体
*/
@Data
public static class TestVo extends Test {
private String testId;
private String testName;
private String demoId;
}
/**
* 连表结果实体
*/
@Data
public static class DemoVo2 extends Demo {
private TestVo testVo;
}
关联代码
public List<DemoVo2> oneToOne() {
JoinLambdaWrapper<Demo> demoJoinLambdaWrapper = new JoinLambdaWrapper<>(Demo.class)
//和LambdaQueryWrapper一样可以指定主表需要查询的字段,默认全部
//.select(Demo::getId)
//.selectAll()
//和LambdaQueryWrapper一样可以拼装主表查询条件
//.eq(Demo::getId, 1)
//内联查询,参数1:需要关联的表对象class,参数2:从表on条件属性名,参数3:主表on条件属性名
.innerJoin(Test.class, Test::getDemoId, Demo::getId)
//关联映射,和xml的resultMap一样,参数1:需要映射的实体类对象名
.oneToOneSelect(DemoVo2::getTestVo, cb -> {
//因为Demo和Test两个实体属性名一样,所以要取别名区分,参数1:表字段名,参数2:别名,参数3:实体属性名
cb.add(Test::getId, "test_id", TestVo::getTestId);
cb.add(Test::getName, "test_name", TestVo::getTestName);
//关联表属性名没有相同无需取别名赋值
cb.add(Test::getDemoId);
})
//和LambdaQueryWrapper一样可以拼装从表查询条件
//.eq(Test::getId, 2)
.end();
//调用关联查询
List<DemoVo2> demos = joinList(demoJoinLambdaWrapper, DemoVo2.class);
return demos;
}
实体对象相关
/**
* 连表结果实体
*/
@Data
public static class DemoVo extends Demo {
private List<TestVo> tests;
}
关联代码
public List<DemoVo> manyToMany() {
JoinLambdaWrapper<Demo> demoJoinLambdaWrapper = new JoinLambdaWrapper<>(Demo.class)
//和LambdaQueryWrapper一样可以指定主表需要查询的字段,默认全部
//.select(Demo::getId)
//.selectAll()
//和LambdaQueryWrapper一样可以拼装主表查询条件
//.eq(Demo::getId, 1)
//内联查询,参数1:需要关联的表对象class,参数2:从表on条件属性名,参数3:主表on条件属性名
.innerJoin(Test.class, Test::getDemoId, Demo::getId)
//关联映射,参数1:需要映射的实体类集合对象名,参数2:实体类集合泛型class
.manyToManySelect(DemoVo::getTests, TestVo.class, cb -> {
//因为Demo和Test两个实体属性名一样,所以要取别名区分,参数1:表字段名,参数2:别名,参数3:实体属性名
cb.add(Test::getId, "test_id", TestVo::getTestId);
cb.add(Test::getName, "test_name", TestVo::getTestName);
//关联表属性名没有相同无需取别名赋值
cb.add(Test::getDemoId);
})
//和LambdaQueryWrapper一样可以拼装从表查询条件
//.eq(Test::getId, 2)
.end();
//调用关联查询
List<DemoVo> demos = joinList(demoJoinLambdaWrapper, DemoVo.class);
return demos;
}
使用实体匹配条件生成LambdaQueryWrapper对象或JoinLambdaWrapper对象,区别于LambdaQueryWrapper构造函数的实体查询匹配,它不支持自定义入参对象,且对实体对象注解侵入,而且不灵活,无法做到既给了构造对象又自定义规则,所以封装了该类。
方法列表:
注:以下所有方法均为对象属性的默认条件匹配方式,即入参对象属性不为空并且未指定特定的匹配方式才会拼入查询条件
queryWrapper() 默认使用eq
eqWrapper() 默认使用eq
ltWrapper() 默认使用lt
gtWrapper() 默认使用gt
leWrapper() 默认使用le
geWrapper() 默认使用ge
likeWrapper() 默认使用like
neWrapper() 默认使用ne
inWrapper() 默认使用in
notInWrapper() 默认使用notIn
运算符方法列表:
eq() =
lt() <
gt() >
le() <=
ge() >=
like() 模糊
ne() 不等于
in() 范围内
notIn() 范围外
asc() 排序,正序
desc() 排序,倒序
举例1:
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
//默认使用eq进行匹配 id=匹配,name模糊匹配,age<=匹配
LambdaQueryWrapper eqQuery = new JMybatisPlusQuery ().queryWrapper(demo)
//name使用 模糊 匹配
.like(Demo::getName)
//age使用 <= 匹配
.le(Demo::getAge)
.build();
//默认使用like进行匹配 name模糊匹配,id=匹配,age<=匹配
LambdaQueryWrapper likeQuery = new JMybatisPlusQuery ().likeWrapper(demo)
//id使用 = 匹配
.eq(Demo::getId)
//age使用 <= 匹配
.le(Demo::getAge)
.build();
......
}
/**
* 数据库实体类
*/
@Data
@Accessors(chain = true)
public static class Demo {
private String id;
private String name;
private Integer age;
}
}
举例2:
public class Test {
public static void main(String[] args) {
DemoDto demoDto = new DemoDto();
//默认使用eq进行匹配 id=匹配,name模糊匹配,age<=匹配
LambdaQueryWrapper eqQuery = new JMybatisPlusQuery ().queryWrapper(demoDto, Demo.class)
//name使用 模糊 匹配
.like(Demo::getName)
//age使用 <= 匹配
.le(Demo::getAge)
.build();
//默认使用like进行匹配 name模糊匹配,id=匹配,age<=匹配
LambdaQueryWrapper likeQuery = new JMybatisPlusQuery ().likeWrapper(demoDto, Demo.class)
//id使用 = 匹配
.eq(Demo::getId)
//age使用 <= 匹配
.le(Demo::getAge)
.build();
......
}
/**
* 入参类
*/
@Data
@Accessors(chain = true)
public static class DemoDto {
private String id;
private String name;
private Integer age;
}
/**
* 数据库实体类
*/
@Data
@Accessors(chain = true)
public static class Demo {
private String id;
private String name;
private Integer age;
}
}
mybatis-plus代码生成器,封装了过程,只需要简单操作一个对象即可生成代码,使用更方便,例子:
public class Test {
public static void main(String[] args) {
//仅支持mysql
JMybatisGenerator.Generator.builder()
.author("lijin") //作者
.username("root") //账号
.password("root") //密码
.url("127.0.0.1:3306/test") //连接
//.clasz(Test.class) //文件生成的位置(不能跨模块),默认为运行类(main方法)的同级
//.tablePrefix("t_") //剔除表名前缀
//.baseEntity(DemoBaseEntity.class) //实体父类
//.baseEntityPropertys(new String[]{"add_time"}) //写于实体父类的表列,注意:"是表列名"
.build()
.create(); //开始生成代码
}
}
代码会生成在main方法执行类的同一层。
同步阻塞更新数值,手写xml硬编码繁琐且不便于维护,用plus先查再修改则会遇到数值被其他事物更改的窘境,所以增加了该类,实现同步阻塞更新数值表列:
注:实体类需要有@TableName注解,实体类属性需要驼峰命名,表名及列名需要下横线命名
举例:
public class Test {
@Autowired
private JSyncUpdate syncUpdate;
public void test() {
//等同于sql:update burse set money = money + 1,integral = integral - 1 where user_id = 1 and money + 1 > 0 and integral - 1 > 0
boolean exec = syncUpdate.update(Burse.class)
.set(Burse::getMoney, new BigDecimal(1))
.set(Burse::getIntegral, new BigDecimal(-1))
.eq(Burse::getUserId, 1)
.exec();
}
/**
* 钱包实体
*/
@Data
@TableName("burse")
public static class Burse {
private Integer id;
private Integer userId;
private BigDecimal money;
private BigDecimal integral;
}
}
为了在没有mybatisplus依赖的模块使用IPage,照抄的一个自定义分页对象,可以和IPage互转。
api如下:
例子:
@Data
@Accessors(chain = true)
public static class DemoVo extends Demo {
}
@Data
@Accessors(chain = true)
public static class DemoVo2 {
private String id;
private String name;
private Integer age;
}
@Data
@Accessors(chain = true)
public static class Demo {
private String id;
private String name;
private Integer age;
}
public static void main(String[] args) {
//拷贝
IPage<Demo> page;
IPage<DemoVo> iPage1 = JPlusBean.copy(DemoVo.class, page);
IPage<DemoVo2> iPage2 = JPlusBean.copy(DemoVo2.class, page);
//JPageBean转IPage
JPageBean<Demo> pageBean;
IPage<Demo> page2 = JPlusBean.toIPage(pageBean);
//IPage转JPageBean
JPageBean<Demo> pageBean2 = JPlusBean.toJPageBean(page);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。