当前位置: 首页 > news >正文

广元网站建设seo优化营销制作设计windows优化大师官方

广元网站建设seo优化营销制作设计,windows优化大师官方,wordpress 用户组权限,网站建设报价明细单MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法:update乐观锁select查所有根据id查多个id批量查询简单条件查询(通…

简介

MyBatis-Plus是MyBatis的增强工具,在MyBatis的基础上做出增强改变,简化开发,提高效率

mybatis-plus的官网链接

特性

mybatis-plus官网的特性详解

快速开始

第一步:创建一张表

CREATE TABLE user
(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id)
);

第二步:插入对应数据

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

第三步:初始化一个项目工程

在这里插入图片描述

第四步:引入依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0+ 版本</version><relativePath/>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>最新版本</version></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>
</dependencies>

第五步:配置数据库连接信息

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=root

第五步:在SpringBoot项目的启动类中添加**@MapperScan注解**,用于对mapper的扫描

package com.example.mpdemo001;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.example.mpdemo001.mapper")
public class Mpdemo001Application {public static void main(String[] args) {SpringApplication.run(Mpdemo001Application.class, args);}}

第六步:编码

实体类:

package com.example.mpdemo001.bean;import lombok.Data;/*** @Title: User* @Package com.example.mpdemo001.bean* @Author: CXY* @Copyright CXY* @CreateTime: 2023/3/9 12:35*/
@Data
public class User {private Long id;private String name;private Integer age;private String email;
}

mapper接口(MyBatis-Plus不需要在接口中写很多方法,只需要继承 BaseMapper< T>即可,T表示泛型

package com.example.mpdemo001.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo001.bean.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {
}

**注意:**在mapper接口上面需要添加一个@Mapper的注解,用于将Mapper接口加入Spring管理

第七步:测试

package com.example.mpdemo001;import com.example.mpdemo001.bean.User;
import com.example.mpdemo001.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
public class Mpdemo001ApplicationTests {@Autowiredprivate UserMapper userMapper;@Testpublic void contextLoads() {List<User> users = userMapper.selectList(null);for (User user:users) {System.out.println(user);}}}

UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件

测试结果:

User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)

可以配置MyBatis-Plus的日志文件,这样可以看到详细的SQL语句实现过程

日志文件的配置如下:

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

MyBatis-Plus的注解详解

@Tableld

IdType:顾名思义即表示主键的类型

主键生成策略

参考资料:分布式系统唯一ID生成方案汇总:https://www.cnblogs.com/haoxinyue/p/5208136.htm

1、数据库自动增长 AUTO

这个是指在建表的时候可以直接设置id自增,这样的话idType即为AUTO;

**缺点:**这样id自增的主键,不利于数据库的分表实现,因为id是按顺序递增的,所以每一次分表的时候都需要知道前一张表的最后一个id的值,再那个基础上进行id加一的操作

2、UUID

每次生成随机唯一的值

**优点:**每次分表的时候不需要知道上一张表的最后一个元素的id值

**缺点:**id无法进行排序

3、Redis生成id

Redis是单线程的,所以也可以用来生成全局唯一的id,可以用Redis的原子操作INCRINCRBY来实现

但是使用这个来进行id生成的时候,需要指定初始值和步长

使用Redis集群可以防止单点故障的问题

单点故障:(英语:single point of failure,缩写SPOF)是指系统中一点失效,就会让整个系统无法运作的部件,换句话说,单点故障即会整体故障。

**优点:**不依赖于数据库,灵活方便,且性能优于数据库,数字id天然排序,对分页或者需要排序的结果很有帮助

**缺点:**如果系统中没有Redis,还需引入新的主键,增加系统的复杂度;需要编码和配置的工作量比较大

4、MP主键自动生成

mp可以通过雪花算法自动生成一个19位数字的id,

@TableName

  • 描述:表名注解,标识实体类对应的表
  • 使用位置:实体类

