学习

mybatis-plus-sgg-19-39

通用Service应用 #

  • 这里会出现 publicKey is now allowed ,在数据库连接语句后面加上这句话即可 allowPublicKeyRetrieval=true

    spring:
      #配置数据源
      datasource:
        #配置数据源类型
        type: com.zaxxer.hikari.HikariDataSource
        #配置数据源各个信息
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&&useSSL=false&&allowPublicKeyRetrieval=true
        username: root
        password: 123456
    
  • 查询

        @Test
        public void testList(){
            //List<User> list = userService.list();
            long count = userService.count();
            System.out.println("总条数:"+count);
        }
    

    SQL执行语句

    ==>  Preparing: SELECT COUNT( * ) FROM user
    ==> Parameters: 
    <==    Columns: COUNT( * )
    <==        Row: 5
    <==      Total: 1
    
  • 批量添加

        @Test
        public void batchInsert(){
            List<User> users=new ArrayList<>();
            for(int i=0;i<10;i++){
                User user=new User();
                user.setName("name"+i);
                user.setEmail("email"+i);
                users.add(user);
            }
    
            boolean b = userService.saveBatch(users);
            System.out.println("result:"+b);
        }
    

    sql日志输出

    ...

mybatis-plus-sgg-12-18

BaseMapper #

  • 注:使用 mvn dependency:resolve -Dclassifier=sources 来获得mapper源码

  • 一些接口介绍

        /**
         * 插入一条记录
         *
         * @param entity 实体对象
         */
        int insert(T entity);
    
        /**
         * 根据 ID 删除
         *
         * @param id 主键ID
         */
        int deleteById(Serializable id);
    
        /**
         * 根据实体(ID)删除
         *
         * @param entity 实体对象
         * @since 3.4.4
         */
        int deleteById(T entity);
    
        /**
         * 根据 columnMap 条件,删除记录
         *
         * @param columnMap 表字段 map 对象
         */
        int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
    
        /**
         * 根据 entity 条件,删除记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
         */
        int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 删除(根据ID或实体 批量删除)
         *
         * @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
         */
        int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);
    
        /**
         * 根据 ID 修改
         *
         * @param entity 实体对象
         */
        int updateById(@Param(Constants.ENTITY) T entity);
    
        /**
         * 根据 whereEntity 条件,更新记录
         *
         * @param entity        实体对象 (set 条件值,可以为 null)
         * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
         */
        int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
    
        /**
         * 根据 ID 查询
         *
         * @param id 主键ID
         */
        T selectById(Serializable id);
    
        /**
         * 查询(根据ID 批量查询)
         *
         * @param idList 主键ID列表(不能为 null 以及 empty)
         */
        List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    
        /**
         * 查询(根据 columnMap 条件)
         *
         * @param columnMap 表字段 map 对象
         */
        List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
    
        /**
         * 根据 entity 条件,查询一条记录
         * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
            List<T> ts = this.selectList(queryWrapper);
            if (CollectionUtils.isNotEmpty(ts)) {
                if (ts.size() != 1) {
                    throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records");
                }
                return ts.get(0);
            }
            return null;
        }
    
        /**
         * 根据 Wrapper 条件,判断是否存在记录
         *
         * @param queryWrapper 实体对象封装操作类
         * @return
         */
        default boolean exists(Wrapper<T> queryWrapper) {
            Long count = this.selectCount(queryWrapper);
            return null != count && count > 0;
        }
    
        /**
         * 根据 Wrapper 条件,查询总记录数
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 entity 条件,查询全部记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 Wrapper 条件,查询全部记录
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 Wrapper 条件,查询全部记录
         * <p>注意: 只返回第一个字段的值</p>
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 entity 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        <P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
        /**
         * 根据 Wrapper 条件,查询全部记录(并翻页)
         *
         * @param page         分页查询条件
         * @param queryWrapper 实体对象封装操作类
         */
        <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
  • BaseMapper测试

    ...

mybatis-plus-sgg-01-11

简介 #

  • MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生
  • 这里以MySQL数据库为案例,以Idea作为IDE,使用Maven作为构建工具,使用SpringBoot完成各种功能
  • 课程主要内容 ly-20241212142149716
  • 特性 润物无声、效率至上、丰富功能
  • 支持的数据库 ly-20241212142149893
  • 框架结构 ly-20241212142149948
    • 左边:扫描实体,从实体抽取属性猜测数据库字段
    • 通过默认提供的方法使用sql语句,然后注入mybatis容器

