JDBC基础内容

news2024/9/21 0:33:35

JDBC的概念:

JDBC就是使用java语言操作关系数据库的一套API,全称为(java DataBase Connectivity)-----java数据库连接.

JDBC的本质:

是由sun公司定义的一套操作所有关系型数据库的规则,即接口,各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

JDBC好处:

各数据库厂商使用相同的接口,java代码不需要针对不同数据库分别开发

可随时替换底层数据库,访问数据库的java代码基本不变

同一套java代码,操作不同的关系型数据库:

在这里插入图片描述

使用JDBC的步骤:

a:创建工程,导入驱动jar包

创建新工程,对工程进行配置:

在这里插入图片描述

创建新模块:

在这里插入图片描述
用于存放jar包:

在这里插入图片描述

将下载好的jar包直接复制到lib下:

在这里插入图片描述

注意,jar一定要放在src下面,别放错啦

编写代码:

package MyJDBC;

import java.sql.*;

public class myjdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //获取连接
        String url="jdbc:mysql://localhost:3306/已创建好的数据库名";
        String username="root";
        String password="你的数据库密码";
        Connection connection= DriverManager.getConnection(url,username,password);

        //定义SQL
        String sql="update person set age=19 where id=2";

        //获取执行SQL的对象Statement
        Statement statement=connection.createStatement();

        //执行sql
        int count_row=statement.executeUpdate(sql);

        //释放资源
        statement.close();
        connection.close();

    }
}

执行完代码之后,在mysql中查询数据的变化情况:

注意:数据库以及表的创建等工作,一定要提前在mysql中完成

在这里插入图片描述
注意:

注册驱动 Class.forName("com.mysql.cj.jdbc.Driver");//mysql5以上的版本,该行代码可以不写,也不会报错

原因是下述文件已经为我们写了该驱动,因此可以自动加载驱动类:

在这里插入图片描述

JDBC API:

DriverManager:

注册驱动 Class.forName("com.mysql.cj.jdbc.Driver");

查看Driver源码:

在这里插入图片描述

获取连接:

//url:连接路径,user:用户名,password:密码
static Connection    getConnection(String url,String user,String password);

url:

语法:

jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...

举例:

//localhost:表示本机  3306:是mysql服务器默认的端口号  person:数据库名称
jdbc:mysql://localhost:3306/person

注意:

如果连接的是本机mysql服务器,并且mysql服务器默认端口为3306,则URL可以简写为:jdbc:mysql:///数据库名称?参数键值对

配置useSSL=false参数,表示禁用安全连接方式,解决警告提示

Connection:

获取执行SQL的对象:

普通执行SQL对象:

Statement createStatement();

预编译SQL的执行SQL对象:防止SQL注入

PreparedStatement prepareStatement(sql)

执行存储过程的对象:

CallableStatement prepareCall(sql)

事务管理:

MySQL事务管理:

开启事务:begin/start transaction;
提交事务:commit;
回滚事务:rollback;

mysql默认自动提交事务

JDBC事务管理:Connection接口中定义了三个对应的方法

开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务
提交事务:commit()
回滚事务:roolback();
package MyJDBC;
import java.sql.*;
public class myjdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        //获取连接
        String url="jdbc:mysql://localhost:3306/MyJDBC";
        String username="root";
        String password="xxx";
        Connection connection= DriverManager.getConnection(url,username,password);

        //定义SQL
        String sql1="update person set age=24 where id=1";
        String sql2="update person set age=22 where id=2";

        //获取执行SQL的对象Statement
        Statement statement=connection.createStatement();

        //执行sql
        try {
            //开启事务
            connection.setAutoCommit(false);
            
            int count_row1=statement.executeUpdate(sql1);
			System.out.println(count_row1);
			int count_row2=statement.executeUpdate(sql2);
            System.out.println(count_row2);
       
            //提交事务
            connection.commit();//未出现异常则提交事务否则事务回滚
        } catch (Exception throwables ) {
            //回滚事务
            connection.rollback();
            throwables.printStackTrace();
        }
        //释放资源
        statement.close();
        connection.close();
    }
}

ide输出:

在这里插入图片描述

mysql数据库中:

数据发生更新!

在这里插入图片描述

当发生异常时:

在这里插入图片描述
idea输出:

