MySQL day03

金融科技数据源 数字金融开放研究平台 阅读详情

MySQL

  • 回顾和提问
  1. 约束分类
  2. 条件判断有哪些
  3. 常用函数有哪些
  4. 如何添加约束
  5. 子查询的使用

二、本章任务

  1. 完成行转列
  2. 完成链接查询
  3. 完成导入和导出

三、本章目标

  1. 掌握链接查询的几种结构
  2. 掌握行转列语法
  3. 掌握数据库的导入和导出
  4. 了解java中备份和恢复数据库

四、知识点

1. 行转列

1.1 什么是行转列

正常的查询结果是这样

 

可是我想要的结果是这样...

 

通过SQL语句 实现这样的功能,就叫行转列

1.2示例数据准备

有 id,名字,课程,成绩

create table test_9(

       id int,

       name varchar(22),

       course varchar(22),

       score decimal(18,2)

);

insert into test_9 (id,name,course,score)values(1,'小王','java',99);

insert into test_9 (id,name,course,score)values(2,'小张','java',89.2);

insert into test_9 (id,name,course,score)values(3,'小李','java',88);

insert into test_9 (id,name,course,score)values(4,'小王','MySQL',92.2);

insert into test_9 (id,name,course,score)values(5,'小张','MySQL',42.2);

insert into test_9 (id,name,course,score)values(6,'小李','MySQL',59.2);

1.3场景一(多行转一行多列)

可以使用下面的SQL语句(group by 与 case when结合使用即可实现):

select name,max(

case course

when 'java' then score

end) Java, max(

case course

when 'MySQL' then score

end) MySQL

from test_9

group by name;

思路分析 :

首先我们默认的情况 每个名字都输出两次,而最终结果只有一次名字,所以肯定是 以名字分组 group by

select * from test_9 group by name;

对我们来说 ,id,课程,和分数都不需要了,只需要有名字 然后再把java和mysql放上去

select name , 1 as java , 1 as MySQL from test_9  group by name;

然后再使用聚合函数聚合(此处理解“聚合”,相当于把多行数据压扁成一行)

select name,max(

case course

when 'java' then score

end) Java, max(

case course

when 'MySQL' then score

end) MySQL

from test_9

group by name;

演示示例:多行转一行多列

1.4场景二(多行转一行一列)

 

相关函数

concat(值,’拼接符’,值 ) : 拼接,多行数据只会拼接一行

group_concat(值,’拼接符’,值 ) : 拼接,多行压扁到一行

思路分析 :

第一步:拆分问题,先按分组的思路

select name,1 as '各科成绩' from test_9 group by name;

 第二步:将课程名与成绩拼接成一列

select name,

    concat(course,'=',score) as '各科成绩'

    from test_9 group by name;

 第三步:利用group_concat函数将多行压扁到一行

select name,

    group_concat(course,'=',score) as '各科成绩'

    from test_9 group by name;

 第四步:修改分隔符(默认是逗号)

select name,

    group_concat(course,'=',score separator ' | ') as '各科成绩'

    from test_9 group by name;

 第五步:按课程名称排序

select name,

    group_concat(course,'=',score order by course asc  separator ' | ') as '各科成绩'

    from test_9 group by name;

演示示例:多行转一行一列

  1.  DQL-连接查询

2.1 笛卡尔积

笛卡尔积,也有的叫笛卡尔乘积

多表查询中,链接的where限定条件,不能少于 表的个数-1 , 否则就会发生笛卡尔乘积 , 这个限定条件并不是随便一个限定条件,而是用于维护映射两个表的条件,比如 外键

笛卡尔乘积是一个很消耗内存的运算,笛卡尔积产生的新表,行数是原来两个表行数的乘积,列数是原来两个表列数的和。所以我们在表连接时要使用一些优化手段,避免出现笛卡尔乘积。

最简单的多表查询 : select * from 表1,表2;

示例数据 :

create table teacher(

    id int ,

    name varchar(20),

    primary key (id)

);

create table student (

    id int ,

    name varchar(20),

    teacher_id int ,

    primary key (id),

    foreign key (teacher_id) references teacher(id)

);

insert into  teacher (id,name) values(1,'张老师');

insert into  teacher (id,name) values(2,'王老师');

insert into  student (id,name,teacher_id) values(1,'小明',1);

insert into  student (id,name) values(2,'小红');

insert into  student (id,name,teacher_id) values(3,'小黑',2);

每个行都有两次

如果直接就是写的select * from teacher,student; ,那么 结果的条数等于两个表的乘积

所以 判断条件最少也要是1个,也就是两个表的个数-1

 

条数对了,因为小红没有teacher_id所以不会被查询出来