开发环境 #

ly-20241212142150006

测试数据库和表 #

  • 这里创建数据库mybatis_plus

  • 然后创建表user

    DROP TABLE IF EXISTS user;
    
    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)
    );
    
  • 插入默认数据

    DELETE FROM user;
    
    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');
    

Spring Boot工程 #

添加依赖,并install Lombok 插件


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.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>3.5.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
    </dependencies>

基础配置 #

  • 创建spring boot启动类

    ...

算法红皮书 3.1.1-3.1.7

查找 #

  • 经典查找算法

  • 符号表这个词来描述抽象的表格,将信息(值)存储在其中,然后按照指定的来获取这些信息

  • 符号表也被称为字典

    • 在英语字典里,键就是单词,值就是单词对应的定义、发音和词源
    • 符号表有时又叫索引
    • 在一本书的索引中,键就是术语,而值就是书中该术语出现的所有页码
  • 下面学习三种经典的数据类型:二叉查找树、红黑树和散列表

符号表 #

  • 符号表最主要的目的是将联系起来

  • 用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键直接找到相对应的值

  • 符号表是一种存储键值对的数据结构,支持两种操作:插入(put),即将一组新的键值对存入表中;查找(get),即根据给定的键得到相应的值

  • 典型的符号表应用 ly-20241212142100034

API #

  • 符号表是一种典型的数据类型 :代表着一组定义清晰的值及相应的操作。使用应用程序编程接口(API)来精确地定义这些操作 一种简单的泛型符号表API ST(Symbol Table) ly-20241212142100261

  • 泛型 对于符号表,我们通过明确地指定查找时键和值的类型来区分它们的不同角色【key和value】

  • 重复的键

    • 这里假设每个键只对应着一个值(表中不允许重复值)
    • 当用例代码向表中存入的键值对和表中已有的键(及关联的值)冲突时,新的值会替代旧的值
    • 上述定义了关联数组的抽象形式,可以将符号表想象成数组,键即索引,值即数组中的值
    • 在一个关联数组中,键可以是任意类型,但我们仍然可以用它来快速访问数组的值
    • 非Java使用st[key]来替代st.get(key),用st[key]=val来替代st.put(key,val)
  • 键不能为空

  • 值不能为空(因为规定当键不存在时get()返回空) 当值为空表示删除

  • 删除操作

    • 延时删除,先将键对应的值置空,之后在某个时刻删除所有值为空的键

    • 即时删除,立即从表中删除指定的键 put实现的开头:

      if(val == null){
       delete(key);
       return;
      }
      
    • 便捷方法 ly-20241212142100362

    • 迭代 在API第一行加上implements Iterable<Key> ,所有实现都包含iterator()方法来实现hasNext()和next()方法的迭代器;这里采用另一种方式:定义keys返回一个Iterable<Key>对象以方便便利所有的键,且允许遍历一部分

    • 键的等价性 自定义的键需要重写equals()方法;且最好使用不可变数据类型作为键

有序符号表 #

  • 一种有序的泛型符号表的API ly-20241212142100464
  • 最大值和最小值、向下取整和向上取整、排名和选择
  • 对于0到size()-1的所有i都有i==rank(select(i)),且所有的键都满足key == select(rank(key))
  • 范围查找
  • 例外情况 当一个方法需要返回一个键但表中没有合适的键可以返回时,我们约定抛出一个异常
  • 有序符号表中冗余有序性方法的默认实现 ly-20241212142100610
  • 所有Comparable类型中compareTo()方法和equals()方法的一致性
  • ★★成本模型 在学习符号表的实现时,我们会统计比较的次数(等价性测试或是键的相互比较),在内循环**不进行比较(极少)**的情况下,我们会统计数组的访问次数

用例举例 #

如何使用

...

算法红皮书 2.5

  • 排序如此有用的原因是,在有序的数组中查找一个元素,要比在一个无序的数组中查找简单得多
  • 通用排序算法是最重要的
  • 算法思想虽然简单,但是适用领域广泛