在这里插入图片描述

mysql中的数据情况:

数据并没有更新!

在这里插入图片描述

Statement:

statement的作用:

执行SQL语句

int executeUpdate(sql):执行DML,DDL语句

//返回值:
(1)DML语句影响的行数
(2)DDL语句执行后,执行成功也可能返回0

注:
DML数据操纵语言:对数据库中的数据进行一些简单操作,如insert、delete、update、select等。DML操作是可以手动控制事务的开启、提交和回滚的

DDL数据定义语言:对数据库中的某些对象(例如database、table)进行管理,如create、alter和dropDDL操作是隐性提交的,不能rollback

执行DML语句:

包括增删改,这里我们以修改作为例子进行讲解

举例:

package MyJDBC;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class myjdbc_test {
   //单元测试:必须导入junit,快速导入的方法:Alt+回车,点击junit4,注意必须在联网环境下
   @Test
   public void test_demo() throws ClassNotFoundException, SQLException {
      //注册驱动
      Class.forName("com.mysql.cj.jdbc.Driver");

      //获取连接
      String url="jdbc:mysql://localhost:3306/myjdbc";
      String username="root";
      String password="xxx";
      Connection connection= DriverManager.getConnection(url,username,password);
      //定义SQL
      String sql="update person set age=18 where id=2";
      //获取执行SQL的对象Statement
      Statement statement=connection.createStatement();
      //执行sql
      int count_row=statement.executeUpdate(sql);
      System.out.println(count_row);
      //释放资源
      statement.close();
      connection.close();

   }
}

输出:

在这里插入图片描述

在mysql中查询数据:

在这里插入图片描述

当所修改的数据不存在时:

在这里插入图片描述

虽然这样能够正确的修改结果,但并不是最优方案,因为输出的影响行数对于用户来说,没有任何意义,因此,我们需要将输出影响行数的内容修改为提示信息。

修改如下:

将输出影响行数的代码修改为如下代码:

if(count_row>0){
         System.out.println("修改成功");
      }else{
         System.out.println("修改失败");
      }

当要修改的数据不存在时,就会提示修改失败的信息:

在这里插入图片描述

执行DDL语句:

将myjdbc_test做如下修改:

在这里插入图片描述

在mysql中进行查询:

在这里插入图片描述

删除刚创建的数据库:

package MyJDBC;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class myjdbc_test {
   //Alt+回车,注意必须在联网环境下
   @Test
   public void test_demo() throws ClassNotFoundException, SQLException {
      //注册驱动
      Class.forName("com.mysql.cj.jdbc.Driver");
      //获取连接
      String url="jdbc:mysql://localhost:3306/?";
      String username="root";
      String password="xxx";
      Connection connection= DriverManager.getConnection(url,username,password);
      //定义SQL
      String sql="drop database myjdbc1";
      //获取执行SQL的对象Statement
      Statement statement=connection.createStatement();
      //执行sql
      int count_row=statement.executeUpdate(sql);
      System.out.println(count_row);
      //释放资源
      statement.close();
      connection.close();

   }
}

idea输出:

在这里插入图片描述
虽然返回值为0,但是在mysql中进行查询,我们会发现该数据库已经成功被删除,因为DDL语句执行后,执行成功也可能返回0,正是由于这个原因,所以我们不能像上面执行DML语句一样,通过返回值来判断是否成功。

在这里插入图片描述

判断DDL语句是否执行成功的方法很简单,只要未报错即认为执行成功;

举例:

在这里插入图片描述

ResultSet:

ResultSet[结果集对象]作用:

ResultSet  executeQuery(sql):执行DQL语句[数据查询语句]

//返回值:ResultSet结果集对象

获取查询结果:

boolean next():
1:将光标从当前位置向前移动一行
2:判断当前行是否为有效行
//返回值:
true:有效行,当前行有数据
false:无效行,当前行没有数据

如下所示:

在这里插入图片描述

光标需要从上到下依次判断当前行是否有效,因此,判断数据是否有效的过程是一个循环的过程:

while(rs.next()){
//获取数据
rs.getXXX(参数);
}
xxx getXXX(参数):获取数据
xxx:数据类型,如int getInt(参数):String getString(参数)
参数:int:列的编号,从1开始  String:列的名称

举例:

package MyJDBC;
import org.junit.Test;

import java.sql.*;

public class myjdbc_test {
   //Alt+回车,注意必须在联网环境下
   @Test
   public void test_demo() throws ClassNotFoundException, SQLException {
      //注册驱动
      Class.forName("com.mysql.cj.jdbc.Driver");
      //获取连接
      String url="jdbc:mysql://localhost:3306/myjdbc";
      String username="root";
      String password="xxx";
      Connection connection= DriverManager.getConnection(url,username,password);

      //定义SQL语句
      String sql="select * from person";

      //获取statement对象
      Statement statement=connection.createStatement();

      //执行SQL
      ResultSet resultSet=statement.executeQuery(sql);

      //处理结果,遍历resultSet中的所有数据

      //光标移动到下一行,并且判断当前行是否有数据
      while(resultSet.next()){
      //第一种写法:
         int id=resultSet.getInt(1);
         int age=resultSet.getInt(2);
         String name=resultSet.getString(3);
      //第二种写法:
      		//int id=resultSet.getInt("id");
         //int age=resultSet.getInt("age");
         //String name=resultSet.getString("name");
         System.out.println(id);
         System.out.println(age);
         System.out.println(name);
         System.out.println("--------------------------");
      }
      //关闭资源
      resultSet.close();
      statement.close();
      connection.close();
   }
}

输出:

1
24
张三
--------------------------
2
18
李军
--------------------------
3
24
张伟
--------------------------

ResultSet简单应用:

要求:查询person账户表数据,封装为Person对象中,并且存储到ArrayList集合当中

步骤:

a:定义实体类person

package pdjo;

public class Person {
//注意:这里的字段要和数据库中的表的字段对应
    private int id;
    private int age;
    private  String name;
    public void setId(int id) {
        this.id = id;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

b:查询数据,封装到person对象中,将person对象存入ArrayList集合中

package pdjo;

import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
    public class myjdbc_test {
        @Test
        public void test_demo() throws ClassNotFoundException, SQLException {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接
            String url="jdbc:mysql://localhost:3306/myjdbc";
            String username="root";
            String password="xxx";
            Connection connection= DriverManager.getConnection(url,username,password);

            //定义SQL语句
            String sql="select * from person";

            //获取statement对象
            Statement statement=connection.createStatement();

            //执行SQL
            ResultSet resultSet=statement.executeQuery(sql);

            //创建集合
            List<Person> personList=new ArrayList<>();

            //处理结果,遍历resultSet中的所有数据
            //光标移动到下一行,并且判断当前行是否有数据
            while(resultSet.next()){
                //创建对象操作
                Person person=new Person();
                int id=resultSet.getInt("id");
                int age=resultSet.getInt("age");
                String name=resultSet.getString("name");
                //赋值操作
                person.setId(id);
                person.setAge(age);
                person.setName(name);
                //将对象放入集合
                personList.add(person);
            }
            //输出集合中的数据
            System.out.println(personList);
            //关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        }
    }

输出:

[Person{id=1, age=17, name='张三'}, Person{id=2, age=21, name='李军'}, Person{id=3, age=24, name='张伟'}, Person{id=3, age=19, name='lucy'}]

PreparedStatement:

PreparedStatement作用:

预编译SQL语句并执行:预防SQL注入问题

SQL注入:SQL注入是通过操作输入来修改事先定义好的SQL语句,用以到达执行代码对服务器进行攻击的方法

恶意的SQL语句会入侵数据库,甚至对数据库产生破坏:

String sql="select * from tb_name where name='"+varname+"' and password='"+varpassword+"'";

对于上述SQL语句,如果我们将' or 1=1 or ' 或者'or'1'='1作为varpassword传进来,那么无论用户名是什么,都会登录成功

举例:

package MyJDBC;
import pdjo.Person;

import java.sql.*;
public class myjdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //获取连接
        String url="jdbc:mysql://localhost:3306/MyJDBC";
        String username="root";
        String password="xxxx";
        Connection connection= DriverManager.getConnection(url,username,password);

        //接收用户输入:用户名和密码
        String name="张三";
        String pwd="'or'1'='1";

        //定义SQL
        String SQL="select * from user_info where name='"+name+"' and password='"+pwd+"'";

        //获取Statement对象
        Statement Statement= connection.createStatement();
        ResultSet resultSet=Statement.executeQuery(SQL);

        //判断是否登录成功
        if(resultSet.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }

        //关闭资源
        resultSet.close();
        Statement.close();
        connection.close();

    }
}

输出:

在这里插入图片描述原因是:

  String SQL="select * from user_info where name='任意' and password=''or'1'='1'";

上述这条SQL语句'1'='1'一定成立,因此可以通过任何的验证,但是有些数据库是不会让这种恶意的SQL语句执行成功的,但也有很多数据库可以让这些语句得到执行,而如果使用预编译语句,传入的任何内容就不会和原来的语句发生任何匹配关系,只要安全使用预编译语句,就不需要对传入的数据做任何过滤。

通过PreparedStatement对象解决注入问题:

package MyJDBC;
import pdjo.Person;

import java.sql.*;
public class myjdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //获取连接
        String url="jdbc:mysql://localhost:3306/MyJDBC";
        String username="root";
        String password="xxx";
        Connection connection= DriverManager.getConnection(url,username,password);

        //接收用户输入:用户名和密码
        String name="lisa";
        String pwd="'or'1'='1";

        //定义SQL
        String SQL="select * from user_info where name='?' and password='?'";

        //获取Statement对象
        PreparedStatement preparedStatement= connection.prepareStatement(SQL);

        ResultSet resultSet=preparedStatement.executeQuery();

        //判断是否登录成功
        if(resultSet.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }

        //关闭资源
        resultSet.close();
        preparedStatement.close();
        connection.close();

    }
}

此时的密码依然是上述发生SQL注入问题的时的密码,但当对象为PreparedStatement,登录失败:

在这里插入图片描述

那么PreparedStatement对象是如何解决这个注入问题呢?

将特殊字符进行转义操作

转义前:

在这里插入图片描述

转义后:

在这里插入图片描述

1:获取PreparedStatement对象:

//sql语句中的参数值,使用?占位符替代
String SQL="select * from user where username=? and password=?";
//通过Connection对象获取,并传入对应的SQL语句
PreparedStatement pstmt=conn.preparedStatement(sql); 

2:设置参数值

PreparedStatement对象:setXXX(参数1,参数2,参数3…):给?赋值
XXX:

数据类型:如setInt(参数1,参数2)

参数:

参数1:?的位置编号,从1开始
参数2:?的值

执行SQL:

executeQuery();不需要再传递SQL
package MyJDBC;
import pdjo.Person;

import java.sql.*;
public class myjdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //获取连接
        String url="jdbc:mysql://localhost:3306/MyJDBC";
        String username="root";
        String password="xxx";
        Connection connection= DriverManager.getConnection(url,username,password);
        //定义SQL
        String SQL="insert into person(id,age,name) values(?,?,?)";
        //获取Statement对象
        PreparedStatement preparedStatement= connection.prepareStatement(SQL);

        //设置?的值:在设置时,数据类型一定要和数据库中表的字段类型一致
        preparedStatement.setInt(1,3);
        preparedStatement.setInt(2,19);
        preparedStatement.setString(3,"lucy");
        preparedStatement.executeUpdate();
        preparedStatement.close();
        connection.close();
    }
}

在数据库查询数据:

在这里插入图片描述

PreparedStatement原理:

PreparedStatement好处

预编译SQL,性能高,并且可以防止SQL注入,将敏感字符进行转义

PreparedStatement预编译功能开启:userServerPreStmts=true

配置mysql执行日志(重启MySQL服务器后生效):

mysql中的ini文件中编写如下代码:

log-output=FILE
general-log=1
general_log_file="D:\mysql.log"
slow-query-log=1
slow_query_log_file="D:\mysql_slow.log"
long_query_time=2

执行SQL语句,查看 D:\mysql.log 日志,即可发现SQL语句中的单引号都被加上了转义字符

PreparedStatement原理:

1:在获取PreparedStatement对象时,将SQL语句发送给mysql服务器进行检查,编译[耗时]
2:执行时就不用再进行这些步骤了,速度较快
3:如果SQL模板一样,则只需要进行一次检查,编译

举例:

未使用预编译

select * from tb_user where username='zhangsan';
select * from tb_user where username-'lisa';

使用编译