虽然条数对了,但是也会先发生一个完全的笛卡尔乘积,然后在新视图中找匹配的数据,再展示匹配的数据,会消耗内存一些

所以不推荐使用,推荐使用链接查询

演示示例:多表查询

课堂练习1:多表查询

优化上面的笛卡尔乘积的方式 :

优化一:使用等值连接条件,比如上面的where s.teahcer_id = t.id。

优化二:能使用inner join的就不要使用left join。

优化三:使用记录数更少的表当左表。

但是如果业务上有要求:

比如,我们有一张用户的基本信息表,我们还有一张用户的订单表

现在我们要求在页面上展示,所有用户的订单记录

这种情况下我们就必须使用left join了,因为inner join 会丢数据

假设基本信息表中有A B C三个用户(3条记录)

订单表中有A B两个人的100条订单记录

这种情况下,我们除了使用left join外,还必须要让基本信息表当左表,订单表当右表。

MYSQL支持的表连接查询有inner join,left join,right join(right join我们工作中基本不用)。

2.2 inner join

插入一条示例数据

INSERT INTO teacher (`id`, `name`) VALUES ('3', '孙老师');

1

select *

from teacher tea

inner join student stu on tea.id = stu.teacher_id;

2

select *

from student stu

inner join teacher tea on tea.id = stu.teacher_id;

总结 :

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用 join 连接查询 时,on和where条件的区别如下:
       1、on条件是在生成临时表时使用的条件,需要和链接查询一起使用。
       2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

链接查询,会发生笛卡尔乘积,但是不是完全的笛卡尔乘积,在生成视图的时候,会进行匹配,不符合条件的就不要了

结果数据是以左表数据为准,先生成左表数据,再生成右表数据

使用内连接的话,会以左边表为基准(student),生成新视图的时候,先生成左边表中的数据,然后再去匹配右边表中是否有符合条件的,没有的话,就不生成这一行

同时左表中有的,右表中没有的数据,都不会生成

右表中有的,左表中没有的也一样不会生成,所以 左表和右表就算换了位置,数据行数不会变多

但是会丢失数据,不符合 条件的数据不会查询出来,所以 刚添加的 孙老师就不会查询出来的,就算是teacher表在左边,也一样不会查询出来孙老师,并且学生小红也没有被查询处理

因为学生表中 teacher_id列 没有保存孙老师的ID,并且小红也没有保存老师的ID,所以都不要

多表查询是有左右表之分的,一般左表是主表,以左边为主

Inner join  也可以直接写join 不写inner

演示示例:inner join

2.3 left join

left join on : 左连接,又称左外链接,是 left outer join 的简写 ,使用left join 和 使用 left outer join 是一样的效果

1 查询结果,显示小红,但是不显示孙老师

select * from student s

    left join teacher t on s.teacher_id = t.id;

2 查询结果显示孙老师,但是不显示小红

select * from teacher t

    left join student s on s.teacher_id = t.id;

总结 :

以左边的表为基准,左表中数据都有,右表中不符合条件的就没有,就在指定列上用null代替

生成视图的时候,也是先生成左表的数据

演示示例:left join

2.4 right join

right join on : 右链接,又称右外连接,是 right outer join 的简写,使用right join 和 使用 right outer join 是一样的

1 查询结果,显示孙老师,但是不显示小红

select * from student s

    right join teacher t on s.teacher_id = t.id;

2 查询结果显示小红,但是不显示孙老师

select * from teacher t

    right join student s on s.teacher_id = t.id;

总结 :

以右表为基准,右表中数据都有,左表中不符合条件的就没有,就在指定列上用null代替

但是视图生成的时候,还是会先生成左表数据

以上可以看出,student right join teacher 显示的内容是与teacher left join student相同的。而teacher right join student 显示的内容又与student left join student相同。

所以,我们工作中,right join基本不用。用的最多的是inner join 与left join。

PS:外键与表连接没有任何关系,不要混淆。

外键是为了保证你不能随便删除/插入/修改数据,是数据完整性的一种约束机制。

而表连接是因为一张表的字段无法满足业务需求(你想查的字段来自于2张甚至多张表)

一个是为了增删改,一个是为了查,它俩之间没有联系。

能使用 inner join 就不使用 left join

            能使用 left join 就不使用 right join

演示示例:right join

2.4 模拟Oracle中的full join

上面几个链接查询中

inner是两个表都符合条件的数据

left join 是 左表都有,右表符合条件才有

right join 是 右表都有,左表符合条件才有

那么能不能让两个表,别管符合不符合,都有呢?

full join / full outer join ,但是MySQL这里给取消了,比如Oracle就有

