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

SpringBoot - MyBatis-Plus使用详解(一)

1,什么是 MyBatis-Plus?

(1)MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。我们可以理解为它已经封装好了一些 CRUD 方法,我们不需要再写 xml 了,直接调用这些方法就行,类似于 JPA。

  • 官网地址:https://mp.baomidou.com/
  • GitHub 主页:https://github.com/baomidou/mybatis-plus

(2)MyBatis-Plus 框架结构如下

在这里插入图片描述

2,MyBatis-Plus 的功能特点

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

3,支持数据库

  • mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver
  • 达梦数据库 、 虚谷数据库 、 人大金仓数据库

4,安装配置

(1)首先编辑项目的 pom.xml 文件,添加如下依赖:

mybatis-plus-boot-starter:MyBatis-Plus 依赖
mysql-connector-java:MySQL 数据库驱动
druid:Druid 是阿里巴巴开发的号称为监控而生的数据库连接池,也是目前最好的数据库连接池。
lombok:提供许多实用注解的工具插件
<!-- MyBatis-Plus依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1</version>
</dependency><!-- 数据库驱动依赖 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency><!-- 数据库连接池 -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version>
</dependency><!-- Lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

(2)接着在 application.properties 中配置数据库连接信息:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/hangge
spring.datasource.username=root
spring.datasource.password=hangge1234

(3)最后 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

要指明一个类是 Mapper 有如下两种方式:
一种方式是在具体的 Mapper 上添加 @Mapper 注解,表明该接口是一个 MyBatis 中的 Mapper。这种方式就是需要在每一个 Mapper 上都添加注解。
还有一种更简单的方式(即本样例使用的方式)便是在配置类上添加 @MapperScan("com.example.demo.mapper") 注解,表示扫描 com.example.demo.mapper 包下的所有接口作为 Mapper。这样就不需要在每个接口上配置 @Mapper 注解了。
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

1,创建实体类

(1)假设我们数据库表结构如下:

(2)创建对应的 User 实体类:

@Data
public class User {//指定主键使用数据库ID自增策略@TableId(type = IdType.AUTO)private Integer id;private String userName;private String passWord;
}

2,创建数据库访问层
​ 我们编写一个 Mapper 类(UserMapper),我们只需要继承 BaseMapper 接口即可,里面不用写任何方法,也不需要编写 xml 文件。

public interface UserMapper extends BaseMapper<User> {
}

3,开始测试
(1)我们在 Controller 中通过调用 UserMapper 进行数据的增、删、改、查操作。

