概述:其实就是简化模型类的编写:
坐标:
org.projectlombok lomboktrue
主要的注解(都是模型类注解):
@Data 生成 get 和 set 以及 toString,equale 等基础的方法完整的 javabean @Getter 生成单独的 get 方法 @Setter 解释同上 @ToString @EqualsAndHashCode @AllArgsConstructor 生成全部参数的构造方法 @NoArgsConstructor 生成无参的构造方法 @Build 链式编程 链式编程示例:public void method() {
// Perrsion perrsion = new Perrsion();
//链式编程示例
Perrsion zhangsan =
Perrsion.builder().age(22).name("zhangsan").id(1111L).build();
System.out.println(zhangsan);
}
链式编程的使用格式 类名.builder().属性(值)...bulid();
就是个小工具,就这样拉! !!!!
二 MP基本信息:
概述:是对mybati使用的简化,详细信息:简介 | MyBatis-Plus
坐标:
三 mp的注解: @TableName(“具体的数据库表名”) //用于类上,注明映射类,若是数据库中的表名和实体 类名相同,则忽略不写,写上最好 表前缀在配置文件中配置格式:com.baomidou mybatis-plus-boot-starter3.4.0
# 表前缀,根据情况填写 mybatis-plus.global-config.db-config.table-prefix=tb_@TableId(指明 id 规则) //实体类属性上,标明主键用,可以在配置文件中设置 配置文件中的配置方式
mybatis-plus.global-config.db-config.id-type = auto@TableField(“数据库表中字段”) //用于数据库表中字段和实体类中的变量名不相同 @TableField(fill=FieldFill.INSERT) //实体类中变量上,用于完成自动添加插入,但是得配合自己重写的 handler @TableField(fill=FieldFill.INSERT_UPDATe) //变量名上,更新时完成自动添加,这块主要用于完成一定的修改和更新上 @TableField(exit=false) //用于忽略该变量,不用将该变量映射到数据 库中 配合以上注解可以使得数据库表和模型类的直接映射: 示例(已经做了详细说明):
@Data
// @Getter
// @Setter
// @ToString
// @EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Builder //链式编程
//mybatisplus 表映射注解
@TableName("tb_user")
//指定表名 建立模型类和表之间的映射,若是表名和类名相同则不写(驼峰命名也是相同),
//注意:若是在配置文件中设置了 tb 延展,user 要是和表名相同,则不用注解
public class Persion implements Serializable {
private static final long serialVersionUID = 8683452581122892189L;
@TableId(type = IdType.AUTO) //主键自增
private Long id;
@TableField(value = "username")
//自动映射表中的 user_name,若是表中的字段名和实体类的字段名相同在,则忽略不写
private String name;
private Integer age;
@TableField(fill = FieldFill.INSERT)//在数据添加时自动补充映射到数据库中的表中
private Date createdate;
//@ TableField(fill =FieldFill.UPDATE)//在数据进行更新时会自动添加到数据库中
@TableField(fill = FieldFill.INSERT_UPDATE)//更新和添加都会填入数据库中的表中
private Date updatedate;
@TableField(exist = false)//忽略这个字段的插入和查询,不希望该值存入数据库
private String ts;
private Sex sex;}
这块要注意数据库中的字段名字和数据类型和模型类的数据类型以及字段的相同:
1 注意数据类型的匹配 Date 类型对应数据库中的 datetime 类型,数据类型不匹 无法完成映射 2 注意在数据库中的字段名为 createdate,则在实体类中对应的字段只能是 createdate(当然也可以通过注解绑定), 但是实体类中的子命名不为 createDate,因为 createDate 对应数据库表中的数据类型 只能是 create_date,从而造成无定法完,handler 中的配置属性名也是一样 四 mp的枚举:就是对一些常用的数据做的封装
使用mp的枚举格式必须进行枚举包的扫描配置
#具体的枚举类所在的包,在SpringBoot的配置文件中的配置 mybatis-plus.type-enums-package = com.nanfeng.nan.mybatisplus.enums
格式:
public enum 枚举类名字 implements IEnum{} //实现 mybatisplus,对一些常用的 不变的值的使用 示例(用到参考格式修改即可):public enum Sex implements IEnum五 mp的mapper文件: 在使用 mybatisplus 时 mapper 接口无需我们自己 写,继承 mybatisplus 提供的父 类 baseMapper{ 男(1, "男"), 女(2, "女"); private Integer code; private String doc; Sex(Integer code, String doc) { this.code = code; this.doc = doc; } @Override public Integer getValue() { return this.code; } @Override public String toString() { return this.doc; }}
@Mapper //这块不标注,就需要引导类进行 mapper 的扫描 public interface PersionMapper extends baseMapper{ }
六 mp的Service:
用不用这个Service看我们自己,若是我们不需要在Service中做业务处理,只是中转调用,直接使用mp提供的即可,否则我们自己写Service做相关的业务处理,mp的Service实现:
1 定义接口继承IService
2 定义实现类继承ServiceImpl
示例:
接口:
public interface PersionService extends IService{ }
实现类:
@Service public class PersionServiceImp extends ServiceImpl七 mybatisplus 的拦截器:implements PersionService { }
在使用 mybatisplus 的分页查询时必须配置拦截器, 否则无法实现分页的拦截:
直接粘贴,谁写都一样,没有任何的技术含量:
@Configuration
public class PageConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
关于分页查询,下面做方法调用时候解释
八 mybaisplus 的 handler mybatisplus 的 handler 主要用于自动插入,即配@TaleField(fill=INSERT_UPDATE ) 使用,就是呗该注解标注的变量在映射进数据库的时候会完成对该变量做自动的后置操作示例:
@Component
public class MymetaObjectHandler implements metaObjectHandler {
@Override
public void insertFill(metaObject metaObject) {
//根据 getFieldValByName 方法将 mataObject 对象(其实就是一个个使用@TableField注解标注的属性的集合),指定属性检测赋值请款
Object created = getFieldValByName("createdate", metaObject);
//如果 created 字段为空进行自动填充.(如果不为空,忽略)
if (null == created) {
//为该属性赋值设置自动填充数据
setFieldValByName("createdate", new Date(), metaObject);
}
Object updated = getFieldValByName("updatedate", metaObject);
//如果 update 字段为空进行自动填充.(如果不为空,忽略)
if (null == created) {
//为该属性赋值设置自动填充数据
setFieldValByName("updatedate", new Date(), metaObject);
}
}
@Override
public void updateFill(metaObject metaObject) {
//只要改属性有变动就自动实现
setUpdateFieldValByName("updatedate", new Date(), metaObject);
strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
fillStrategy(metaObject, "updateTime", LocalDateTime.now());
}
}
十 mapper的常用方法:
没啥好说的,直接看例子吧!
@SpringBootTest
@RunWith(SpringRunner.class)
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
@Test
public void testInsert() {
User user = new User();
//user.setId(6L);
user.setUserName("zahnsgan");
user.setPassword("root123");
int count = userMapper.insert(user);
System.out.println(count);
}
@Test
public void testDelete() {
//3. 根据 map 构造条件,删除
Map map = new HashMap<>();
//delete from tb_user where user_name = ? and age = ?
map.put("user_name","zhangsan");
map.put("age","18");
userMapper.deleteByMap(map);} }
@Test
public void testUpdateById() {
User user = new User();
user.setId(2L);
user.setPassword("1111111");
int count = userMapper.updateById(user);
}
@Test
public void testSelectPage() {
int current = 1;//当前页码
int size = 2;//每页显示条数
IPage page = new Page(current,size);
userMapper.selectPage(page,null);
List records = page.getRecords();//当前页的数据
long pages = page.getPages();//总页数 2
long total = page.getTotal();//总记录数 4
System.out.println(records);
System.out.println(pages);
System.out.println(total);
}
}
条件构造器:
基本的运算符号和对应的方法:
eq( ) : 等于 =
ne( ) : 不等于 <>
gt( ) : 大于 >
ge( ) : 大于等于 >=
lt( ) : 小于 <
le( ) : 小于等于 <=
between ( ) : BETWEEN 值1 AND 值2
notBetween ( ) : NOT BETWEEN 值1 AND 值2
in( ) : in
notIn( ) :not in
条件构造器查询
@SpringBootTest
@RunWith(SpringRunner.class)
public class WrapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testWrapper1() {
//1.创建查询条件构建器
QueryWrapper wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.lt("age", 23)
.in("name", "李四", "王五");
List users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper2() {
//1.创建查询条件构建器
QueryWrapper wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五");
List users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper3() {
//1.创建查询条件构建器
QueryWrapper wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.likeLeft("user_name", "zhang");
List users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper4() {
//1.创建查询条件构建器
QueryWrapper wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五")
//.orderBy(true,true,"age")
.orderByDesc("age"); //倒序查询.顺序为 asc
List users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper5() {
//1.创建查询条件构建器
QueryWrapper wrapper = new QueryWrapper<>();
//2.设置条件
wrapper.eq("user_name", "lisi")
.or()
.lt("age", 23)
.in("name", "李四", "王五")
//.orderBy(true,true,"age")
.orderByDesc("age")
.select("id", "user_name");
List users = userMapper.selectList(wrapper);
System.out.println(users);
}
@Test
public void testWrapper6() {
int current = 1;//当前页码
int size = 2;//每页显示条数
//1. 构建分页对象
Page page = new Page<>(current, size);
//2. 构建条件对象
QueryWrapper wrapper = new QueryWrapper();
wrapper.lt("age", 23);
userMapper.selectPage(page, wrapper);
List records = page.getRecords();
long total = page.getTotal();
long pages = page.getPages();
System.out.println(records);
System.out.println(total);//2
System.out.println(pages);//1
}
@Test
public void testWrapper7() {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUserName, "zhangsan");
User user = userMapper.selectOne(wrapper);
}
@Test
public void testWrapper8() {
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("user_name", "bbb");
userMapper.delete(wrapper);
}
@Test
public void testWrapper9() {
UpdateWrapper wrapper = new UpdateWrapper<>();
//条件
wrapper.eq("user_name", "lisi")
.set("password", "22222");
//update tb_user set password = ? where user_name = ?
userMapper.update(null, wrapper);
}
@Test
public void testWrapper10() {
UpdateWrapper wrapper = new UpdateWrapper<>();
//条件
wrapper.eq("user_name", "lisi");
//update tb_user set password = ?,age = ? where user_name = ?
User user = new User();
user.setPassword("3333");
user.setAge(33);
userMapper.update(user, wrapper);
}
}
mp实现的修改只是将指定的字段做了修改,原来没有指定的字段还是原来数据,并不是null
需要注意的是修改条件构造器和lam格式的条件构造器,大致上增删改查就这样完成了!!!
十一 面对多表的联查增删改查使用mp的思路:方式一:
在mapper中添加自己的方法即可:
示例:
public interface UserMapper extends baseMapper{ @Select("select name, age from tb1,tb2 where id=1") public User selectManyTable(); }
方式二:
持久层进行单表查询,业务层实现pojo的数据重组
十二 配置文件:plication.properties # datasource spring.datasource.url = jdbc:mysql://47.119.137.8:3306/mytest spring.datasource.password = root spring.datasource.username = root spring.datasource.driver-class-name = com.mysql.jdbc.Driver # myatisplus 配置 # 表前缀,根据情况填写 #mybatis-plus.global-config.db-config.table-prefix= # id 策略 mybatis-plus.global-config.db-config.id-type = auto # 日志,查看生成的 sql 语句 mybatis-plus.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl # 枚举包的扫描(该枚举完成对一些不变数据的赋值) mybatis-plus.type-enums-package = com.nanfeng.nan.mybatisplus.enums
使用mp注意事项:
(1)实体类的变量名和数据库中的表的字段名 数据库 username --> 实体类 username -->错误 userName 数据库 user_name --> 实体类 userName -->错误 username 一定注意映射时字段和变量的名字对应,若是不对应,不对应时注解标注 (2) 设置自动添加熟悉时需要重写 handler,再 handler 中做数据处理(格在上面文档) (3) 在使用 mybatisplus 的分页查询时需要设置拦截器(配置方法在上面文档 基本上就这样了,啦啦啦去啦啦啦啦啦啦啦..................................................完事!!!!, 关于代码生成器,其实就是执行指定代码,生成模板,这个就算了,打死也不想用,太麻烦,自己动手,我觉得更简单 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


