相关文章推荐
重情义的跑步鞋  ·  mac更新c++编译器 - CSDN文库·  9 月前    · 
高大的灌汤包  ·  怎么用python实现电脑cpu温度监控_百度知道·  1 年前    · 
腼腆的滑板  ·  Python3-定时任务四种实现方式_51C ...·  1 年前    · 
英俊的汤圆  ·  What causes a Status ...·  2 年前    · 
善良的勺子  ·  Overview of update ...·  2 年前    · 
Code  ›  通用Mapper Example类使用以及源码分析_example.criteria_西京刀客的博客
源码 string mybatis动态sql criteria
https://blog.csdn.net/inthat/article/details/90906140
心软的刺猬
1 年前
  • 一、通用Mapper Example类使用
    • 1. 常用使用方式举例
    • 2. 使用方式:条件嵌套组合
  • 二、通用Mapper Example类源码分析
    • 1. 代码细节理解
      • 1.1 Criteria类
      • 1.2 Criterion类
      • 1.3 Example类成员变量oredCriteria
      • 1.4 Examle构造函数
      • 1.5 Examle静态方法builder
    • 2. Example类关系简单分析
      • 2.1 类关系
      • 2.2 使用流程分析

      一、通用Mapper Example类使用

      1. 常用使用方式举例

      首先定义数据库表映射类:

      public class MybatisDemo {
      private Long id;
      private Long count;
      private String name;

      public Long getId() {
          return id;
      public Long getCount() {
          return count;
      public String getName() {
          return name;
      

      // setter……
      }
      此处省略了数据库表映射和set方法。

      接下来就是实现example查询的几种方式,核心代码如下:

      方式一:普通Example方式(从and方法开始可以实现动态sql拼接)

      Example example = new Example(CandidateBrandEntity.class);
      example
        //.selectProperties("cabId","cabName")
          .and().andEqualTo("cabDeleted",0)
          .andLike("cabName","%d%");
      // 排序
      example.orderBy("cabCreatedTime")
          /*.desc()*/
            .orderBy("cabId").desc();
      // 获得结果
      List<CandidateBrandEntity> brands = brandEntityMapper.selectByExample(example);
      

      方式二:Criteria方式(可使用criteria完成动态sql拼接)

      Example example = new Example(MybatisDemo.class);
      Example.Criteria criteria = example.createCriteria();
      criteria.andEqualTo(“count”, 0)
      .andLike(“name”, “%d%”);
      example.orderBy(“count”)
      //.desc()
      .orderBy(“name”).desc();
      List demos = mybatisDemoMapper.selectByExample(example);

      方式三:Example.builder 方式(其中where从句中内容可以拿出来进行动态sql拼接)

      Example example = Example.builder(MybatisDemo.class)
      .select(“cabId”,“cabName”)
      .where(Sqls.custom().andEqualTo(“count”, 0)
      .andLike(“name”, “%d%”))
      .orderByDesc(“count”,“name”)
      .build();
      List demos = mybatisDemoMapper.selectByExample(example);

      方式四:Example.builder + Weekend方式,优势:不用输入属性名,避免数据库有变动或输入错误就会出错

      //获得seekendsql
      WeekendSqls sqls = WeekendSqls.custom();

      //可进行动态sql拼接
      sqls = sqls.andEqualTo(MybatisDemo::getCount,0).andLike(MybatisDemo::getName,"%d%");

      //获得结果
      List demos = mybatisDemoMapper.selectByExample(Example.builder(MybatisDemo.class).where(sqls).orderByDesc(“count”,“name”).build());

      2. 使用方式:条件嵌套组合

      通用example语法

      Example e = new Example(User.class);
              Example.Criteria c = e.createCriteria();
              //关键字查询部分
              String keyword = pageReq.getKeyword();
              if (StringUtils.isNotEmpty(keyword)) {
                  c.orEqualTo("userName", keyword).orEqualTo("policeNo",keyword).orEqualTo("realName",keyword);
              //部门查询部门
              Example.Criteria criteria = e.createCriteria();
              criteria.andEqualTo("departmentId", departmentId);
              e.and(criteria);
              PageHelper.startPage(pageReq.getPageIndex(), pageReq.getPageSize());
              List<User> users = userMapper.selectByExample(e);
      

      执行的sql为:

      WHERE (
      user_name = ?
      OR police_no = ?
      OR real_name = ?
      )
      AND (department_id = ?)

      总结下来,就是,

      每个条件组合(a/b/c) (d)各自创建自己的cirteria,再用and或者or方法去连接

      二、通用Mapper Example类源码分析

      1. 代码细节理解

      1.1 Criteria类

      criteria
      英 [kraɪ’tɪərɪə] 美 [kraɪ’tɪrɪə]

      n. 标准,条件(criterion的复数)
      

      在这里插入图片描述
      作者这里用 单词criteria 应该表达的是条件的意思,指sql where条件!

      criterion的复数

      如下GeneratedCriteria类有成员变量criteria,就是Criterion组成的对象数组。

                  criteria = new ArrayList<Criterion>();
      

      同时Criteria类继承了抽象父类的很多方法,例如

              public Criteria andEqualTo(String property, Object value) {
                  addCriterion(column(property) + " =", value, property(property));
                  return (Criteria) this;
              public Criteria andNotEqualTo(String property, Object value) {
                  addCriterion(column(property) + " <>", value, property(property));
                  return (Criteria) this;
      

      很多这些方法,里面都是调addCriterion传不同的参数,如下addCriterion实现如下,其实就是new Criterion实例传参,添加到数组criteria中。

              protected void addCriterion(String condition, Object value, String property) {
                  if (value == null) {
                      if (notNull) {
                          throw new MapperException("Value for " + property + " cannot be null");
                      } else {
                          return;
                  if (property == null) {
                      return;
                  criteria.add(new Criterion(condition, value));
      

      总结: 对于一个一组条件就是一个 由 Criterion对象组成的数组。对于如下这种嵌套的组合,它的实现就是调方法createCriteria,创建一个新的new Criteria实例,一个Criteria实例包含一个Criterion对象数组还包含一个private String andOr;成员变量描述这组条件用 and还是or连接。

      WHERE (
        user_name = ? 
        OR police_no = ? 
        OR real_name = ?
      AND (department_id = ?)
      

      1.2 Criterion类

      criterion
      英 [kraɪˈtɪəriən] 美 [kraɪˈtɪriən]
      n.(评判或作决定的)标准,准则,原则,条件‘’

      可以看到 criterion 是前面 criteria的单数。所以这里就是指单个条件信息。

      Criterion类组成的数组是 Criteria类的父类的成员变量,采用protected修饰(protected List criteria;)子类(Criteria类)继承该成员变量。

      对于Example的内部静态类Criterion ,我们需要分析其成员变量,如下:
      它把单个sql条件分成了如下三种情况:
      private boolean noValue;
      private boolean singleValue;
      private boolean betweenValue;
      private boolean listValue;

      各个情况,最终sql拼接如:

      • noValue无值情况
        什么情况没有value呢?
        比如: column(property) + " is null"和 column(property) + " is not null")
        sql.append(criterion.getAndOr()).append(" ").append(criterion.getCondition());
      • singleValue单值情况
        sql.append(criterion.getAndOr()).append(" ").append(criterion.getCondition()).append(criterion.getValue());
        举例: and
      • betweenValue between值情况
        sql.append(criterion.getAndOr()).append(" “).append(criterion.getCondition()).append(” “).
        append(criterion.getValue()).append(” and ").append(criterion.getSecondValue());
      • listValue list值情况
        条件(in等) + (x1,x2,x3)

      注意:这里的condition 通过addCriterion方法看到,都是例如 column(property) + " <" 或column(property) + " between"

          public static class Criterion {
              private String condition;
              private Object value;
              private Object secondValue;
              private String andOr;
              private boolean noValue;
              private boolean singleValue;
              private boolean betweenValue;
              private boolean listValue;
              private String typeHandler;
      

      总结: Criterion实例就是一个单个的条件,它组成的对象数组,就是一组条件。Criteriond的成员变量中的condition条件 都是 列名 + 操作符 组成,例如: column(property) + " <" 或column(property) + " between"。它把列名加操作符定义为条件变量。 当然有些条件没有 操作符 如 column(property) + " is null"也是 condition。

      1.3 Example类成员变量oredCriteria

      Example类成员变量oredCriteria,用于封装最终嵌套拼接的条件,它是由Criteria对象组成的对象数组。一个Criteria实例中又包含一个由Criterion对象组成的对象数组。

          protected List<Criteria> oredCriteria;
      

      1.4 Examle构造函数

      如下,构造函数是实体类的.class,

      * 带exists参数的构造方法 * @param entityClass * @param exists - true时,如果字段不存在就抛出异常,false时,如果不存在就不使用该字段的条件 * @param notNull - true时,如果值为空,就会抛出异常,false时,如果为空就不使用该字段的条件 public Example(Class<?> entityClass, boolean exists, boolean notNull) { this.exists = exists; this.notNull = notNull; oredCriteria = new ArrayList<Criteria>(); this.entityClass = entityClass; table = EntityHelper.getEntityTable(entityClass); //根据李领北建议修改#159 propertyMap = table.getPropertyMap(); this.ORDERBY = new OrderBy(this, propertyMap);

      其中table、和propertyMap定义如下,构造函数,从实体类中获取拿到这些信息。

      	 protected EntityTable               table;
      	 //属性和列对应
      	 protected Map<String, EntityColumn> propertyMap;
      

      其中有个构造函数比较特殊,传参为Builder

          private Example(Builder builder) {
              this.exists = builder.exists;
              this.notNull = builder.notNull;
              this.distinct = builder.distinct;
              this.entityClass = builder.entityClass;
              this.propertyMap = builder.propertyMap;
              this.selectColumns = builder.selectColumns;
              this.excludeColumns = builder.excludeColumns;
              this.oredCriteria = builder.exampleCriterias;
              this.forUpdate = builder.forUpdate;
              this.tableName = builder.tableName;
              if (!StringUtil.isEmpty(builder.orderByClause.toString())) {
                  this.orderByClause = builder.orderByClause.toString();
      

      1.5 Examle静态方法builder

      builder使用

      //获得结果
      List<MybatisDemo> demos = mybatisDemoMapper.selectByExample(Example.builder(MybatisDemo.class).where(sqls).orderByDesc("count","name").build());
      
          public static Builder builder(Class<?> entityClass) {
              return new Builder(entityClass);
      

      2. Example类关系简单分析

      2.1 类关系

      2.2 使用流程分析

      	Example example = new Example(MybatisDemo.class);
      	Example.Criteria criteria = example.createCriteria();
      

      使用如上方式使用example,先new Example实例,调实例的createCriteria,其中createCriteria的实现和调用如下,最终返回 new Criteria实例,看可以看到实例化Criteria,还使用了Map<String, EntityColumn> propertyMap属性相关信息的map

          public Criteria createCriteria() {
              Criteria criteria = createCriteriaInternal();
              if (oredCriteria.size() == 0) {
                  criteria.setAndOr("and");
                  oredCriteria.add(criteria);
              return criteria;
          protected Criteria createCriteriaInternal() {
              Criteria criteria = new Criteria(propertyMap, exists, notNull);
              return criteria;
      

      mapper实例使用类似如下,跟踪selectByExample方法。

          List<CandidateBrandEntity> brands = brandEntityMapper.selectByExample(example);
      

      我们的业务Mapper类,继承Mapper类,Mapper类又继承ExampleMapper又继承SelectByExampleMapper,如下,我们可以看到是ExampleProvider类实现,通过ExampleProvider查看
      selectByExample的实现:

      @RegisterMapper
      public interface SelectByExampleMapper<T> {
          @SelectProvider(
              type = ExampleProvider.class,
              method = "dynamicSQL"
          List<T> selectByExample(Object var1);
      

      ExampleProvider的selectByExample的实现,

      * 根据Example查询 * @param ms * @return public String selectByExample(MappedStatement ms) { Class<?> entityClass = getEntityClass(ms); //将返回值修改为实体类型 setResultType(ms, entityClass); StringBuilder sql = new StringBuilder("SELECT "); if (isCheckExampleEntityClass()) { sql.append(SqlHelper.exampleCheck(entityClass)); sql.append("<if test=\"distinct\">distinct</if>"); //支持查询指定列 sql.append(SqlHelper.exampleSelectColumns(entityClass)); sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass))); sql.append(SqlHelper.exampleWhereClause()); sql.append(SqlHelper.exampleOrderBy(entityClass)); sql.append(SqlHelper.exampleForUpdate()); return sql.toString();

      跟进SqlHelper.exampleWhereClause(),发现它最后返回是maybaits xml中sql语法格式的字符串。

      * Example查询中的where结构,用于只有一个Example参数时 * @return public static String exampleWhereClause() { return "<if test=\"_parameter != null\">" + "<where>\n" + " ${@tk.mybatis.mapper.util.OGNL@andNotLogicDelete(_parameter)}" + " <trim prefix=\"(\" prefixOverrides=\"and |or \" suffix=\")\">\n" + " <foreach collection=\"oredCriteria\" item=\"criteria\">\n" + " <if test=\"criteria.valid\">\n" + " ${@tk.mybatis.mapper.util.OGNL@andOr(criteria)}" + " <trim prefix=\"(\" prefixOverrides=\"and |or \" suffix=\")\">\n" + " <foreach collection=\"criteria.criteria\" item=\"criterion\">\n" + " <choose>\n" + " <when test=\"criterion.noValue\">\n" + " ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}\n" + " </when>\n" + " <when test=\"criterion.singleValue\">\n" + " ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value}\n" + " </when>\n" + " <when test=\"criterion.betweenValue\">\n" + " ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value} and #{criterion.secondValue}\n" + " </when>\n" + " <when test=\"criterion.listValue\">\n" + " ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}\n" + " <foreach close=\")\" collection=\"criterion.value\" item=\"listItem\" open=\"(\" separator=\",\">\n" + " #{listItem}\n" + " </foreach>\n" + " </when>\n" + " </choose>\n" + " </foreach>\n" + " </trim>\n" + " </if>\n" + " </foreach>\n" + " </trim>\n" + "</where>" + "</if>";

      总结: 使用方法就是程序流程,它的使用思路就是,根据实体类实例化Example,又根据Example实例,创建Criteria实例,最后调用业务Mapper实例的如selectByExample方法传入example实例,selectByExample方法会根据传参的内容,生成mybatis兼容的sql形式,mybatis会根据mabatis形式sql解析成为数据库能够执行的原始 SQL。

      这就是——通用Mapper
      参考URL:
      https://www.jianshu.com/p/5f84624e96bc
      Mybatis 解析 SQL 源码分析一
      参考URL: https://my.oschina.net/mengyuankan/blog/2874776
      Mybatis解析动态sql原理分析
      参考URL: https://www.cnblogs.com/fangjian0423/p/mybaits-dynamic-sql-analysis.html
      [推荐]【Mybatis源码分析】06-SqlSession执行过程之获取BoundSql代理对象
      参考URL: https://blog.csdn.net/shenchaohao12321/article/details/80008304

      通用Mapper Example类源码分析代码细节理解1. criteriacriteria英 [kraɪ’tɪərɪə] 美 [kraɪ’tɪrɪə]n. 标准,条件(criterion的复数)作者这里用 单词criteria 应该表达的是条件的意思,指sql where条件!...
      Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria 。    Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样, Crit
      单表查询 有类似这样的要求: select xxx from table_name where column1 = ? and column2 = ? and (column3 = ? or column4 = ? or column5 like ?) 使用...
      1.时间范围的查询,以及排序 Example example = new Example(xxxx.class); Example.Criteria criteria = example.createCriteria(); //获取1天前的date Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar...
      example实例解析 mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分 xxxExample example = new xxxExample(); Criteria criteria = new Example().createCriteria(); 方法 说明 example.setOrderByClause(“字段名 AS...
      一、什么是example类 mybatis-generator会为每个字段产生如上的Criterion,如果表的字段比较多,产生的Example类会十分庞大。理论上通过example类可以构造你想到的任何筛选条件。在mybatis-generator中加以配置,配置数据表的生成操作就可以自动生成example了。具体配置可以参考MBG有关配置。 下面是mybatis自动生成example的使用。 二、了解example成员变量 //升序还是降序 //参数格式:字段+空格+asc(desc)
      注意。example没加条件:没写example.createCriteria(); 执行查询:selectByExample(example).====就会查询全部。 分类: 框架 Mybatis逆向工程会生成实例及实例对应的example(用于添加条件,相当于where后的部分) xxxExample example = new xxxExample(); Criteria criteria = example.createCriteria(); 方法说明: 1.添加升序排列条件,DESC为降序
      在查询方法 设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结: Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria 。 Criteria 和 DetachedCriteria 的...
      import org.apache.ibatis.session.SqlSession; import org.junit.Assert; import org.junit.Test; import tk.mybatis.mapper.entity.Example; import tk.mybatis.m...
      通用Mapper 通用 Mapper4 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及Example 相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。 只能解决单表操作,不能进行表连接 1.1MBG与通用Mapper
      ### 回答1: Mybatis通用Mapper是一个基于Mybatis框架的插件,它可以帮助我们快速地进行数据库操作,避免了手写SQL的繁琐和容易出错的问题。使用Mybatis通用Mapper,我们只需要定义好实体类和Mapper接口,就可以直接调用通用的增删改查方法,非常方便。 具体使用方法如下: 1. 引入Mybatis通用Mapper的依赖包,可以通过Maven或者Gradle进行引入。 2. 定义实体类,需要注意的是实体类的属性名要和数据库表的字段名一致,或者使用@ColumnName注解进行映射。 3. 定义Mapper接口,继承通用Mapper接口,例如: public interface UserMapper extends Mapper<User> {} 4. 在Mybatis的配置文件中配置通用Mapper插件,例如: <plugins> <plugin interceptor="tk.mybatis.mapper.plugin.MapperInterceptor"> <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/> </plugin> </plugins> 5. 在代码中调用通用Mapper的方法,例如: @Autowired private UserMapper userMapper; public void addUser(User user) { userMapper.insert(user); 以上就是Mybatis通用Mapper的使用方法,它可以大大简化我们的开发工作,提高开发效率。 ### 回答2: Mybatis通用Mapper是一个基于Mybatis的通用Mapper插件。它提供了单表的增删改查操作,同时还支持通用的批量操作和条件查询等功能。在使用Mybatis通用Mapper时,我们不需要编写繁琐的Mapper接口和对应的XML文件,只需要使用注解即可完成对数据库的操作。 首先,我们需要在pom.xml文件中添加Mybatis通用Mapper的依赖: <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>4.1.5</version> </dependency> 接下来,我们需要在Mybatis的配置文件中添加通用Mapper的配置: <plugins> <plugin interceptor="tk.mybatis.mapper.common.MapperInterceptor"> <property name="mappers" value="tk.mybatis.mapper.common.BaseMapper"/> </plugin> </plugins> 完成以上操作后,我们就可以在项目中使用Mybatis通用Mapper了。例如,我们要对一个用户表进行操作,可以创建一个User实体类: public class User { private Integer id; private String username; private String password; private String email; // 省略getter和setter方法 然后,我们通过注解在UserMapper接口中定义对用户表的操作: public interface UserMapper extends Mapper<User> { 这里的Mapper是Mybatis通用Mapper提供的一个接口,通过继承该接口,我们可以直接使用其中定义好的单表操作方法。 接下来,我们就可以直接在代码中使用UserMapper了。例如,我们要插入一条用户记录,可以使用以下代码: User user = new User(); user.setUsername("test"); user.setPassword("123456"); user.setEmail("test@example.com"); userMapper.insert(user); 如果我们需要查询一条用户记录,可以使用以下代码: User user = new User(); user.setId(1); User result = userMapper.selectOne(user); 以上就是使用Mybatis通用Mapper的简单示例。在实际使用中,我们还可以通过注解实现复杂的批量操作和条件查询等功能,具体请参考Mybatis通用Mapper的官方文档。 ### 回答3: Mybatis通用mapper是基于Mybatis的一个工具,简化了Mybatis中XML配置的工作量,提供了一些通用的方法,能够简化我们的增删改查操作。下面简单介绍一下Mybatis通用mapper的使用方法。 一、引入依赖和配置 在pom文件中引入mybatis和通用mapper的依赖 <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>${mybatis-mapper.version}</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency> 在application.yml中进行相关配置 mybatis: #配置别名 type-aliases-package: com.xxxx.entity #配置xml映射文件路径 mapper-locations: classpath:mapper/*.xml mapper: #配置通用mapper的包路径 mappers: tk.mybatis.mapper.common.Mapper #配置实体类主键的生成策略 identity: mysql #配置mysql的方言,不配置通用mapper的分页插件会出错 dialect: mysql 二、编写实体类和Mapper接口 在编写实体类时,需要给实体类的属性加上@TableId和@Column注解,用来指明主键和列名。例如: @Data @Table(name = "user") public class User { @GeneratedValue(generator = "JDBC") @Column(name = "id") private Long id; @Column(name = "username") private String username; @Column(name = "password") private String password; @Column(name = "age") private Integer age; @Column(name = "email") private String email; 在编写Mapper接口时,直接继承Mapper<T>接口即可,T为对应的实体类。例如: @Repository public interface UserMapper extends Mapper<User> { 三、编写通用方法 Mybatis通用mapper提供了一些通用方法,例如插入数据、更新数据、删除数据和查询数据等。这些方法都可以直接调用或者根据需要进行封装。 (1)插入数据 使用通用mapper的插入方法,代码如下: User user = new User(); user.setUsername("testUser"); user.setPassword("123456"); user.setAge(20); user.setEmail("testUser@xx.com"); userMapper.insert(user); 使用通用mapper的批量插入方法,代码如下: List<User> userList = new ArrayList<>(); User user1 = new User(); user1.setUsername("testUser1"); user1.setPassword("123456"); user1.setAge(20); user1.setEmail("testUser@xx.com"); userList.add(user1); User user2 = new User(); user2.setUsername("testUser2"); user2.setPassword("123456"); user2.setAge(21); user2.setEmail("testUser@xx.com"); userList.add(user2); userMapper.insertList(userList); (2)更新数据 使用通用mapper的更新方法,代码如下: User user = new User(); user.setId(1L); user.setUsername("newTestUser"); userMapper.updateByPrimaryKey(user); (3)删除数据 使用通用mapper的删除方法,代码如下: userMapper.deleteByPrimaryKey(1L); (4)查询数据 使用通用mapper的查询方法,代码如下: User user = userMapper.selectByPrimaryKey(1L); 使用通用mapper的查询所有数据方法,代码如下: List<User> userList = userMapper.selectAll(); 使用通用mapper的条件查询方法,代码如下: Condition condition = new Condition(User.class); condition.createCriteria().andEqualTo("username", "testUser"); List<User> userList = userMapper.selectByExample(condition); 以上就是使用Mybatis通用mapper的一些常用方法,它们都能够简化我们的开发工作。当然,如果有需要,我们还可以自己封装一些方法来实现更加灵活和高效的操作。
 
推荐文章
重情义的跑步鞋  ·  mac更新c++编译器 - CSDN文库
9 月前
高大的灌汤包  ·  怎么用python实现电脑cpu温度监控_百度知道
1 年前
腼腆的滑板  ·  Python3-定时任务四种实现方式_51CTO博客_python 定时任务
1 年前
英俊的汤圆  ·  What causes a Status Code of 0 indicating ReqCancelled?
2 年前
善良的勺子  ·  Overview of update channels for Microsoft 365 Apps - Deploy Office | Microsoft Learn
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号