模拟一下 full join 的功能

使用 union 获取并集

select * from student s

    left join teacher t on s.teacher_id = t.id

union

select * from student s

    right join teacher t on s.teacher_id = t.id;

 

演示示例:full join

课堂练习2:链接查询

  1.  数据库导入和导出

3.1 使用Navicat数据导入和导出

导出

使用Navicat最为简单

右键要导出的表或者数据库,

转储SQL文件,

仅结构 是只有创建表/数据库 语句,没有数据

结构和数据 是有创建语句,也有数据

 

然后会生成一个sql文件

 

导入

右键数据库

运行 SQL文件

 

会弹出一个窗口

 

选择完成之后会有相应的地址填写进去

 

点击开始就行

 

然后刷新一下表/数据库就可以了

课堂练习3:使用Navicat数据导入和导出

3.2 使用CMD数据导入和导出

导出

打开CMD控制台 进入到 MySQL安装路径下的bin目录下

 

或者直接在地址地方输入cmd,如下图

也可以直接打开

mysqldump -u用户名 -p密码  需要导出的数据库 > d:\tianliang.sql(导出的文件的保存位置)

-u用户名 -p密码 要备份的数据库, > 是把文件保存到哪里, < 是文件在哪里导进来

执行命令 mysqldump -uroot -proot _06_> d:\tianliang.sql

就被导出了

导入

还是进入到bin目录下

 mysql -u用户名 -p密码  导入到哪个数据库< d:\tianliang.sql(被导入的文件路径)

-u用户名 -p密码  需要导入的数据库  需要导入的sql文件

执行命令 mysql -uroot -proot _06_< d:\tianliang.sql

 

导入完成

课堂练习4:使用CMD数据导入和导出

3.3 使用Java执行CMD数据导入和导出

演示示例:MySQLUtil

4. JDBC介绍

我们之前学习MYSQL时,为了使用MYSQL服务,我们通常要使用客户端与MYSQL服务进行连接,然后才能输入SQL语句进行数据库的各种操作。客户端有命令行与图形界面2种。

但是在更多的环境下,由我们人直接操作数据是很低效的,比如双11这种业务场景下,一秒中往往要在库中生成上千万甚至几亿条数据,靠人来手工操作是不现实的,只能依赖于程序进行这种高并发的操作。

程序语言有多种,比如Java、Python、C/C++等,程序语言如果想执行SQL语句,也必须要先与数据库进行连接,数据库也有多种,比如MySQL、Oracle、SQL Server等。

不同的程序语言去连接不同的数据库,如果没有一个统一的标准或者规范,肯定是相当混乱的。Java语言对此的解决方案就是JDBC。

JDBC定义了一套规范标准,它对应的是各种接口与抽象类(通常对应java.sql包下面的各种类与接口),具体实现交给各数据库厂商去完成, MySQL的有自己的实现类并打成jar包发布,供程序开发人员使用;Oracle也有自己的实现jar包。

我们开发人员在使用的时候,要根据连接数据库的不同,去对应的官网上下载对应数据库版本与程序语言的数据库驱动(Java语言对应的是一个jar包)。(比如我们使用MySQL 5.1,就要去MySQL官网下载Java语言对应的jar包)

JDBC : Java DataBase Connectivity  (java数据库链接)

  是让java链接数据库的API

API : Application Programming Intergace (应用程序接口)

    就是函数库

所以 JDBC 就是提供java连接数据库的应用程序接口的,只是接口或者抽象类

而JDBC就是java中提供的一个规范,基本都是接口和抽象类作为父类,具体的实现,是数据库厂商去弄的,只不过这些厂商需要按照我的接口标准来实现

如果我们要想操作数据库,就需要把厂商开发的实现类,导入进来

然后在项目上右键  ->  Build Path  ->  Configure Build Path...,将之加入我们项目的CLASSPATH。

5. JDBC使用步骤

第0步: 导包

第1步:注册驱动 (仅仅做一次)

  第2步:建立连接(Connection)

  第3步:创建运行SQL的语句(Statement)

  第4步:运行语句

  第5步:处理运行结果(ResultSet)

第6步:释放资源

其中 如果是添加,删除,更新操作,可以没有第5步,查询肯定会有第五步

5.0 导包

创建java项目

创建lib文件夹

把mysql-connector-java-5.1.38-bin.jar复制到lib中

右键  ->  Build Path  -> Add to Build Path

5.1 注冊驱动

创建java类 JDBC_01_Base_DQL

Class.forName("com.mysql.jdbc.Driver");

5.2 建立连接(Connection)

第一个参数是url

jdbc:mysql://IP:端口/数据库