将各种数据排序 #

  • Java的约定使得我们能够利用Java的回调机制将任意实现Comparable接口的数据类型排序

    • 我们的代码直接能够将String、Integer、Double 和一些其他例如File 和URL 类型的数组排序,因为它们都实现了Comparable 接口
  • 交易事务 商业数据的处理,设想一家互联网商业公司为每笔交易记录都保存了所有的相关信息

    public int compareTo(Transaction that)
    {
    	return this.when.compareTo(that.when);
    }
    
  • 指针排序 我们使用的方法在经典教材中被称为指针排序,因为我们只处理元素的引用而不移动数据本身

  • 不可变的键 用不可变的数据类型作为键,比如String、Integer、Double和File等

  • 廉价的交换

    • 使用引用的另一个好处是不必移动整个元素对于几乎任意大小的元素,使用引用使得在一般情况下交换的成本和比较的成本几乎相同(代价是需要额外的空间存储这些引用)

    • 研究将数字排序的算法性能的一种方法就是观察其所需的比较和交换总数,因为这里隐式地假设了比较和交换的成本是相同的

  • 多种排序方法

    • 根据情况将一组对象按照不同的方式排序。Java 的Comparator 接口允许我们在一个类之中实现多种排序方法
  • 多键数组

    • 一个元素的多种属性都可能被用作排序的键

      • 我们可以定义多种比较器,要将Transaction 对象的数组按照时间排序可以调用: Insertion.sort(a, new Transaction.WhenOrder()) 或者这样来按照金额排序: Insertion.sort(a, new Transaction.HowMuchOrder())
    • 使用Comparator的插入排序

      public static void sort(Object[] a, Comparator c)
      {
      	int N = a.length;
      	for (int i = 1; i < N; i++)
      	for (int j = i; j > 0 && less(Comparator, a[j], a[j-1]); j--)
      	exch(a, j, j-1);
      }
      private static Boolean less(Comparator c, Object v, Object w)
      {
      	return c.compare(v, w) < 0;
      }
      private static void exch(Object[] a, int i, int j)
      {
      	Object t = a[i];
      	a[i] = a[j];
      	a[j] = t;
      }
      
    • 使用比较器实现优先队列

      ...

算法红皮书 2.4

优先队列 #

  • 有些情况下,不需要要求处理的元素全部有序,只要求每次都处理键值最大的元素,然后再收集更多的元素,然后再处理键值最大的元素
  • 需要一种数据结构,支持操作:删除最大元素和插入元素,这种数据类型叫做优先队列
  • 优先队列的基本表现形式:其一或两种操作都能在线性时间内完成
  • 基于二叉堆数据结构的优先队列,用数组保存元素并按照一定条件排序,以实现高效的删除最大元素和插入元素

API #

  • 抽象数据类型,最重要的操作是删除最大元素和插入元素 delMax()和insert()

  • 用“最大元素”代替“最大键值”或是“键值最大的元素”

  • 泛型优先队列的API ly-20241212142058095

  • 优先队列的调用示例 从N各输入中找到最大的M各元素所需成本 ly-20241212142058324

    • 优先队列的用例 pq里面最多放5个,当大于5个的时候,就从中剔除1个

      public class TopM
      {
      	public static void main(String[] args)
      	{
      		// 打印输入流中最大的M行
      		int M = Integer.parseint(args[0]);
      		MinPQ<Transaction> pq = new MinPQ<Transaction>(M+1);
      		while (StdIn.hasNextLine())
      		{
      			// 为下一行输入创建一个元素并放入优先队列中
      			pq.insert(new Transaction(StdIn.readLine()));
      			if (pq.size() > M)
      			  pq.delMin();
      			// 如果优先队列中存在M+1个元素则删除其中最小的元素
      		}
      		// 最大的M个元素都在优先队列中
      		Stack<Transaction> stack = new Stack<Transaction>();
      		while (!pq.isEmpty()) stack.push(pq.delMin());
      		for (Transaction t : stack) StdOut.println(t);
      	}
      }
      
    • 应用 ly-20241212142058429

      ...

zsx_flowable_design01

  • 模型设计完后,下面三个表有变化

    ly-20241212142116933

    • act_cio_model ly-20241212142117063
    • act_cio_model_module_rel ly-20241212142117162
    • act_ge_bytearray ly-20241212142117254
  • 部署之后,四个表有变化 ly-20241212142117340

    • act_cio_deployment 多了39条记录 ly-20241212142117428

      ly-20241212142117516

    • act_ge_bytearray 多了两条记录 ly-20241212142117610

    • act_re_deployment 多了一条记录 ly-20241212142117704

    • act_re_procdef 多了一条记录 ly-20241212142117795

  • 流程开始运行

    • 下面只写上主要的几个表
    • 送审时这个结点只能选一个 ly-20241212142117883
    • 流程运行时变量表 ly-20241212142117970