select * from tb_user where username=?;
setString(1,'zhangsan');
setString(1,'lisa');

第一种未使用预编译,那么程序每次运行都会经历检查SQL语法,编译SQL,执行SQL这三个步骤,但是使用预编译,前两个步骤只执行一次,此后只需要执行第三个步骤即可。

在这里插入图片描述

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

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

相关文章

更智能行车记录仪,4K画质超清晰,凌度行车记录仪 4K版上手

行车记录仪是很多车友的必需品&#xff0c;这两年行车记录仪的提升非常明显&#xff0c;如今市面上已经能够找到很多4K分辨率的产品了&#xff0c;相比于早期只要有480P分辨率的记录仪&#xff0c;清晰度和可靠性都更加出色&#xff0c;确实有升级的必要。 这两天我尝试了一款华…

P2141 [NOIP2014 普及组] 珠心算测验————C++

题目 [NOIP2014 普及组] 珠心算测验 题目描述 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术。珠心算训练&#xff0c;既能够开发智力&#xff0c;又能够为日常生活带来很多便利&#xff0c;因而在很多学校得到普及。 某学校的珠心算老师采用一种快速考…

基于python机器学习及深度学习在空间模拟与时间预测领域中的实践技术应用

机器学习 理论知识 1.1.1 课程目标 了解机器学习的发展历史、计算原理、基本定义&#xff0c;熟悉机器学习方法的分类&#xff0c;常用机器学习方法&#xff0c; 以及模型的评估与选择&#xff1b;熟悉数据预处理的流程&#xff0c;掌握 python 程序包的使用&#xff1b;理解机…

美国培生教育集团下PYP Readers系列的音乐是怎样制造的,读了吗?

很多小朋友都对音乐很感兴趣。 TA可能会喜欢Pop Music , 可能会喜欢Rap Music&#xff0c; 也可能会喜欢Rock&Roll...... 那么TA可能会想&#xff0c;这些音乐到底是怎样产生的呢&#xff1f; 没错&#xff0c;乐器&#xff08;Instrument&#xff09;&#xff01; 好书推荐…

【YOLO系列】YOLO V1论文总结

目标检测论文总结 【RCNN系列】 RCNN Fast RCNN Faster RCNN 【YOLO系列】 YOLO V1 文章目录目标检测论文总结前言一、Pipeline二、模型设计1.训练阶段2.损失函数2.1.框回归损失2.2.置信度损失2.3.分类损失总结前言 一些经典论文的总结。 一、Pipeline YOLO的pipeline很简单…

排查 Hive 任务导致磁盘写满的过程

计算的中间结果会写到 HDFS&#xff0c;如果用户写的SQL 有问题。如用户的 SQL 如下&#xff1a; select * from A join B where a.dt20230101 and b.dt20230101&#xff0c;如 A 表 dt20230101 分区 1000万行&#xff0c;B 表 dt20230101 有 1万行记录。由于 SQL 没有关联条件…

Druid 连接池技术的使用

文章目录官网链接连接性能消耗问题分析数据库连接池的作用市面常见连接池产品和对比国货之光druid连接池使用导入druid依赖硬编码方式&#xff08;了解&#xff09;软编码方式druid配置(了解)官网链接 http://www.apache-druid.cn/GettingStarted/chapter-1.html 连接性能消耗…

[Vue组件及组件之间的通信]一.Vue脚手架的使用;二.Vue的组件和组件之间的通信

目录 一.Vue脚手架的使用 1.通过命令行使用vue-cli的指令创建&#xff1a;vue init webpack 项目名称 2使用webStorm软件&#xff1a;本质仍然使用vue脚手架 3.使用vue ui创建&#xff1a;vue提供的图形化的操作界面 二.Vue的组件和组件之间的通信 1.组件&#xff1a;是vu…

数字签名与签名验证过程

1.1 生成数字签名 1 利用RSA算法生成公钥、私钥。私钥由密钥持有者自主保存&#xff0c;公钥可对外发布。 2 准备好待签名的文档。 3 利用哈希算法&#xff08;HASH&#xff09;&#xff0c;生成待签名文档的摘要。&#xff08;文档摘要&#xff09; 4 利用签名者的私钥&am…

谷粒学院——第十八章、统计分析

