测试办法
public class SpringBootStartTests {
@Autowired
private UserMapper userMapper;
@Test
public void test() {
List<UserBean> userBeans = userMapper.selectList(null);
System.out.println(userBeans);
}
@Test
public void insert() {
UserBean userBean = new UserBean();
userBean.setAge(11);
userBean.setName("老王0");
userBean.setEmail("6362@qq.com");
int insert = userMapper.insert(userBean);
System.out.println("insert=" + insert);
}
@Test
public void updateUser() {
UserBean userBean = new UserBean();
userBean.setAge(112);
userBean.setId(5L);
userBean.setEmail("6362111@qq.com");
int insert = userMapper.updateById(userBean);
System.out.println("insert=" + insert);
}
//测试乐观锁
@Test
public void OptimisticLock() {
//先查询
UserBean userBean = userMapper.selectById(1609472201189371906L);
userBean.setName("OptimisticLock");
//在更新
int byId = userMapper.updateById(userBean);
}
//通过ID查询
@Test
public void testSelectById() {
UserBean userBean = userMapper.selectById(1L);
System.out.println(userBean);
}
//通过批量ID查询
@Test
public void testSelectByIds() {
List<UserBean> userBeans = userMapper.selectBatchIds(Arrays.asList(1609472201189371906L, 2L, 5L));
//SELECT id,age,name,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? , ? )
System.out.println(userBeans);
}
//通过Map条件查询 得到的是一个集合
@Test
public void testSelectByMap() {
HashMap<String, Object> HashMap = new HashMap<>();
HashMap.put("age","11");
List<UserBean> userBeans = userMapper.selectByMap(HashMap);
System.out.println(userBeans);
}
//分页查询
@Test
public void testSelectPage() {
// 1、创建Page对象
// 2、传入两个参数 第一个参数:current:1 当前页是1 size:3 返回一页的记录数是三条 也就是一页只有三行记录
Page<UserBean> page = new Page<>(1,3);
//Page<T> var1 Page对象, Wrapper<T> var2 查询条件构造器对象
//这里注意 Mp底层将查询到的数据封装到page对象中
userMapper.selectPage(page, null);
System.out.println("getCurrent当前页数"+page.getCurrent());
System.out.println("getRecords查询数据列表"+page.getRecords());//每页数据list集合
System.out.println("getTotal查询列表总记录数(数据库该表总记录数)"+page.getTotal());
System.out.println("getSize一页有多少行(记录数)"+page.getSize());
System.out.println("查询总共有多少页数"+page.getPages());
System.out.println("当前页数"+page.getCurrent());
System.out.println("下一页"+page.hasNext()); //下一页
System.out.println("上一页"+page.hasPrevious()); //上一页
}
//物理(Physics)删除
@Test
public void deletePhysicsDate() {
int i = userMapper.deleteById(0L);
System.out.println("影响行数"+i);
}
//逻辑(logic)删除
@Test
public void deletelogicDate() {
int i = userMapper.deleteById(1L);
System.out.println("影响行数"+i);
}
//复杂的条件查询
@Test
public void testSelectQuery() {
QueryWrapper<UserBean> queryWrapper = new QueryWrapper<>();
//1、ge(>=)、gt(>)、le(<=)、lt(<)、isNull、isNotNull
// queryWrapper.ge("age","15");
//2、eq(=)、ne(!=)
// queryWrapper.ne("age","11");
//selectOne-》如果出现多条记录就会Expected one result (or null) to be returned by selectOne(), but found: 5
//意思就是只要一条记录 但是找到的结果出现多条记录 就会报错
// UserBean userBean = userMapper.selectOne(queryWrapper);
//3、between、notBetween 包含大小边界
//queryWrapper.notBetween("age","11","25");
//语句:SELECT id,age,name,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND age BETWEEN ? AND ?
//语句:SELECT id,age,name,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND age NOT BETWEEN ? AND ?
// 4、allEq
Map<String, Object> map = new HashMap<>();
map.put("id", 2);
map.put("name", "Jack");
map.put("age", 20);
queryWrapper.allEq(map);
//语句:SELECT id,age,name,email,create_time,update_time,version,deleted FROM user WHERE deleted=0 AND name = ? AND id = ? AND age = ?
List<UserBean> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
//5、like、notLike、likeLeft、likeRight
queryWrapper
.notLike("name", "e")
.likeRight("email", "t");
//6、in、notIn、inSql、notinSql、exists、notExists
queryWrapper.inSql("id", "select id from user where id < 3");
// 语句:SELECT id,name,age,email,create_time,update_time,deleted,version
//FROM user WHERE deleted=0 AND id IN (select id from user where id < 3)
// 7、or、and
// 注意:这里使用的是 UpdateWrapper
//修改值
//修改条件
UpdateWrapper<UserBean> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "h")
.or()
.between("age", 20, 30);
int result = userMapper.update(new UserBean(), userUpdateWrapper);
System.out.println(result);
// 8、嵌套or、嵌套and
// 这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号
//修改值
UserBean user = new UserBean();
user.setAge(99);
user.setName("Andy");
//修改条件
UpdateWrapper<UserBean> userUpdateWrapperr = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "h")
.or(i -> i.eq("name", "李白").ne("age", 20));
int results = userMapper.update(user, userUpdateWrapper);
// 语句:UPDATE user SET name=?, age=?, update_time=?
// WHERE deleted=0 AND name LIKE ?
// OR ( name = ? AND age <> ? )
//9、orderBy、orderByDesc、orderByAsc
// queryWrapper.orderByDesc("id");
//语句:SELECT id,name,age,email,create_time,update_time,deleted,version
//FROM user WHERE deleted=0 ORDER BY id DESC
}
// 10、last
// 直接拼接到 sql 的最后
// 注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
@Test
public void testSelectListLast() {
QueryWrapper<UserBean> queryWrapper = new QueryWrapper<>();
queryWrapper.last("limit 1");
List<UserBean> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
// 语句:SELECT id,name,age,email,create_time,update_time,deleted,version
// FROM user WHERE deleted=0 limit 1
// 11、指定要查询的列
// queryWrapper.select("id", "name", "age");
// 语句:SELECT id,name,age FROM user WHERE deleted=0
// 12、set、setSql
// 最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段
@Test
public void testUpdateSet() {
//修改值
UserBean user = new UserBean();
user.setAge(99);
//修改条件
UpdateWrapper<UserBean> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "h")
.set("name", "老李头")//除了可以查询还可以使用set设置修改的字段
.setSql(" email = '123@qq.com'");//可以有子查询
int result = userMapper.update(user, userUpdateWrapper);
}
// 语句: UPDATE user SET age=?, update_time=?, name=?, email = '123@qq.com' WHERE deleted=0 AND name LIKE ?
}
自动填充
//不要忘记添加 @Component 注解 加了spring才会托管
@Component
public class userMetaObjectHandler implements MetaObjectHandler {
private static final Logger logger = LoggerFactory.getLogger(userMetaObjectHandler.class);
@Override
public void insertFill(MetaObject metaObject) {
logger.debug("insertFill");
this.setFieldValByName("version",1,metaObject);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("deleted", 0, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
logger.debug("updateFill");
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
配置类
@Configuration //告诉springBoot这个是配置类 也就是将所有的配置都弄到这个类中
@MapperScan("com.mp.mapper") //扫描映射的文件所在的包 若无则无法找到相关映射文件
public class MybatisPlusConfig {
/** 当然这个插件弄到启动类中也可以 不过建议都放在配置类中
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//逻辑删除插件
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
/**
* SQL 执行性能分析插件
* 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
* Spring Boot 中设置dev环境
* #环境设置:dev、test、prod
* spring.profiles.active=dev
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启 必须在配置文件设置该项目是什么环境 spring.profiles.active=dev
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
//参数:format: SQL是否格式化,默认false。
performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行 会报错
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
}
JavaBean
@Data //包装了属性的get set hashCode equals tostring
@TableName("user")
public class UserBean {
/*
* 主键策略
* 1、自增模式,
* 数据库分表时候,需要知道上一张表的最后记录的ID,才能让新表的ID加1,明显有点缺陷
* 2、UUID,生成全球唯一的值,缺点就是不利于排序,长
* 3、Redis生成ID:
* 当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,
所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis。
* 可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。各个Redis生成的ID为:
*4、利用MP自带的主键策略,生成一个19位的值作为主键
* */
/*
要想主键自增需要配置如下主键策略
需要在创建数据表的时候设置主键自增
实体字段中配置 @TableId(type = IdType.AUTO)
*/
/* IdType有六种类型
* AUTO(0),自动增长
NONE(1),无策略
INPUT(2),输入型 自己输入啥就是啥
ID_WORKER(3), MP自带策略(当主键类型是数字型用这个 字符型用下面那个)
UUID(4),
ID_WORKER_STR(5);MP自带策略(当主键类型是字符型用这个 数字型用上面那个)
*
* */
@TableId(type = IdType.ID_WORKER)
private Long id;
private int age;
private String name;
private String email;
/* 自动填充
* 项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:
*步骤:
* 1、增加属性 @TableField(fill=FieldFill.INSERT)
@TableField(fill = FieldFill.INSERT_UPDATE)
* 2、自定义一个类实现接口 MetaObjectHandler
* */
//数据库是 create_time java代码一般是createTime 驼峰式
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//数据库是 update_time java代码一般是updateTime 驼峰式
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@Version //告诉springBoot这个乐观锁需要的版本号
@TableField(fill =FieldFill.INSERT ) //就是当插入数据时 将自动填充赋值version的值为1 如果不弄version的值就会为null 我们就需要手动赋值为1
private Integer version;
@TableField(fill = FieldFill.INSERT)
@TableLogic //告诉Mp 这个是逻辑删除的字段名
private Integer deleted;
}
映射的类
/*
* 扫描项目中的Dao层,将dao接口类注入到Spring,能够让其他类进行引用;
@Mapper:在dao接口类中,添加此注解;麻烦的在于,每个dao接口类都必须添加此注解;
@MapperScan:可以指定要扫描的dao接口类的路径,可以在启动类中添加此注解,
* 可替代@Mapper注解(此模块内dao接口类不用都添加@Mapper注解)
扫描一个包
@MapperScan("com.demo.mapper"):扫描指定包中的接口
@MapperScan("com.demo.*.mapper"):一个 * 代表一级包;比如可以扫到com.demo.aaa.mapper,
* 不能扫到com.demo.aaa.bbb.mapper
@MapperScan("com.demo.**.mapper"):两个 * 代表任意个包;比如可以扫到com.demo.aaa.mapper,
* 也可以扫到com.demo.aaa.bbb.mapper
*
* @MapperScan({"com.kfit.demo","com.kfit.user"})
* */
@Repository
//@Mapper
public interface UserMapper extends BaseMapper<UserBean> {
}
配置属性
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=8438031100
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#此为默认值,如果你的默认值和mp默认的一样,该配置可无
#当逻辑删除属性值1是代表已经删除(数据存在用户不可看)
mybatis-plus.global-config.db-config.logic-delete-value=1
#当逻辑删除属性值0是代表未删除(数据存在用户可看)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
#环境设置:dev(开发)、test(测试)、prod(生产) 设置该项目的环境是开发环境
spring.profiles.active=dev
版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!
常见资源合集和破解beqptwpmc...