@RestController
public class HelloController {@AutowiredUserMapper userMapper;@RequestMapping("/test")public void test(){// 新增数据User user1 = new User();user1.setUserName("hangge");user1.setPassWord("123456");int i1 = userMapper.insert(user1);System.out.println("插入一条数据>>>" + i1);// 修改数据User user2 = new User();user2.setId(1);user2.setPassWord("888888");int i2 = userMapper.updateById(user2);System.out.println("更新一条数据>>>" + i2);// 删除数据int i3 = userMapper.deleteById(12);System.out.println("删除一条数据>>>" + i3);// 查询单条数据User user4 = userMapper.selectById(1);System.out.println("查询1条数据>>>" + user4.toString());// 查询多条数据List<User> users = userMapper.selectList(null);System.out.println("查询多条数据>>>" + users);return;}
}

(2)在浏览器中访问 http://localhost:8080/test 地址,可以看到控制台打印出的日志如下,可以发现通过几个简单的步骤,我们就实现了 User 表的 CRUD 功能:

二、设置模型对应的表名、字段名

1,设置关联的表名

(1)默认情况下,如果数据库表是使用标准的下划线命名,并且能对应上实体类的类名,我们就不需要特别去手动匹配。比如有张 user_info 表,那么会自动匹配下面这个实体类:

@Data
public class UserInfo {private Integer id;private String userName;private String passWord;
}

(2)如果数据库中所有表都有个表名前缀,比如我们想让 t_user_info 表仍然对应 UserInfo 实体类,可以添加如下全局配置设置表名前缀:

mybatis-plus.global-config.db-config.table-prefix=t_

(3)如果所有表名都不是下划线命名(但能跟类名对应上),比如想让 userinfo 表对应 UserInfo 实体类,可以添加如下全局配置,表示数据库表不使用下划线命名

mybatis-plus.global-config.db-config.table-underline=false

(4)除了上面两种全局配置方法外,我们还可以使用 @TableName 表名注解指定当前实体类对应的表名,比如下面 UserInfo 实体类对应表名为 user:

@Data
@TableName(value = "user")
public class UserInfo {private Integer id;private String userName;private String passWord;
}

2,设置关联的字段名
(1)同表名一样,如果数据库表里的字段名使用标准的下划线命名,并且能对应上实体类的成员名称(驼峰命名),我们就不需要特别去手动匹配。比如下面 user_info 表里的字段会自动跟 UserInfo 实体类的各个成员属性一一对应:

@Data
public class UserInfo {private Integer id;private String userName;private String passWord;
}

(2)如果数据库表里的字段名并不是使用下划线命名(但能跟实体类的成员名称对应上),可以添加如下全局配置,表示数据库表字段名不使用下划线命名:

mybatis-plus.configuration.map-underscore-to-camel-case=false

(3)除了全局配置方法外,我们还可以使用 @TableId 注解(标注在主键上)和 @TableField 注解(标注在其他成员属性上)来指定对应的字段名:

@Data
public class UserInfo {@TableId(value = "uuid")private Integer id;@TableField(value = "uname")private String userName;@TableField(value = "pword")private String passWord;
}

三、主键策略

我们可以通过 @TableId 注解的 type 属性来设置主键 id 的增长策略,一共有如下几种主键策略,可根据情况自由配置。

1,ASSIGN_ID(雪花算法)
​ 如果不设置 type 值,默认则使用 IdType.ASSIGN_ID 策略(自 3.3.0 起)。该策略会使用雪花算法自动生成主键 ID,主键类型为 Long 或 String(分别对应 MySQL 的表字段为 BIGINT 和 VARCHAR)

提示:该策略使用接口 IdentifierGenerator 的方法 nextId(默认实现类为 DefaultIdentifierGenerator 雪花算法),下面是雪花算法介绍:
雪花算法(SnowFlake)是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且 ID 引入了时间戳,基本上保持自增的。
@Data
public class UserInfo {//指定主键生成策略使用雪花算法(默认策略)@TableId(type = IdType.ASSIGN_ID)private Long id;private String userName;private String passWord;
}

2,ASSIGN_UUID(不含中划线的UUID)
​ 如果使用 IdType.ASSIGN_UUID 策略,则会自动生成不含中划线的 UUID 作为主键。主键类型为 String,对应 MySQL 的表字段为 VARCHAR(32)

提示:该策略使用接口 IdentifierGenerator 的方法 nextUUID

@Data
public class UserInfo {//指定主键生成策略为不含中划线的UUID@TableId(type = IdType.ASSIGN_UUID)private String id;private String userName;private String passWord;
}

3,AUTO(数据库 ID 自增)

对于像 MySQL 这样的支持主键自动递增的数据库,我们可以使用 IdType.AUTO 策略。

@Data
public class UserInfo {//指定主键使用数据库ID自增策略@TableId(type = IdType.AUTO)private Integer id;private String userName;private String passWord;
}

4,INPUT(insert 前自行 set 主键值)
(1)针对有序列的数据库:比如 Oracle,SQLServer 等,当需要建立一个自增字段时,需要用到 sequence。

提示:
在 Oracle 11g 中,设置自增字段,需要先创建序列(SQUENCE)再创建一个触发器(TRIGGER)。
在 Oracle 12c 中,只需要使用 IDENTITY 属性就可以了,和 MySQL 一样简单。

(2)Mybatis-Plus 已经定义好了常见的数据库主键序列,我们首先只需要在 @Configuration 类中定义好 @Bean:

Mybatis-Plus 内置了如下数据库主键序列(如果内置支持不满足你的需求,可实现 IKeyGenerator 接口来进行扩展):
DB2KeyGenerator
H2KeyGenerator
KingbaseKeyGenerator
OracleKeyGenerator
PostgreKeyGenerator
@Bean
public OracleKeyGenerator oracleKeyGenerator(){return new OracleKeyGenerator();
}

(3)然后实体类配置主键 Sequence,指定主键策略为 IdType.INPUT 即可:

提示:支持父类定义 @KeySequence 子类使用,这样就可以几个表共用一个 Sequence

@TableName("TEST_SEQUSER")
@KeySequence("SEQ_TEST")//类注解
public class TestSequser{@TableId(value = "ID", type = IdType.INPUT)private Long id;}

(4)如果主键是 String 类型的,也可以使用:

如何使用 Sequence 作为主键,但是实体主键类型是 String 也就是说,表的主键是 varchar2,但是需要从 sequence 中取值
实体定义 @KeySequence 注解 clazz 指定类型 String.class
实体定义主键的类型 String
注意:oracle 的 sequence 返回的是 Long 类型,如果主键类型是 Integer,可能会引起 ClassCastException
@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class)
public class YourEntity{@TableId(value = "ID_STR", type = IdType.INPUT)private String idStr;...
}