第二个参数是数据库用户名

第三个参数是数据库密码

5.3 创建运行SQL的语句(Statement)

5.4 运行语句

   

5.5 处理运行结果(ResultSet)

while (rs.next()) {

           //  在循环遍历中,把数据取出来

           System.out.print(rs.getInt("id") + "    ");

       // 如果传入是整型值 就会获取对应的列,比如下面 就是获取第一列的值,不建议使用

           System.out.print(rs.getInt(1) + "    ");

           System.out.print(rs.getString("id") + "  ");

           // 字符串不能用int来接收,除非这个 字符串是纯数字

           // System.out.print(rs.getInt("name") +"    ");

           System.out.print(rs.getString("name") + "  ");

           System.out.print(rs.getString("course") + "  ");

           System.out.print(rs.getDouble("score")+"  ");

           // 3 对应的是name列,如果更改表结构,把name列放到第四位了,那么这里就获取不到name了

           // 所以 不灵活,不推荐使用

           System.out.println(rs.getString(3));

       }

5.6 释放资源

先打开的资源后关闭

演示示例:JDBC_01_Base_DQL_00

课堂练习1:使用JDBC查询test_jdbc表

6 代码优化

上面程序中,有可能会导致释放资源出现问题

比如查询语句写错了等,这时候会抛出异常,那么关闭语句就不会执行

所以我们应该使用try...catch...finally来优化一下

以刚才的练习为例,对test_jdbc表的查询进行优化

       Connection conn = null;

       Statement stmt = null;

       ResultSet rs = null ;

       try {

           // 1 加载驱动

           Class.forName("com.mysql.jdbc.Driver");

           // 2 创建数据库连接对象

           // 导包使用的都是java.sql的

            conn = DriverManager.getConnection(

                  "jdbc:mysql://127.0.0.1:3306/_06_", "root", "root");

          

           // 3 创建语句传输对象

              String sql = "select * from test_jdbc";

               stmt = conn.createStatement();

             

              // 4 接收数据库结果集

               rs = stmt.executeQuery(sql);

              while (rs.next()) {

                  //  在循环遍历中,把数据取出来

                  System.out.print(rs.getInt("id") + "    ");

                  System.out.print(rs.getString("name") + "  ");

                  System.out.println(rs.getDouble("money")+"  ");

              }

      

       } catch (Exception e) {

           e.printStackTrace();

       }finally{

           try {

              if (rs != null) {

                  rs.close();

              }

              if (stmt != null) {

                  stmt.close();

              }

              if (conn != null) {

                  conn.close();

              }

           } catch (SQLException e) {

              e.printStackTrace();

           }

       }

   

演示示例:JDBC_01_Base_DQL_01

7 DML

Data Manipulation Language : 数据操作语言

涉及的关键字有 : delete,update,insert

和查询的操作几乎一样,就是把第4步和第5步更改一下

       Connection conn = null;

       Statement stmt = null;

       ResultSet rs = null;

       try {

           // 1 加载驱动

           Class.forName("com.mysql.jdbc.Driver");

           // 2 创建数据库连接对象

           conn = DriverManager.getConnection(

                  "jdbc:mysql://127.0.0.1:3306/_06_", "root", "root");

           // 3 语句传输对象

           stmt = conn.createStatement();

           String sql = "insert into test_jdbc (id,name,money) values (4,'小小',999.9)";

           // sql = "update test_jdbc set money=money+1000 where id=1 ";

           // sql = "delete from test_jdbc where id = 1";

           // 如果是查询,就返回true,不是就返回false,价值不大,所以用的不多,添加,删除,更新都可以用这个方法

           // stmt.execute(sql);

           // 返回值是int,返回影响了几条数据(更改了几条/删除了几条/添加了几条),添加,删除,更新都可以用这个方法

           int count = stmt.executeUpdate(sql);

           System.out.println("影响了 " + count + " 条数据");

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           try {

              // 关闭资源,从上到下依次关闭,后打开的先关闭

              if (rs != null) {

                  rs.close();

              }

              if (stmt != null) {

                  stmt.close();

              }

              if (conn != null) {

                  conn.close();

              }

           } catch (Exception e2) {

              e2.printStackTrace();

           }

       }

    演示示例:JDBC_02_DML

8. PreparedStatement