在这里插入图片描述

@TableField

  • 描述:字段注解(非主键)

自动填充

将数据自动填充进去

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。 我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作

具体实现过程:

在实体类中需要自动进行自动填充的对象上面添加注解:**@TableField(fill=FieldFill.Xxx)**FieldFill的取值:

在这里插入图片描述

然后创建一个类用于实现MetaObjectHandler接口,实现接口中的方法,

注意:需要在这个类上面添加注解,让Spring进行管理

package com.example.mpdemo001.bean;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;import java.util.Date;/*** @Title: MyBatisMeta* @Package com.example.mpdemo001.bean* @Author: CXY* @Copyright CXY* @CreateTime: 2023/3/10 14:02*/
@Component
//这个不能忘,忘了就无法进行了
public class MyBatisMeta implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {//插入时间,第一次创建的时候,需要插入创建时间和更新时间this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {//每一次更新数据的时候,插入时间this.setFieldValByName("updateTime",new Date(),metaObject);}
}

测试结果:

在这里插入图片描述

测试方法:

update

@Test
public void testUpdateById(){User user=new User();user.setId(1L);user.setName("战三");int i = userMapper.updateById(user);System.out.println(i);}

结果:
在这里插入图片描述

注意:update生成的是动态sql

乐观锁

针对一种特定问题的解决方案,主要解决的是丢失更新的问题

主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数 据更新

如果不考虑事务的隔离性的话,会产生的问题有:

1、产生读问题:脏读,不可重复读,幻读