linux_韩老师_28-39

文件目录 #

  • 用来定位绝对路径或相对路径 cd ~ 用来定位家目录 cd .. 返回上一级 cd - 返回上一次目录

  • mkdir 用于创建目录 mkdir -p hello/l1/l2 多级目录创建

  • recursion 递归 rm -rf 要删除的目录 #递归删除

  • 使用cp进行复制,加上 -r 进行递归复制

  • rm 删除某个文件(带提示)

    • rm -f 删除文件(不带提示)
    • rm -rf 强制删除递归文件(夹)
  • mv 用来重命名(移动到同一目录下)、(或者移动文件)

  • 注意,下面的命令,是将hello移动到hello2下,并改名为a(而不是hello2下的a目录) mv Hello.java hello2/a

    • mv Hello.java hello2/a/ 移动到hello2下的a目录下(最后有一个斜杠)
  • 移动目录

    • mv hello2 hello1/AB 或者 mv hello2/ hello1/AB

      或者 mv hello2/ hello1/AB/

      会把整个hello2文件夹(包括hello2)移动到AB下

    • 同样是上面的指令,如果AB不存在,那么就会将hello2移动到hello1下,并将hello2文件夹,改名为AB

  • cat 指令

    • cat -p /etc/profile 浏览并显示文件
    • 管道命令 cat -p /etc/profile | more 把前面的结果再交给more处理 (输入enter查看下一行,空格查看下一页)
  • less指令

    ...

linux_韩老师_21-33

用户管理 #

  • 使用ssh root@192.168.200.201进行服务器连接 ly-20241212142135612

  • xshell中 ctr+shift+r 用来重新连接

  • 用户解释图 ly-20241212142135812

  • 添加一个用户milan,会自动创建该用户的家目录milan

    • 当登录该用户时,会自动切换到家目录下 ly-20241212142135882
  • 指定家目录 ly-20241212142135954

  • 指定密码 ly-20241212142136024

  • 用milan登录,自动切换到/home/milan pwd:显示当前用户所在的目录

    ly-20241212142136094

  • 用户删除

    • 删除用户但保留家目录
      • 需要用超级管理员才能删除 ly-20241212142136163 使用su -u root切换到超级管理员
      • 先logout然后再删除 ly-20241212142136235
    • 删除用户及家目录 userdel -r milan
    • 建议保留家目录
  • 查询root用户信息

    • 使用id xx 查询 ly-20241212142136305
  • 切换用户 su - xx

    • 从权限高切换到权限低的用户不需要密码;反之需要 ly-20241212142136377
    • 使用logout(exit也行),从root用户回到jack
  • 查看当前用户 who am i ly-20241212142136445 即使切换了用户,返回的还是root(第一次登录时的用户) ly-20241212142136517

  • 用户组(角色)

    • 增加、删除组

      groupadd wudang
      groupdel wudang
      

      如果添加用户的时候没有指定组,那么会创建一个跟用户名一样的名字的组 ly-20241212142136586 id是1002,组为king

      ly-20241212142136655

    • 添加用户zwj,添加组wudang,并将zwj添加到wudang组里面

      groupadd wudang
      useradd -g wudang zwj
      

      ly-20241212142136719

      ...

官方的hello-world

简介 #

  • MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

快速开始 #

  • 数据库的Schema脚本 resources/db/schema-mysql.sql

    DROP TABLE IF EXISTS user;
    
    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)
    );
    
  • 数据库Data脚本 resources/db/data-mysql.sql

    DELETE FROM user;
    
    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');
    
  • 创建一个spring boot工程(使用maven)

    • 父工程

      <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.7.0</version>
          <relativePath/>
      </parent>
      
    • springboot 相关仓库及mybatis-plus、mysql、Lombok相关仓库引入

      
          <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>3.5.1</version>
              </dependency>
      
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
              <dependency>
                  <groupId>com.h2database</groupId>
                  <artifactId>h2</artifactId>
                  <scope>runtime</scope>
              </dependency>
              <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.29</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.18.24</version>
                  <scope>provided</scope>
              </dependency>
      
          </dependencies>
      
    • 配置resources/application.yml文件

      ...