添加或者更新的时候,尽量使用 PreparedStatement ,而不是使用Statement

  Statement 和 PreparedStatement 的区别

 

  Statement用于执行静态SQL语句,在执行的时候,必须指定一个事先准备好的SQL语句,并且相对不安全,会有SQL注入的风险

 

  PreparedStatement是预编译的SQL语句对象,sql语句被预编译并保存在对象中, 被封装的sql语句中可以使用动态包含的参数 ? ,

  在执行的时候,可以为?传递参数

 

  使用PreparedStatement对象执行sql的时候,sql被数据库进行预编译和预解析,然后被放到缓冲区,

  每当执行同一个PreparedStatement对象时,他就会被解析一次,但不会被再次编译 可以重复使用,可以减少编译次数,提高数据库性能

  并且能够避免SQL注入,相对安全(把’ 单引号 使用 \ 转义,避免SQL注入 )

8.1 DQL

    使用PreparedStatement 执行查询

public static void load(int id) {

       Connection conn = null;

       PreparedStatement prst = null;

       ResultSet rs = null;

       try {

           // 1 加载驱动

           Class.forName("com.mysql.jdbc.Driver");

           // 2 创建数据库连接对象

           conn = DriverManager.getConnection(

                  "jdbc:mysql://127.0.0.1:3306/_06_", "root", "root");

           // 这里我们用? 问号代替值,可以叫占位符,也可以叫通配符

           String sql = "select * from test_jdbc where id = ?";

           // 3 语句传输对象

           prst = conn.prepareStatement(sql);

           // 设置第一个?的值

           prst.setInt(1, id);

           rs = prst.executeQuery();

           while (rs.next()) {

              System.out.print(rs.getInt("id") + "   ");

              System.out.print(rs.getString("name") + "   ");

              System.out.println(rs.getString("money") + "   ");

           }

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           try {

              // 关闭资源,从上到下依次关闭,后打开的先关闭

              if (rs != null) {

                  rs.close();

              }

              if (prst != null) {

                  prst.close();

              }

              if (conn != null) {

                  conn.close();

              }

           } catch (Exception e2) {

              e2.printStackTrace();

           }

       }

    }

演示示例:JDBC_03_PreparedStatement_load

8.1 DML

使用PreparedStatement 执行增删改,以添加为例

    public static void add(int id, String name, double money) {

       Connection conn = null;

       PreparedStatement prst = null;

       try {

           // 1 加载驱动

           Class.forName("com.mysql.jdbc.Driver");

           // 2 创建数据库连接对象

           conn = DriverManager.getConnection(

                  "jdbc:mysql://127.0.0.1:3306/_06_", "root", "root");

           // 这里我们用? 问号代替值,可以叫占位符,也可以叫通配符

           String sql = "insert into test_jdbc (id,name,money) values (?,?,?)";

           // 3 语句传输对象

           prst = conn.prepareStatement(sql);

           // 设置第一个?的值

           prst.setInt(1, id);

           prst.setString(2, name);

           prst.setDouble(3, money);

           // 返回也是影响的条数

           int count = prst.executeUpdate();

           System.out.println("影响了 "+count+" 条数据");

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           try {

              // 关闭资源,从上到下依次关闭,后打开的先关闭

              if (prst != null) {

                  prst.close();

              }

              if (conn != null) {

                  conn.close();

              }

           } catch (Exception e2) {

              e2.printStackTrace();

           }

       }

    }

演示示例:JDBC_03_PreparedStatement_add

9. 封装工具类

主要针对2个方面进行改进封装。

以下的代码我们每个方法中都会重复一次,这是没必要的,因为不同的方法其实只是具体执行的SQL语句的内容不同,对于获取连接与释放资源,对应的逻辑是相同的。我们完全可以把这一段逻辑抽取出来,形成独立的类与方法,再在实际应用时调用对应的类和方法就可以了。

1 创建连接这些

2 关闭资源这些

创建链接这些可以这样进行优化

    public static Connection getConnection() throws ClassNotFoundException,

           SQLException {

       String username = "root";

       String password = "root";

       String url = "jdbc:mysql://127.0.0.1:3306/_06_";

       Class.forName("com.mysql.jdbc.Driver");

       Connection connection = DriverManager.getConnection(url, username,

              password);

       return connection;

    }

关闭资源这些可以这样进行优化

因为Connection和Statement/PreparedStatement以及ResultSet都实现了AutoCloseable接口

所以我们可以直接写AutoCloseable

    public static void close(AutoCloseable obj) {

       if (obj != null) {

           try {

              obj.close();

           } catch (Exception e) {

              e.printStackTrace();

           }

       }

    }

演示示例:DBUtil和JDBC_04_TestDBUtil

课堂练习2:使用DBUtil对test_jdbc表进行增删改查各一次

10. Batch多语句操作

  在一次任务中,执行多条数据