5,NONE(无状态)
如果使用 IdType.NONE 策略,表示未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

附:全局策略配置
​ 假设我们希望默认全部都使用 AUTO 策略(数据库 ID 自增),那么可以在 application.properties 中添加如下配置进行修改:
1 .mybatis-plus.global-config.db-config.id-type=auto

MyBatis-Plus 内置通用 Mapper,我们仅需要继承 BaseMapper,通过少量配置即可实现单表大部分 CRUD 操作,同时其更有强大的条件构造器,满足各类使用需求。

四、Mapper 的 CRUD 接口1:基本查询

1,准备工作

(1)假设我们有如下用户信息表 user_info:

(2)首先创建对应的实体类 UserInfo

@Data
public class UserInfo {private Integer id;private String userName;private String passWord;private Integer age;
}

(3)接着只需要创建 UserInfoMapper 接口,并继承 BaseMapper 接口,就可以使用各种 CRUD 方法了。

public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

2,selectById(根据 id 查询一条记录)

@RestController
public class HelloController {@AutowiredUserInfoMapper userInfoMapper;@RequestMapping("/test")public void test(){// 根据id查询数据UserInfo user = userInfoMapper.selectById(2);System.out.println(user);}
}

3,selectOne(使用查询构造器,查询一条记录):

注意:是数据库中符合传入条件的记录有多条,那就不能用这个方法,会报错。

(1)查询前我们需要先创建相应的 QueryWrapper,通过自己写表中相应的属性来构造 where 条件:

// 查询条件:名字中包含'ha'并且年龄小于40
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","ha").lt("age",40);
// 开始查询
UserInfo user = userInfoMapper.selectOne(queryWrapper);
System.out.println(user);

(2)除了使用 QueryWrapper 外,我们还可以 lambda 条件构造器做同样的事。
提示:lambda 条件构造器好处是由于它是通过调用实体类中的方法,如果方法名称写错,会直接报错,从而提前纠错。不像 QueryWrapper 是通过自己写表中相应的属性来构造 where 条件,容易发生拼写错误,等到运行时才发现。

// 查询条件:名字中包含'ha'并且年龄小于40
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40);
// 开始查询
UserInfo user = userInfoMapper.selectOne(queryWrapper);
System.out.println(user);
  • MyBatis-Plus 提供了 4 种方式创建 lambda 条件构造器,前三种分别如下:
LambdaQueryWrapper<UserInfo> lqw1 = new QueryWrapper<UserInfo>().lambda();
LambdaQueryWrapper<UserInfo> lqw2= new LambdaQueryWrapper<>();
LambdaQueryWrapper<UserInfo> lqw3 = Wrappers.lambdaQuery();
  • 无论是之前的 lambda 构造器还是 queryWrapper,每次编写完条件构造语句后都要将对象传递给 mapper 的 selectOne 方法,比较麻烦,MyBatisPlus 提供了第四种函数式编程方式,不用每次都传。
UserInfo userInfo = new LambdaQueryChainWrapper<>(userInfoMapper).like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40).one();

(3)我们也可以将对象直接以构造参数的形式传递给 QueryWrapper,MyBatisPlus 会自动根据实体对象中的属性自动构建相应查询的 SQL 语句:

// 查询条件:名字为'hangge'并且年龄为22
UserInfo userInfo = new UserInfo();
userInfo.setUserName("hangge");
userInfo.setAge(22);
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
UserInfo user = userInfoMapper.selectOne(queryWrapper);
System.out.println(user);

如果想通过对象中某些属性进行模糊查询,我们可以在跟数据库表对应的实体类中相应的属性标注相应注解即可。比如我们想通过姓名进行模糊查询用户:

@Data
public class UserInfo {private Integer id;@TableField(condition = SqlCondition.LIKE)private String userName;private String passWord;private Integer age;
}
  • 下面我们查询名字包含 ha 的用户,可以发现生成的 sql 语句确实使用 like 进行模糊查询:
// 查询条件:名字包含为'ha'
UserInfo userInfo = new UserInfo();
userInfo.setUserName("ha");
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
UserInfo user = userInfoMapper.selectOne(queryWrapper);

4,selectBatchIds(根据 ID 批量查询,返回一个 List)

List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
List<UserInfo> users = userInfoMapper.selectBatchIds(ids);
System.out.println(users);

5,selectByMap(通过 Map 封装的条件查询,返回一个 List)

注意:map 写的是数据表中的列名,而非实体类的属性名。比如属性名为 userName,数据表中字段为 user_name,这里应该写的是 user_name。
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("user_name", "hangge");
columnMap.put("age", 22);
List<UserInfo> users = userInfoMapper.selectByMap(columnMap);
System.out.println(users);