2、产生写问题:丢失更新(就是指多个人同时修改同一条数据,最后提交的把之前提交的数据覆盖了

解决丢失更新问题:

悲观锁:串行,只有一个人能在当前情况下进行操作

乐观锁:添加了一个version版本号,当一个人在进行数据操作的时候,提交数据时会比较当前数据版本号和数据库中的版本号是否一直,如果一致则可以进行修改,修改后版本号进行加一的操作。反之不能进行修改。

**乐观锁的使用例子有:**12306抢票系统,当别人把最后一张票抢走之后,另外的人就不能再进行抢票了

乐观锁的使用流程:

  1. 取出记录时,获取当前version
  2. 更新时,带上这个version
  3. 执行更新时, set version = newVersion where version = oldVersion
  4. 如果version不对,就更新失败

当有很多配置的时候,建议新建一个配置类,将所有配置写在配置类中

package com.example.mpdemo001.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Title: MyBatisConfigurations* @Package com.example.mpdemo001.config* @Author: CXY* @Copyright CXY* @CreateTime: 2023/3/10 15:12*/
@Configuration
@MapperScan("com.example.mpdemo001.mapper")
public class MyBatisConfigurations {/*** 乐观锁插件** 新版*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}}

测试成功代码:

@Test
public void testOptimisticLockerFail() {User user = userMapper.selectById(1l);user.setName("死亡法师");user.setAge(10000);int i = userMapper.updateById(user);System.out.println(i);
}

测试成功的结果

在这里插入图片描述

测试失败代码:

@Test
public void testOptimisticLockerFail() {User user = userMapper.selectById(2l);user.setName("哈利波特");user.setAge(300);//模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了versionuser.setVersion(user.getVersion()-1);int i = userMapper.updateById(user);System.out.println(i);
}

结果:

在这里插入图片描述

select

查所有

@Test
public void testSelect(){List<User> users = userMapper.selectList(null);users.forEach(System.out::println);
}

结果
在这里插入图片描述

根据id查

在这里插入图片描述

多个id批量查询

在这里插入图片描述

简单条件查询(通过map封装条件)

在这里插入图片描述

注意:map中的key对应的是数据库中的列名。例如数据库user_id,实体类是userId,这时map的key需 要填写user_id

分页

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

添加插件:

/*** 分页插件(官网最新)*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor1() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;
}

测试分页实现:

@Test
public void testPageSelect(){Page page=new Page<>(1,3);userMapper.selectPage(page, null);page.getRecords().forEach(System.out::println);System.out.println(page.getCurrent());System.out.println(page.getPages());System.out.println(page.getSize());System.out.println(page.getTotal());System.out.println(page.getRecords());}

测试结果

在这里插入图片描述

分页的各个属性:

在这里插入图片描述

delete

根据id删除

@Test
public void testDeletedById(){int i = userMapper.deleteById(4l);System.out.println(i);
}

批量删除

@Test
public void testDeletedByIds(){int i = userMapper.deleteBatchIds(Arrays.asList(1, 2, 3));System.out.println(i);
}

简单的条件查询删除

@Test
public void testDeleteByMap(){HashMap<String,Object> hashMap=new HashMap<>();hashMap.put("name","Tom");hashMap.put("age",28);int i = userMapper.deleteByMap(hashMap);System.out.println(i);
}

逻辑删除

逻辑删除就是指在数据中多加一个标志属性,删除的时候只对该属性进行修改,而不是真正的删除数据,逻辑删除有利于数据的恢复

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍 旧能看到此条数据记录

在这里插入图片描述

在实体类上添加deleted属性

@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;

如果想修改默认属性值,则可在application.properties中进行配置

默认0表示未被删除,1表示被删除

在这里插入图片描述

在配置类中注册bean

@Bean
public ISqlInjector sqlInjector() {return new LogicSqlInjector();
}

高版本不用配置插件了,上述java代码无需编写。

测试删除:

@Test
public void testLogicDelete() {int result = userMapper.deleteById(1L);System.out.println(result);
}

在这里插入图片描述

被删除数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操做

性能分析

在配置类中添加性能优化插件

@Profile({“dev”,“test”})表示对什么环境起作用

dev:开发环境

test:测试环境

prod:生产环境,项目部署好之后的环境 最好不要在这里使用性能优化插件

环境配置在配置文件中设置:

spring.profile.active=xxx(dev,test,prod)

**参数:**maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。

**参数:**format: SQL是否格式化,默认false

Wrapper

在这里插入图片描述

  1. Wrapper : 条件构造抽象类,最顶端父类
  2. AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  3. QueryWrapper : Entity 对象封装操作类,不是用lambda语法(使用较多
  4. UpdateWrapper : Update 条件封装,用于Entity对象更新操作
  5. AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
  6. LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
  7. LambdaUpdateWrapper : Lambda 更新封装Wrapper

wrapper条件构造器测试

1、ge、gt、le、lt、isNull、isNotNull

@Test
public void testQueryWrapper(){QueryWrapper<User> queryWrapper=new QueryWrapper<>();queryWrapper.isNull("email").ge("age",30).isNotNull("name");//上面代码可以表示多个条件int delete = userMapper.delete(queryWrapper);System.out.println(delete);
}

gt:大于;ge:大于等于;le:小于;lt:小于等于

2、eq、ne

eq表示等于

ne表示不等于

@Test
public void testSelectOne() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "Tom");User user = userMapper.selectOne(queryWrapper);System.out.println(user);
}

注意:selectOne方法返回的是一条实体记录,如果返回多条时,会报错

3、between、notBetween

是包含边界值的查询条件

需要注意小值在前,大值在后

@Test
public void testSelectCount() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.between("age", 20, 30);Long count = userMapper.selectCount(queryWrapper);System.out.println("==============="+count);
}

4、allEq

多条件均相等

@Test
public void testSelectList() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();Map<String, Object> map = new HashMap<>();map.put("id", 2);map.put("name", "Jack");map.put("age", 20);queryWrapper.allEq(map);List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}

5、like、notLike、likeLeft、likeRight

like:模糊查询,表示like %内容%

notLike:不包含

likeLeft:表示like %内容

likeRight:表示 like 内容%

@Test
public void testQuerrySelectMaps() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.notLike("name","san").likeRight("email","test1");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);maps.forEach(System.out::println);}

6、in、notIn、inSql、notInSql、exists、notExists

in notIn用法如下:

notIn(“age”,{1,2,3})—>age not in (1,2,3)

notIn(“age”, 1, 2, 3)—>age not in (1,2,3)

inSql、notInSql可以实现子查询

@Testpublic void testSelectObjs() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//queryWrapper.in("id", 1, 2, 3);queryWrapper.inSql("id", "select id from user where id < 3");List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表objects.forEach(System.out::println);}

7、or、and

不调用or则默认为使用 and 连

8、嵌套or、嵌套and

这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号

 @Testpublic void testUpdate2() {
//修改值User user = new User();user.setAge(99);user.setName("Andy");
//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").or(i -> i.eq("name", "李白").ne("age", 20));
//        i -> i.eq("name", "李白").ne("age", 20)这一段是lambda表达式int result = userMapper.update(user, userUpdateWrapper);System.out.println(result);}

最后的sql语句为:

UPDATE user SET name=?, age=?, update_time=? WHERE deleted=0 AND name LIKE ?

OR ( name = ? AND age <> ?)

9、orderBy、orderByDesc、orderByAsc

**orderBy:**默认是升序

**orderByDesc:**表示升序排列,该方法可以有多个条件参与排列

**orderByAsc:**表示降序排列,该方法可以有多个条件参与排列

10、last

直接拼接到 sql 的最后

注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

@Test
public void testSelectListLast() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.last("limit 1");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);
}

sql语句:SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 limit 1

11、set、setSql

最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段

@Testpublic void testUpdateSet() {
//修改值User user = new User();user.setAge(99);
//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").set("name", "老李头")//除了可以查询还可以使用set设置修改的字段.setSql(" email = '123@qq.com'");//可以有子查询int result = userMapper.update(user, userUpdateWrapper);}

sql语句:

UPDATE user SET age=?, update_time=?, name=?, email = ‘123@qq.com’ WHERE deleted=0 AND name LIKE ?

b站教学视频:
尚硅谷

http://www.mmbaike.com/news/55489.html

相关文章:

  • 网络招商平台网站怎么做百度排行榜
  • 备案 网站建设计划书快手秒赞秒评网站推广
  • 做网站和做软件哪个赚钱百度一下你就知道主页
  • wordpress timthumb.phpseo上海网站推广
  • 网站建设在哪里申请如何做企业产品推广
  • wordpress大学 加载慢百度竞价和优化的区别
  • 网络营销论文选题方向seo宣传网站
  • 昭通网站seo优化合肥seo管理
  • 东莞佳诚网站建设有限公司汽车网站建设方案
  • 为什么网站只能显示ip地址_不能显示域名 wordpress夫唯seo
  • 郑州网站建设创新网络网站建设公司企业网站
  • 网络网站开发设计网站内容管理系统
  • php 上传网站seo排名优化代理
  • 静态网站中怎么做图片切换搜索引擎营销的特点
  • 如何看一个网站是谁做的网站seo技术
  • 如何做网站滚动条seo关键词快速排名
  • 在线咨询网站开发价格金戈枸橼酸西地那非片
  • 做ppt好用的网站河南网站开发公司
  • 北京医疗网站建设新网seo关键词优化教程
  • 辅料企业网站建设费用武汉网站排名提升
  • 深圳微商城网站制作百度产品优化排名软件
  • 站点建错了网页能打开吗看网站搜索什么关键词
  • 深圳产品外观设计公司百度seo优化服务项目
  • 怎么样提高网站排名网站优化外包找谁
  • 网站名称查询西安网站快速排名提升
  • 吉林市建设工程档案馆网站甘肃网站推广
  • wordpress百度搜索快速整站排名seo教程
  • 中国域名根服务器seo排名软件
  • 一个人可以建设网站吗深圳外贸网络推广渠道
  • 网站精品案例广告公司网站制作