10.1 Statement实现

       Connection conn = null;

       Statement stmt = null;

       try {

           conn = DBUtil.getConnection();

           stmt = conn.createStatement();

           stmt.addBatch("insert into test_jdbc (id,name,money) values(21,'stmt多条测试1',99.12)");

           stmt.addBatch("insert into test_jdbc (id,name,money) values(22,'stmt多条测试2',99.22)");

           stmt.addBatch("insert into test_jdbc (id,name,money) values(23,'stmt多条测试3',99.32)");

           stmt.addBatch("insert into test_jdbc (id,name,money) values(24,'stmt多条测试4',99.42)");

           stmt.executeBatch();

           System.out.println("执行成功");

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           DBUtil.close(stmt);

           DBUtil.close(conn);

       }

    演示示例:JDBC_05_Batch_Statement

10.2 PreparedStatement实现

       Connection conn = null;

       PreparedStatement prst = null;

       try {

           conn = DBUtil.getConnection();

           String sql = "insert into test_jdbc (id,name,money) values(?,?,?)";

           prst = conn.prepareStatement(sql);

           prst.setInt(1, 31);

           prst.setString(2, "prst多条测试1");

           prst.setDouble(3, 11.1);

           prst.addBatch();

           prst.setInt(1, 32);

           prst.setString(2, "prst多条测试2");

           prst.setDouble(3, 21.1);

           prst.addBatch();

           prst.setInt(1, 33);

           prst.setString(2, "prst多条测试3");

           prst.setDouble(3, 31.1);

           prst.addBatch();

           prst.executeBatch();

           System.out.println("执行成功");

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           DBUtil.close(prst);

           DBUtil.close(conn);

       }

       演示示例:JDBC_05_Batch_PreparedStatement

课堂练习3:使用Batch对test_jdbc表进行多行数据增删改各一次

JQ8900语音播报模块在RT-Thread系统下的驱动移植与测试详解 本文详细讲解了如何在RT-Thread嵌入式操作系统中,为JQ8900语音播报模块进行驱动移植与功能测试。内容涵盖从获取驱动代码、配置Kconfig工程、编译烧录到核心代码解析的完整流程,并提供了基于串口通信的上电测试与问题排查方法,帮助开发者快速掌握在RT-Thread系统下集成外部模块的核心技能。 阅读详情

相关推荐

Python量化投资入门教程:从零构建你的第一个交易策略

量化投资教程以数学模型和计算机程序实现超额收益,选用Python工具链完成数据获取、策略构建及回测。通过移动平均线交叉策略示例,展示数据预处理、信号生成、收益计算及可视化全流程,结合收益率、最大回撤和夏普比率评估策略,并建议参数优化与策略融合提升稳健性。

ylmx5201314的博客 2456

“/”与“\”以及“//”与“\\”之间的区别

/ 正斜杠 表示除法,分隔。在windows系统中通常用来分隔命令行参数,/ 表示选项等。不能作为文件名isiss/。 正斜杠"/"在某些文档里面表示“或”,如通讯方式GSM/GPRS/3G,表示采用其中一种通讯方式。 \ 反斜杠 在windows系统中,\ 用来表示目录。 而在unix系统中,/ 表示目录。 由于web遵循unix命名,所以在网址(URL)中,/ 表示目录。 ...

570的博客 9万+

从Microchip SDK到STM32实战:手把手教你移植LAN9252 EtherCAT从站驱动(含EEPROM配置避坑)

本文详细介绍了如何将Microchip SDK中的LAN9252 EtherCAT从站驱动移植到STM32F407平台,包括FSMC接口配置、中断处理适配和EEPROM配置等关键步骤。通过实战指南和避坑技巧,帮助开发者快速实现高性能EtherCAT从站设备的开发,适用于工业自动化领域。

weixin_29197835的博客 446

文件路径中的/,\和\\的区别

系统不同、共享文件不同、网址访问不同。 “\“:Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不混淆,所以采用 反斜杠\ 作为路径分隔符。 “./”:代表目前所在的目录 “…/”:代表上一层目录 以"/"开头:代表根目录 ...

赤蓝基族长 6万+

将Apollo高精地图中的车道线叠加在多种导航地图上

本文介绍了将Apollo高精地图车道线叠加到普通导航地图的技术方案。高精地图具备厘米级车道精度和丰富的语义信息,叠加可实现可视化验证、调试分析和数据对比等功能。核心技术包括坐标系统转换(UTM/WGS84/BD09/GCJ02)和数据处理流程,通过Python脚本完成Apollo地图解析、坐标批量转换和多格式输出。文章详细提供了环境准备、工作目录创建和坐标转换脚本等操作步骤,实现了高精地图数据在OpenStreetMap、百度地图和高德地图上的可视化展示。

Hi20240217的博客 1333