6,selectList(使用查询构造器,返回一个 List):

注意:selectList 使用与 selectOne 类似,不同的是当数据库中符合传入的条件的记录有多条,使用 selectOne 会报错。这时就要使用 selectList。

(1)查询前我们需要先创建相应的 QueryWrapper,通过自己写表中相应的属性来构造 where 条件:

// 查询条件:名字中包含'ha'并且年龄小于40
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","ha").lt("age",40);
// 开始查询
List<UserInfo> users = userInfoMapper.selectList(queryWrapper);
System.out.println(user);

(2)除了使用 QueryWrapper 外,我们还可以 lambda 条件构造器做同样的事。

提示:lambda 条件构造器好处是由于它是通过调用实体类中的方法,如果方法名称写错,会直接报错,从而提前纠错。不像 QueryWrapper 是通过自己写表中相应的属性来构造 where 条件,容易发生拼写错误,等到运行时才会发现。
// 查询条件:名字中包含'ha'并且年龄小于40
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40);
// 开始查询
List<UserInfo> users = userInfoMapper.selectList(queryWrapper);
System.out.println(users);
  • MyBatis-Plus 提供了 4 种方式创建 lambda 条件构造器,前三种分别如下:

    LambdaQueryWrapper<UserInfo> lqw1 = new QueryWrapper<UserInfo>().lambda();
    LambdaQueryWrapper<UserInfo> lqw2= new LambdaQueryWrapper<>();
    LambdaQueryWrapper<UserInfo> lqw3 = Wrappers.lambdaQuery();
    
  • 无论是之前的 lambda 构造器还是 queryWrapper,每次编写完条件构造语句后都要将对象传递给 mapper 的 selectList 方法,比较麻烦,MyBatisPlus 提供了第四种函数式编程方式,不用每次都传。

List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper).like(UserInfo::getUserName,"ha").lt(UserInfo::getAge,40).list();

(3)我们也可以将对象直接以构造参数的形式传递给 QueryWrapper,MyBatisPlus 会自动根据实体对象中的属性自动构建相应查询的 SQL 语句:

// 查询条件:名字为'hangge'并且年龄为22
UserInfo userInfo = new UserInfo();
userInfo.setUserName("hangge");
userInfo.setAge(22);
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
List<UserInfo> users = userInfoMapper.selectList(queryWrapper);
System.out.println(users);

如果想通过对象中某些属性进行模糊查询,我们可以在跟数据库表对应的实体类中相应的属性标注相应注解即可。比如我们想通过姓名进行模糊查询用户:

@Data
public class UserInfo {private Integer id;@TableField(condition = SqlCondition.LIKE)private String userName;private String passWord;private Integer age;
}
  • 下面我们查询名字包含 ha 的用户,可以发现生成的 sql 语句确实使用 like 进行模糊查询:
// 查询条件:名字包含'ha'
UserInfo userInfo = new UserInfo();
userInfo.setUserName("ha");
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
List<UserInfo> users = userInfoMapper.selectList(queryWrapper);

7,selectMaps(使用查询构造器,返回一个 List):
​ selectMaps 的用法和上面的 selectList 很像,都是传入一个查询构造器进行查询,然后返回一个 List。不同在于 selectMaps 返回的 List 里面是 Map:

注意: Map 里的 key 为表字段名,而不是对应实体类的属性名。

UserInfo userInfo = new UserInfo();
userInfo.setUserName("ha");
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
List<Map<String, Object>> users = userInfoMapper.selectMaps(queryWrapper);
System.out.println(users);

8,selectObjs(使用查询构造器,返回一个 List):

selectObjs 的用法和前面的 selectList 很像,都是传入一个查询构造器进行查询,然后返回一个 List。不同在于 selectObjs 返回的 List 里面只有返回的第一个字段值:

UserInfo userInfo = new UserInfo();
userInfo.setAge(22);
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
List<Object> users = userInfoMapper.selectObjs(queryWrapper);
System.out.println(users);

9,selectCount(使用查询构造器,查询总记录数):

​ selectCount 的用法和前面的 selectList 很像,都是传入一个查询构造器进行查询,不同的是 selectCount 返回的是一个 Integer 值(符合条件的记录数):

UserInfo userInfo = new UserInfo();
userInfo.setAge(22);
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
// 开始查询
Integer count = userInfoMapper.selectCount(queryWrapper);
System.out.println(count);

附:添加自己的数据库操作

如果觉得默认提供的 CRUD 接口不能满足需求,我们可以添加自己的 SQL 语句,具体有如下两种方案。

1,注解方式(Mapper.java)
我们可以直接在自定义方法上使用 @Select 设置对应的 sql 语句:

public interface UserInfoMapper extends BaseMapper<UserInfo> {@Select("select * from user_info WHERE age > #{age}")List<UserInfo> getAll(Integer age);
}

2,XML 形式(Mapper.xml)
(1)首先在 mapper.xml 中添加自定义的 sql 语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserInfoMapper"><select id="getAll" resultType="com.example.demo.model.UserInfo">SELECT * FROM user_info WHERE age > #{age}</select>
</mapper>

(2)然后在 mapper.java 中添加相应的接口方法即可:

public interface UserInfoMapper extends BaseMapper<UserInfo> {List<UserInfo> getAll(Integer age);
}	

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-35088.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

Jasper(1)——入门

Jasper&#xff08;1&#xff09;——入门 第一次写自己的总结~写得烂大家别介意哈O(∩_∩)O 由于项目需要&#xff0c;导出功能必须要Jasper导出报表&#xff0c;所以不得不用&#xff0c;刚接触真的蛮多坑。现在我自己还没摸索明白&#xff0c;因此很多我都是不知道的&#…...

c++实现树的dfs,bfs

void dfs(Node* head) {if (head nullptr) {return;}std::cout << head->value << ",";dfs(head->left);dfs(head->right); }void bfs(Node* head) {if (head nullptr) { // if head is nullptr, return directlyreturn;}std::queue<Nod...

laravel 8 实现excel 导出

composer 下载 composer require maatwebsite/excel 引入 use Elasticsearch\ClientBuilder; 创建excel文件 php artisan make:Exports FangExports FangExports 里面 return Fang::all(); php后台 //导出房东excelpublic function exports(){return Excel::download(…...

Vue相关:

目录 1,说一下vue最大特点是什么或者说vue核心是什么 2,说一下vue常用基本指令有哪些 3,Vue常用的修饰符...

【Unity】如何将资源包里的Prefabs资源为己所用

步骤一、将所需要的prefab从外部导入的资源拖入Scene中。二、右键该预制体&#xff0c;选择Unpack Prefab Completely取消该预制体及其子物体与资源包中预制体的关联。三、将该预制体拖动到自己的prefabs文件夹目录下&#xff0c;制作成自己项目的预制体。四、在Project面板下&…...

防火墙高可靠性

双机热备、BFD双向转发检测、IP-LINK链路检测、Link-Group逻辑组、ETH-Trunk链路捆绑、Bypass&#xff0c;跨数据中心集群&#xff0c;双主控、业务板备份、数据中心会话同步 双机热备 目的&#xff1a;为了防止单点故障 实现&#xff1a;两台硬件软件相同的FW之间通过一条独…...

Centos8.0系统升级到最新版本

一 &#xff0c;Centos8.0更换国内源&#xff08;阿里源&#xff09; 1&#xff0c; 备份旧的配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup2&#xff0c;进入cd /etc/yum.repos.d cd /etc/yum.repos.d3&#xff0c;下载新的 Ce…...

高端音响的死亡被大大夸大了

几年前&#xff0c;在 MP3 盗版时代的鼎盛时期——当高端音频世界哀叹 MP3 文件的糟糕音质&#xff0c;而 MP3 用户乐于用音质换取免费音乐时——一位业内同事问我我以为高端音频已经死了。我向她保证不&#xff0c;一部分音乐迷&#xff0c;虽然可能不是主流&#xff0c;但总是…...

Java学习笔记--13.网络编程

Java学习笔记–13 第十章 网络编程 目录Java学习笔记--13前言网络编程1.定义2.TCP通信(1).ServerSocket(2).Socket3.UDP通信(1).发送方(2).接收方前言 21世纪&#xff0c;走进了信息时代&#xff0c;各种各样的软件层出不穷&#xff0c;但是总离不开程序开发&#xff0c;离不…...

wimform 继承窗体卡顿解决

get { const int CS_NOCLOSE 0x200; CreateParams cp base.CreateParams; cp.ClassStyle cp.ClassStyle | CS_NOCLOSE; if (!DesignMode) { cp.ExStyle...

git 替换commit的账户与邮箱信息 GitLab: Committer‘s email does not follow the pattern

最终解决方法来源&#xff1a; https://segmentfault.com/q/1010000006999861 https://www.cnblogs.com/zh7791/p/12986083.html ① git rebase -i HEAD~N N代表前N次的提交记录 ② 出现记录后键入i进入INSERT模式&#xff0c;在需要修改的条目上&#xff0c;将pick改为edit…...

后端返回状态码401, 获取不到怎么办?

传送门...

解决for循环中异步请求顺序不一致的问题

解决for循环中异步请求顺序不一致的问题参考文章&#xff1a; &#xff08;1&#xff09;解决for循环中异步请求顺序不一致的问题 &#xff08;2&#xff09;https://www.cnblogs.com/mo3408/p/12163012.html 备忘一下。...

可以ping通网关,dns。但是死活不能上网????怎么回事?

苹果电脑重装了一把win7系统。连接手机热点没问题&#xff0c;连接店里wifi也没问题。但是呢连接家里wifi死活不能上网&#xff01;&#xff01;&#xff01; 各种网上搜索啊&#xff0c;花了三四个小时&#xff0c;找到了各种解决方法&#xff0c;比如什么winsock reset还有什…...

python3中 下载wechatpy后 没有 work模块

1、 环境 win10 2、python3.6 3、wechatpy 最新版本 4、python3 中安装 wechatpy 模块后找不到 work模块 5、错误如下&#xff1a; ModuleNotFoundError: No module named wechatpy.work 这个错误明显是找不到wechatpy.work这个模块 6、查看wechatpy 使用文档 &#x…...

机器学习----支撑向量机(SVM)

SVM 支持向量机&#xff08;Support Vector Machine, SVM&#xff09; 图中是一个样本空间&#xff0c;里面有一些样本点&#xff0c;分成红色和蓝色两类。 逻辑回归是要找到一根决策边界&#xff0c;由决策边界把数据分成两类。但可能存在这样一些数据&#xff08;下图&…...

Spring都没弄明白凭什么拿高薪?真香系列

正文 二叉树 由 n&#xff08; n > 0&#xff09;个有限节点组成一个具有层次关系的集合&#xff0c;看起来就像一个倒挂的树&#xff0c;因此称这样的数据结构为树。 一个节点的子节点个数叫做度&#xff0c;通俗的讲就是树叉的个数。树中最大的度叫做树的度&#xff0c…...

一天一道ctf 第36天

[NPUCTF2020]ReadlezPHP 点进源码发现/time.php?source&#xff0c;访问一下得到 <?php #error_reporting(0); class HelloPhp {public $a;public $b;public function __construct(){$this->a "Y-m-d h:i:s";$this->b "date";}public functi…...

dockerfile的详细介绍

Dockerfile 关键字作用备注FROM指定父镜像指定dockerfile基于那个image构建MAINTAINER作者信息用来标明这个dockerfile谁写的LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看RUN执行命令执行一段命令 默认是/bin/sh…...

nacos心跳

轮询 概括来说是服务端定时主动的去与要监控状态的客户端&#xff08;或者叫其他系统&#xff09;通信&#xff0c;询问当前的某种状态&#xff0c;客户端返回状态信息&#xff0c;客户端没有返回或返回错误、失效信息、则认为客户端已经宕机&#xff0c;然后服务端自己内部把这…...

机器学习----支撑向量机(SVM)

SVM 支持向量机&#xff08;Support Vector Machine, SVM&#xff09; 图中是一个样本空间&#xff0c;里面有一些样本点&#xff0c;分成红色和蓝色两类。 逻辑回归是要找到一根决策边界&#xff0c;由决策边界把数据分成两类。但可能存在这样一些数据&#xff08;下图&…...

采坑记录之node-sass

node-sass这货很容易安装失败 下面是node-sass官网给出的对应node.js版本的图 一定要按照node-sass官网给出的对应node.js版本来安装&#xff0c;不然很容易安装失败 下面是sass-loader版本图 我自己安装的是node.js 14.x版本的&#xff0c;对应的node-sass的版本是4.14.x&a…...

Elasticsearch:使用 Debian 软件包安装 Elasticsearch

Elasticsearch 的 Debian 包可以从我们的网站或我们的 APT 仓库下载。 它可用于在任何基于 Debian 的系统上安装 Elasticsearch&#xff0c;例如 Debian 和 Ubuntu。 Elasticsearch 的最新稳定版本可以在下载 Elasticsearch 页面上找到。 其他版本可以在过去的版本页面上找到。…...

ZZULIOJ 1009: 求平均分

题目描述 已知某位学生的数学、英语和计算机课程的成绩&#xff0c;求该生三门课程的平均分。 输入 输入三个整数&#xff0c;数据之间由空格隔开。 输出 输出占一行&#xff0c;包含一个实数&#xff0c;为三门课的平均分&#xff0c;保留两位小数。 样例输入 87 73 93…...

后端返回状态码401, 获取不到怎么办?

传送门...

Node.js-EJS模板

EJS是一个JavaScript模版库&#xff0c;用来将EJS模版结合着JSON数据转换为HTML 并且可以直接在模版中写JavaScript的语法 安装ejs包 //控制台输入 npm i ejs简单示例 let template <h1>Hello, <% name %></h1> let data {name: World }let renderStr …...

python数据分析——如何用python连接远程数据库

本文将以SQLite、MySQL&#xff0c;PostgreSQL为例讲解python怎样连接远程数据库并执行相关数据库操作。 SQLite SQLite可能是与Python连接的最方便的数据库&#xff0c;因为我们不需要安装任何外部Python SQL模块即可使用。默认情况下&#xff0c;Python会自带一个名为sqlite…...

一本通1034:计算三角形面积

1034&#xff1a;计算三角形面积 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 72178 通过数: 23831 【题目描述】 平面上有一个三角形&#xff0c;它的三个顶点坐标分别为(x1,y1),(x2,y2),(x3,y3) &#xff0c;那么请问这个三角形的面积是多少&#xff0c;精确…...

error C249: ‘DATA‘: SEGMENT TOO LARGE

今天碰到这个问题&#xff0c;浪费挺长时间的&#xff0c;做个笔记提供一种解决方法&#xff1a;error C249: ‘DATA’: SEGMENT TOO LARGE 编译的时候出现这个错误 需要将【魔术棒】中【Target】项中【Memory Model】&#xff0c;由small&#xff1a;xxxx改成Large&#xff1…...

活动目录备份和灾难恢复之自动备份与授权还原

前言 由于服务器系统状态总在变化&#xff0c;因该增加对系统状态备份的频率&#xff0c;来减少备份对服务器工作环境的影响&#xff0c;所以最好是每天晚上对服务器系统状态进行备份&#xff0c;但是单独使用wbadmin命令无法创建系统状态的自动备份计划&#xff0c;此时可以使…...

dbc2000 注册机|dbc2000 注册码注册机下载

点击下载来源&#xff1a;dbc2000 注册机 dbc2000 注册机是同名源程序软件的注册机软件&#xff0c;该源程序软件是一款应用于数据库搭建以及数据写入的数据库架设工具&#xff0c;它拥有强大的数据写入功能&#xff0c;在作为应用程序使用时&#xff0c;它不仅可以充当数据属性…...

秋招面经第八弹:网易二面-数据开发工程师

秋招第八弹&#xff1a;网易二面-数据开发工程师 写在最前&#xff1a;秋招以来一直在冲&#xff0c;因为事情比较多&#xff0c;对于笔试面试一直没有复盘&#xff0c;现在靠仅存的记忆把面试的一些问题记录下来&#xff0c;尽可能记录出能回忆到的问题&#xff0c;但可能记的…...

安卓课程格子APP

https://download.csdn.net/download/weixin_57836618/73810452 功能演示&#xff1a; 查看所有课程 点击主页面空白处即可添加课程 添加课程之后查看课程 查看双周课程 查看单周课程 6.查看课程详情...

强化学习——格子世界

强化学习——格子世界 项目源码地址&#xff1a;https://gitee.com/infiniteStars/machine-learning-experiment 1. 实验内容 2. 实验代码 import numpy as np import matplotlib.pyplot as plt from matplotlib.table import Table from xml.dom.minidom import Document #手…...

华为机试 - 跳格子游戏

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 地上共有N个格子&#xff0c;你需要跳完地上所有的格子&#xff0c;但是格子间是有强依赖关系的&#xff0c;跳完前一个格子后&#xff0c;后续的格子才会被开启&#xff0c;格子间的依赖关系由多组st…...

php 爬课程表信息,Ruby爬取教务系统生成课程表

我为什么要虐自己最近觉得课程格子广告越来越多&#xff0c;乱七八糟的东西越来越多&#xff0c;完全失去了一开始的存在价值&#xff0c;并且没有电脑端app&#xff0c;想查看课程必须拿出手机&#xff0c;而我使用电脑频率要比手机高&#xff0c;所以才有了折腾的动力。于是我…...

android 课程表 ui,UICollectionViewLayout实现课程表布局

因为项目中有课程表的相关模块&#xff0c;第一时间想到用UICollectionView。然而后期的需求越来越复杂&#xff0c;每个格子需要展示的内容越来越多&#xff0c;所以不得不寻找合适的解决方案。最后发现自定义UICollectionViewLayout可以实现我的需求。先放效果图&#xff1a;…...

Android自定义View课程表,Android 自定义View课程表表格

自己闲下来时间写的一个课表控件使用的自定义LinearLayout 里面View都是用代码实现的 最终效果如下图 写的可能有问题希望多多指点创建一个自定义LinearLayout 控件用来装载课程的信息和课程的周数 和节数大概的布局三这样的根据上面的看来觉得总体布局我分了两个 上面的星期是…...

java课程设计设计_java课程设计

1. 团队课程设计博客链接https://www.cnblogs.com/choco1ate/p/12172223.html2.本组课题及本人任务本组课题&#xff1a;泡泡堂(炸弹人)游戏本人任务&#xff1a;Box类(游戏地图中的每个方格)Bomb类(游戏过程中的)游戏玩家输赢信息的文件储存3.需求分析Box类&#xff1a;该类为…...

《课程格子》的一个笔试题目

题目如下&#xff0c;感觉很适合喜欢琢磨的程序员&#xff0c;也是考验你编码风格的时候。 Lets make a tower defense game&#xff08;塔防游戏):1. You have 1 tower, with H health and D dps(damage per second).2. There are n attackers, each with h_i health and d_i …...

Android仿照超级课程表 or 课程格子 一键提取课表功能(方正系统)

参考文章http://blog.csdn.net/sbsujjbcy ,本文仿照‘ 安卓弟 提供的android 项目实战——打造超级课程表一键提取课表功能文章&#xff0c;对他的代码进行了修改和补充&#xff0c;为什么要修改呢&#xff1f;原因是安卓弟的那个源码版本过于老旧&#xff0c;很多方法已经过…...

AQS源码解析 8.共享模式_Semaphore信号量

AQS源码解析—共享模式_Semaphore信号量 简介 synchronized 可以起到锁的作用&#xff0c;但某个时间段内&#xff0c;只能有一个线程允许执行。 Semaphore&#xff08;信号量&#xff09;用来限制能同时访问共享资源的线程上限&#xff0c;非重入锁。 Semaphore 是什么&am…...

备份容灾技术基础

备份概念及结构 备份的基本概念&#xff1a; 备份&#xff1a;指将文件系统或数据库系统中的数据加以复制&#xff1b;一旦发生灾难或错误操作时&#xff0c;得以方便而及时地恢复系统的有效数据和正常运作。 备份系统的组成&#xff1a; 备份服务器备份软件存储设备 备份…...

NFV基础技术

在NFV之前&#xff0c;NF&#xff08;Network Function&#xff09;是一直存在的&#xff0c;网络中&#xff0c;NF可以看成一个个独立的网元&#xff0c;实现着各自的功能。NF以固定的方式连接起来&#xff0c;统一提供的网络功能和服务。V&#xff08;Virtualization&#xf…...

软件技术层次理解

0. 新人期 对所做系统、基础都跟不上&#xff0c;很迫切的补充基础&#xff0c;了解系统&#xff0c;开发的平台。 1. 看完代码调用过程。 完成这个过程&#xff0c;内心会有点小膨胀&#xff0c;感觉自己很牛了&#xff0c;但实际上&#xff0c;只是识别了静态代码的过程&am…...

java基础-软件简述

大家好&#xff0c;我依然是你们的老朋友&#xff0c;老寇&#xff0c;现在跟随我一起遨游代码的海洋&#xff0c;做好准备&#xff0c;马上出发。介绍&#xff1a;回想当年我还是一个小菜鸡的时候&#xff08;咳咳&#xff0c;现在也是菜鸡&#xff09;&#xff0c;打开课本的…...

CVTE软件技术支持面试总结

CVTE软件技术支持还是如期的挂了。一面技术面通过&#xff0c;二面技术面莫名的挂了&#xff0c;简单总结下吧。笔试内容比较基础&#xff0c;涉及嵌入式、Linux命令&#xff0c;C语言&#xff0c;数据结构与算法内容&#xff0c;20个选择题&#xff0c;2道编程题&#xff0c;编…...

FreeCAD二次开发-基于控制台模式FC外部开发

版本 FreeCAD0.18.2+PyCharm Community 2020.3.3 演示效果 环境搭建步骤 1.先安装好FreeCAD和PyCharm 2.添加环境变量 点击确定,全部关掉。 3.测试变量是否生效(CMD打开控制台,输入python回车) 弹出如下,说明可以进入FreeCAD自带的python解释器 4.打开PyCharm新建项目 …...

软件基础知识点汇总

软件基础1 计算机结构2 软件的定义3 操作系统的定义4 软件的生命周期5 瀑布模型6 模块化开发7 软件测试8 数据结构类型9 查找10 排序11 三级存储结构12 调度1 计算机结构 冯诺依曼式&#xff1a;CPU&#xff08;控制器、运算器&#xff09;、存储器、输入设备、输出设备。 2 …...

软件技术基础复习提纲

文章目录第一章 绪论软件开发过程数据结构在计算问题中的用途算法设计操作系统操作系统主要功能编译原理相关数据库相关第二章 数据结构2.1 线性表2.2 复杂度分析2.3 分治递归2.4 树树的各种基本概念二叉树的存储结构二叉树、满二叉树、完全二叉树二叉树的遍历2.5 图图的定义及…...