准备工作 需求分析 1、统计在线教育项目中&#xff0c;每一天有多少注册人数 2、把统计出来的注册人数&#xff0c;使用图表显示出来 创建数据库表 创建工程 service_statistics 配置文件 # 服务端口 server.port8008# 服务名 spring.application.nameservice-statistic…

Python基础(二十一):面向对象深入了解

文章目录 面向对象深入了解 一、魔法方法 1、__init__() 2、__str__() 3、__del__()

数据结构入门——二叉树(C语言实现)

数据结构入门——二叉树一. 树概念及结构1.1 树的概念1.2 树的相关概念1.3 树的表示1.4 树的应用二. 二叉树概念及结构2.1 二叉树的概念2.2 特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储结构三. 二叉树的顺序结构及其实现(堆的实现)3.1 二叉树的顺序结构3.2 堆的实现(以大堆为…

要想宝宝吃得好,粮仓就要保护好,做好3点保护粮仓,防止皲裂

众所周知&#xff0c;母乳喂养的妈妈并不容易&#xff0c;因为母乳喂养也有很多“难题”&#xff0c;也会很痛&#xff0c;比如开奶痛、挂奶、堵奶等&#xff0c;疼痛的程度不亚于子宫收缩。还有一个&#xff0c;牛奶&#xff0c;牛奶。.头皲裂的时候&#xff0c;真的是含泪喂奶…

Python实现可视化大屏数据

参考网址如下&#xff1a; 【Python】全网最新最全Pyecharts可视化教程(三)&#xff1a;制作多个子图_51CTO博客_python数据可视化pyecharts使用pyecharts拖拉&#xff0c;拽&#xff0c;创建大屏展示 - 简书 (jianshu.com) 智慧大屏是如何实现数据可视化的&#xff1f; - 知…

调查问卷考试问卷创建生成工具助手小程序开发

调查问卷考试问卷创建生成工具助手小程序开发 问卷调查考试软件&#xff0c;可以自由让每一个用户自由发起调查问卷、考试问卷。发布的问卷允许控制问卷的搜集、回答等各个环节的设置&#xff0c;同时支持系统模板问卷&#xff0c;选用模板问卷后可以一键创建属于自己的问卷&a…

JVM基础知识总结

日常工作中接触到的jvm相关的知识&#xff0c;和jvm相关书籍中汇总总结一下jvm相关基础知识&#xff0c;作为对jvm的了解。 文章目录jvm运行时数据区域程序计数器java虚拟机栈堆heap非堆内存 nonheap方法区直接内存 Direct Memory类加载机制类的加载过程类加载器加载过程的详细…

阿里云网络解决方案架构师任江波:全球一张网,支撑游戏业务高效互联

2022 年 8 月 30 日&#xff0c;阿里云用户组&#xff08;AUG&#xff09;第 9 期活动在北京举办。活动现场&#xff0c;阿里云网络解决方案架构师任江波&#xff0c;向参会企业代表分享了全球一张网&#xff0c;支撑游戏业务高效互联。本文根据演讲内容整理而成。 在座的很多我…

Web3中文|年度回顾:2022年Web3的发展情况

老生常谈的话题都有一个共同点&#xff0c;那就是它总是包含着一些无趣但至关重要的真理。例如&#xff0c;众所皆知天空是蓝色的&#xff0c;所以大家并不会把它纳入日常讨论&#xff0c;但这并不代表它对物理学、生物学和其他学科而言没有价值。 当我们回望2022年的Web3领域…

docker 部署maven服务器,并将代码发布到maven服务器,并kie-server关联

书接上文 已经搭建好了kie-server的docker swarm集群. 没有搭建business-central是集群是因为这是个页面的可视化的开发环境 一来面向开发人员,不需要集群部署 二来他的数据是放在本地的git服务器上的. 所以每个node的数据不会统一 三来部署好了之后页面也打不开… 四来busines…

推荐系统入门学习(一)【小白入门系列】

推荐系统入门学习&#xff08;一&#xff09; 前言&#xff1a;本博客不会采取大量的难懂的语言来介绍推荐系统&#xff0c;只会用一些简单的方式来介绍推荐系统&#xff0c;祝学习愉快&#xff01; 1、推荐系统的概念 简单的说&#xff0c;推荐系统则是将产品推荐给用户的一…