微信聊天记录数据库解密实战:从WCDB到sqlcipher4的关键步骤解析

本文详细解析了微信桌面版聊天记录数据库的解密实战过程。通过逆向分析,定位了微信从WCDB框架到sqlcipher4加密的关键步骤,并成功提取了数据库密钥。文章重点介绍了如何通过动态调试、字符串定位等方法,追踪并验证sqlcipher4的加密密钥,最终实现对加密数据库文件的解密操作,为安全研究和数据恢复提供了技术参考。

weixin_29322553的博客 1071

文件路径问题的基础知识、/”、“\”与“\\”三种符号的区别

而在程序中,字符串中的“\\”主要是为了转义,“\\”转义后被理解为“\”,如果是 / 就不需要使用转义了。a.指本地目录的,在不同系统的情况: windows下是\,linux和unix下是/".."(两个点,即两个英文句号),代表上一级目录。"."(一个点,即英文句号),代表当前目录。"/"(斜杠),代表根目录。b.网络路径使用的是/

LMH564123的博客 3万+

各种AI的调试日记——辅助工作篇

记录使用各种AI(语言大模型)的心得和总结

m0_73056986的博客 1391

'/',‘\\’与‘\’的区别

‘/’,‘//’与‘\’作用 ‘/’,‘//’与‘\’在计算机语言中一般是除法和分割的意思,操作系统常使用他们来分割不同级别的目录 ‘/’与‘\’区别 ‘/’,与‘\’最常见于文件路径(指文件存储的位置)和网址中如:C:\Users\del\Desktop\1.zip,C:/Users/el/Desktop/1.zip和https://blog.youkuaiyun.com/a1111h C:\U...

a1111h的博客 4万+

Lmbench测试集 --- 延迟测试工具lat_mem_rd

lmbench测试集简介 以及 lat_mem_rd延迟测试工具: 如何测试、测试结果、源码分析

MonologueYY的博客 1万+

苹果生态最佳搭档:Mac mini + OpenClaw + iPhone 远程控制

本文详细介绍如何通过iPhone远程控制Mac mini上的OpenClaw应用,打造高效苹果生态工作流。内容包括:1) 苹果生态整合优势,包括AirDrop、Handoff等功能对比;2) Mac mini配置步骤,涵盖SSH/VNC设置、网络优化及Docker部署OpenClaw;3) iPhone端SSH/VNC客户端选择与Tailscale内网穿透配置;4) 详细SSH密钥设置与连接测试方法。通过这套方案,用户可实现跨设备无缝控制OpenClaw应用,提升远程工作效率。(149字)

一键难忘的博客 793

文件路径中,“/”、“\”与“\\”三种符号的区别

熟悉的Linux系统使用的,表示path。1、/出现在计算机中,一般情况如下。本人目前在python中使用的情况。windows系统中表示的路径。2、\出现在计算机中。

qq_44808875的博客 9万+

通过傅里叶变换进行音频变声变调

在游戏或者一些特殊场景下为了提高娱乐性或者保护声音的特征,我们会对音频进行变声变调处理。

yang1fei2的博客 1817

Mysql高级-day03

Mysql高级-day03 1. 应用优化 前面章节,我们介绍了很多数据库的优化措施。但是在实际生产环境中,由于数据库本身的性能局限,就必须要对前台的应用进行一些优化,来降低数据库的访问压力。 1.1 使用连接池 对于访问数据库来说,建立连接的代价是比较昂贵的,因为我们频繁的创建关闭连接,是比较耗费资源的,我们有必要建立 数据库连接池,以提高访问的性能。 1.2 减少对MySQL的访问 1.2.1 避免对数据进行重复检索 在编写应用代码时,需要能够理清对数据库的访问逻辑。能够一次连接就获取到结果的,就不用两

MARSHCW的博客 375

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

mysql-day03笔记

文章目录1、insert 语句一次插入多条记录2、快速创建表3、将查询结果插入到一张表当中(insert)4、快速删除表中的数据4.1、使用 truncate 语句删除数据:5、对表结构的增删改?6、约束 * * * * *6.1、什么是约束?6.2、约束包括哪些?6.3、非空约束:not null6.4、唯一性约束:unique6.5、主键约束(primary key,简称PK)* * * * *6.6、外键约束(foreign key,简称FK) * * * * *7、存储引擎(了解)7.1、什么是存储

kitty_Happy的博客 2436

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

MYSQL day03

MySQL-Day03笔记1、索引 1、BTREE 2、优点 :加快数据的检索速度 3、缺点  1、需动态维护,占用系统资源,降低数据维护速度  2、占用物理存储空间 4、索引示例  1、开启运行时间检测 :set profiling=1;   备注 :show variables like "profiling";  2、执行查询语句   select name from t1 where na...

qq_42371362的博客 192

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

day03 MySQL函数&DCL&JDBC

1.概述: mysql是独立于java语言之外的,但是将来我们写的sql语句要放到java语言中,那么如何将mysql和java语言连接起来,就需要使用JDBC技术JDBC是一种标准,一种规则,主要作用是使用java语言操作数据库的JDBC这个标准中有很多的接口,接口中有很多方法初始化配置容器:创建Properties对象。定位配置文件:通过类加载器找到。加载配置内容:将文件内容解析为键值对。注册数据库驱动:确保能识别驱动。提取连接参数:为后续创建数据库连接做准备。//添加用户@Test。

u010297404的博客 1166

mysql_day03总结

本文摘要: 本课程系统介绍了MySQL运维相关内容,主要包括日志管理、主从复制、分库分表和读写分离四大模块。日志管理部分详细讲解了错误日志、二进制日志、查询日志和慢查询日志的作用及配置;主从复制章节阐述了原理、配置步骤及常见问题;分库分表部分通过MyCat中间件实现,讲解了垂直/水平拆分方式及多种分片算法;读写分离部分涵盖一主一从和双主双从架构搭建。课程通过理论讲解与实践操作结合,帮助掌握MySQL高可用架构设计与实现,解决大数据量场景下的性能瓶颈问题。(149字)

mrjieke6的博客 988

MySQL高级-Day03toStudents

MySQL-Day02必须掌握 外键 原理 让当前表字段的值在另一张表的范围内去选择 使用规则 1、数据类型要一致 2、主表被参考字段必须为KEY的一种 : PRI 级联动作 1、cascade : 删除 更新同步(被参考字段) 2、restrict(默认) : 不让主表删除 更新 3、set null : 删除 更新,从表该字段值设置为NULL 嵌套查询(子查询) 定义 把内层的查询结果作...

huhaidi123的博客 357

MySQL知识_day03

数据库(DataBase)知识学习 一、数据库和数据库管理系统: 1、数据库:数据库(Database)是按照数据结构来组织、存储和管理数据的仓库, 数据库管理系统:数据库管理系统(database management system简称dbms),是一种操纵和管理数据库的 大型软件,用于建立、使用和维护数据库 常用的数据库: 1、

神秘人998的博客 815

MySQL学习day03

MySQL学习day03一、约束(非常重要,五颗星*****)1、什么是约束?2、约束包括哪些?3、非空约束:not null4、唯一性约束: unique5、主键约束(primary key,简称PK)1、主键约束的相关术语?2、什么是主键?有啥用?3、怎么给一张表添加主键约束呢?4、可以这样添加主键吗,使用表级约束?5、表级约束主要是给多个字段联合起来添加约束?6、一个表中主键约束能加两个吗?7、主键值建议使用:int bigint char 等类型。不建议使用:varchar来做主键。主键值一般

shujiaw的博客 375

MySQL高级学习笔记-day03

Mysql高级-day03 MySQL高级部分学习笔记,该笔记仅供学习参考。 1.应用优化 前面章节,我们介绍了很多数据库层面的优化措施。但是在实际生产环境中由于数据库本身性能局限,就必须要对前台的应用进行一些优化,来降低数据库的访问。 1.1使用连接池 对于范文数据库来说,简历联结的代价是比较昂贵的,因为我们频繁的创建关闭联结,是比较耗费资源的,我们有必要建立数据库连接池,以提高访问的性能。 1.2减少对MySQL的访问 1.2.1避免对数据进行重复检索 在编写应用代码时,需要能够理清对数据库的访问逻辑。

String小四的博客 598

mysql day03

insert into zhl_users values(100, '周宏亮', md5('123456'));select * from zhl_users where name = '周宏亮' and pwd = md5('123456');插入后查询看到的密码是经过md5加密后的。

aoligei98的博客 1223

MySQL学习之路--Day03

从零到熟悉MySQL,虽然一路上磕磕绊绊,但终有收获~

CXY_DXL的博客 1415

day03 mysql

使用数据库可以高效的有条理的储存数据: 1、可以结构化存储大量的数据, 2、可以有效的保持数据的一致性、完整性。 lSQL分类: n数据定义语言:简称DDL(Data Definition Language),用来定义数据库对象:数据库,表,列等。关键字:create,alter,drop等 n数据操作语言:简称DML(Data Manipulation Language),用...

okbin1991的博客 94
上一篇: My SQL day02
下一篇: MySQL JDBC
java_yangXL
博客等级 码龄5年 1粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值