JDBC(数据库和Java)

news2024/9/23 15:24:24

JDBC

JDBC(Java数据库连接)是一种Java API(应用程序编程接口),允许Java程序与数据库交互。它提供了一个标准接口,用于从Java程序连接到关系数据库(如MySQL、Oracle和Microsoft SQL Server)并与之交互。JDBC允许您执行各种数据库操作,例如插入、更新和从数据库检索数据。它提供了一组类和接口,允许您连接到数据库、发送SQL语句和处理结果。JDBC是Java标准版(JavaSE)平台的一部分,广泛用于企业应用程序中的数据库连接。

前置知识:

  • 需要软件: mysql mysql可视化工具 idea
  • sql语句:掌握数据库连接命令;掌握基本的 DDL DML DQL等命令;掌握数据库事务的概念
  • Java基础语法:基本容器的使用(集合和数组);泛型;多态机制;反射技术。

学习知识体系:

  • 阶段一:jdbc版本和概念的理解
  • 阶段二:jdbc的核心使用
  • 阶段三:jdbc连接性能的优化 连接池的使用
  • 阶段四:jdbc使用优化工具高阶的封装
  • 阶段五:实践。

jdbc的技术和概念的理解

DBC(Java Database Connectivity)是Java语言中用于操作关系型数据库的一种API(Application Programming Interface)。它提供了一组Java接口,可以让Java程序与关系型数据库进行交互,包括连接数据库、执行SQL语句、处理结果等操作。

jdbc:Java database connetctivty Java连接数据库
jdbc是Java程序连接数据库技术的统称。
jdbc:是有Java语言的规范(接口)和各个数据库厂商的实现驱动组成。
jdbc是一种面向接口的编程
jdbc优势:
只要学习jdbc规范的方法,便可以操作所有的关系型数据库。
项目中要切换数据库软件,只需要更换对应的数据集驱动jar包,不需要更改代码。

JDBC的核心概念包括:

  1. JDBC驱动:JDBC驱动是一种软件组件,用于将JDBC API与特定数据库的实现相连接。JDBC驱动通常由数据库供应商提供,可以分为四种类型:JDBC-ODBC桥、本地API驱动、网络协议驱动和本地协议驱动。

  2. 连接:通过JDBC API,Java程序可以建立与数据库的连接。连接是一个重要的资源,需要在使用完成后关闭,以释放相关资源。

  3. Statement:Statement是执行SQL语句的接口,包括执行查询语句和更新语句等。Statement还可以设置参数和查询结果的处理方式。

  4. ResultSet:ResultSet是查询结果的接口,包含了查询返回的数据集。可以使用ResultSet来遍历查询结果,获取每一行的数据。

  5. 数据库事务:JDBC支持数据库事务的处理,可以通过Connection接口的begin、commit和rollback方法来实现事务操作。

  6. 数据源:数据源是一种JDBC的高级概念,它提供了一种池化的方式来管理JDBC连接。通过使用数据源,可以提高JDBC连接的效率和可靠性。

总之,JDBC是Java程序与关系型数据库进行交互的重要手段,理解JDBC的技术和概念对于Java程序员来说是非常必要的。

JDBC核心优势

  1. 可移植性: JDBC API 是标准的 Java API,因此可以在任何支持 JDBC 的平台上使用。这使得开发人员可以轻松地将应用程序从一个平台迁移到另一个平台。

  2. 安全性: JDBC API 提供了一种安全的方式来访问数据库。开发人员可以使用 JDBC API 来确保应用程序不会遭受 SQL 注入攻击等安全漏洞。

  3. 灵活性: JDBC API 允许开发人员使用任何数据库管理系统(DBMS)。开发人员可以使用 JDBC API 与任何 DBMS 进行交互,而不需要学习不同的 API。

  4. 性能: JDBC API 是一种高效的方式来访问数据库。开发人员可以使用 JDBC API 来执行高效的数据库操作,从而提高应用程序的性能。

  5. 可扩展性: JDBC API 提供了一种可扩展的方式来访问数据库。开发人员可以使用 JDBC API 来访问任何类型的数据库,包括关系型数据库、非关系型数据库、大数据存储系统等。

jdbc核心api和使用路线

jdbc技术的组成

1.jdbc的规范接口是包含在jdk中,存储在java.sql和Javax.sql包中。
2 jdbc的实现类是由各个数据库厂商提供,提供的是jar包,将这正jar 包称之为驱动

JDBC技术的组成包括以下几个部分:

  1. JDBC API:提供了访问数据库的标准接口,包括连接数据库、执行SQL语句、处理结果集等功能。

  2. JDBC Driver Manager:负责加载并管理JDBC驱动程序,通过它可以获取数据库连接。

  3. JDBC Driver:实现了JDBC API,用于与特定数据库进行通信。

  4. JDBC Test Suite:用于测试JDBC驱动程序的兼容性和性能。

  5. JDBC-ODBC桥接器:用于连接基于ODBC的数据库系统。

  6. SQL接口:用于执行SQL语句和管理数据库对象,如表、视图等。

  7. 数据源对象:用于管理数据库连接池,提高应用程序的性能和可靠性。

总之,JDBC技术的核心是JDBC API,而JDBC Driver Manager和JDBC Driver则是实现JDBC API的关键组件。其他组件如JDBC Test Suite和数据源对象等则是为了增强JDBC的功能和性能。

涉及的核心类和接口

JDBC涉及的核心类和接口如下:

  1. DriverManager:管理JDBC驱动程序的类。

  2. Connection:表示与数据库建立的连接。

  3. Statement:执行SQL语句的接口。

  4. PreparedStatement:预编译的SQL语句的接口。

  5. CallableStatement:调用存储过程的接口。

  6. ResultSet:表示查询结果集的接口。

  7. ResultSetMetaData:结果集的元数据接口。

  8. DatabaseMetaData:数据库元数据接口。

  9. SQLException:处理JDBC异常的类。

  10. Driver:JDBC驱动程序接口。

  11. Blob:二进制数据的接口。

  12. Clob:字符数据的接口。

  13. Savepoint:保存点的接口,表示事务中的一个特定点。

  14. DataSource:数据源接口,提供连接池和事务管理等功能。

  15. ConnectionPoolDataSource:连接池数据源接口,用于实现连接池。

  16. XADataSource:分布式事务数据源接口,用于实现分布式事务。

DriverManager

  • 将第三方数据库厂商实现的驱动jar包注册到程序中
  • 可以根据数据库连接信息获取Connection

Connction

  • 和数据库建立的连接,在连接对象上可以多次执行CRUD动作
  • 可以获取statement和preparedstatement,callablestatement对象

statement|preparedstatement|callablestatement

  • 发送具体的sql语句到数据库对象
  • 不同的是发送方稍有不同。

ResultSet

  • 抽象了数据的查询结果集
  • 存储了dql查询数据的结果对象
  • 需要我们对这个结果进行解析,获取具体的数据库中的数据

jdbc使用的路线

  • 静态sql(没有动态值的语句):DriverManager---->Connction—>Statement–>ResultSet
  • 预编译sql(有动态值的语句):
    DriverManager---->Connction—>Preparedstatement–>ResultSet
  • 执行存储过程的sql:DriverManager---->Connction—>Callablestatement–>ResultSet

jdbc的使用

配置jar包,导入到项目的lib目录中
在这里插入图片描述

jdbc的使用步骤

  1. 注册驱动
  2. 获取连接
  3. 创建发送sql语句的对象
  4. 发送sql 执行sql 斌返回结果
  5. 结果集的解析
  6. 释放资源

基于statement查询

基于statement查询是指使用Java程序中的Statement对象来执行SQL查询语句。Statement对象是Java程序中的一个接口,它允许程序员向数据库发送简单的SQL语句并获取结果。基于statement查询的优点是可以执行任何SQL语句,包括动态SQL语句。但是,基于statement查询也有一些缺点,比如容易受到SQL注入攻击,同时也不够灵活。在实际应用中,建议使用PreparedStatement对象来代替Statement对象进行查询操作,��提高代码的安全性和效率。

import com.mysql.cj.jdbc.Driver;

import java.sql.*;

/**
 * 1. 注册驱动
 *
 * 2. 获取连接
 *
 * 3. 创建发送sql语句的对象
 *
 * 4. 发送sql 执行sql 斌返回结果
 *
 * 5. 结果集的解析
 *
 * 6. 释放资源
 */
public class JDBCBaseDemo1 {
    public static void main(String[] args) throws SQLException {
// 1 注册驱动 Driver -->com.mysql.cj.jdbc.Driver;
//        DriverManager.registerDriver(new Driver());
        DriverManager.registerDriver(new Driver());
// 2. 获取连接
        Connection conn =
                DriverManager.getConnection("jdbc:mysql://localhost:3306/studydb","root","amp126578");
// 3 创建发送sql语句的对象
        Statement stmt = conn.createStatement();
// 4 发送sql语句
        String sql = "select id,name,age from emp ";
        ResultSet rs = stmt.executeQuery(sql);
// 5 解析得到结果集
        while(rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");


            System.out.println(id +"--"+name+"--"+age+"---");
        }
//6 释放资源 先开后关
        rs.close();
        stmt.close();
        conn.close();
    }
}
代码的重构:
public class JDBCBaseDemo1 {
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
@Before
public void start() throws SQLException {
// 1 注册驱动 Driver -->com.mysql.cj.jdbc.Driver;
DriverManager.registerDriver(new Driver());
// 2. 获取连接
Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/studydb","root","root");
// 3 创建发送sql语句的对象
stmt = conn.createStatement();
}
@After
public void destroy(){
//6 释放资源 先开后关
try {
if(rs !=null){
rs.close();
}
if(stmt != null){
stmt.close();
}
if(conn !=null){
conn.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Test
public void queryTest() throws SQLException {
// 4 发送sql语句
String sql = "select id,name,age,job,salary from emp where id= 1";
ResultSet rs = stmt.executeQuery(sql);
// 5 解析得到结果集
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");

System.out.println(id +"--"+name+"--"+age+"---");
}
}
@Test
public void insertTest() throws SQLException {
// 4 发送sql语句
String sql = "insert into emp(name,age,job,salary) values ('张三',22,)";
int rows = stmt.executeUpdate(sql);
// 5 解析得到结果集
System.out.println("受影响的行数:"+ rows);
}
@Test
public void updateTest() throws SQLException {
// 4 发送sql语句
String sql = "update emp set salary = 25000 where id = 23";
int rows = stmt.executeUpdate(sql);
// 5 解析得到结果集
System.out.println("受影响的行数:"+ rows);
}
@Test
public void deleteTest() throws SQLException {
// 4 发送sql语句
String sql = "delete from emp where id=23";
int rows = stmt.executeUpdate(sql);
// 5 解析得到结果集
System.out.println("受影响的行数:"+ rows);
}
}
*// 1* *注册驱动* *Driver -->com.mysql.cj.jdbc.Driver;
**// DriverManager.registerDriver(new Driver());

注册驱动的操作在8.0以后可以省略,当我们获取连接的时候,DriverManager会根据连接的url地址来自动
加载驱动。
url解析:
jdbc:mysql://localhost:3306/studydb
jdbc: 协议
mysql:子协议
localhost: 数据库服务器的地址
3306:mysql服务的端口
studydb: 要连接的数据库名称
加载和注册驱动的另外的方式:

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

在这里插入图片描述

public static void main(String[] args) throws SQLException {
// 1 让用户输入账户和密码
Scanner sc = new Scanner(System.in);
String username = sc.nextLine();
String password = sc.nextLine();
sc.close();
//2 通过账户和密码来查询用户是否存在
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "select * from users where username= '"+ username+ "' and
password='"+password+"'";
Statement stmt = conn.createStatement();
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
//3 判断查询的结果 如果查询结构不为null 就成功 否则就失败
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//4 释放资源
rs.close();
stmt.close();
conn.close();
}
}

在这里插入图片描述
通过以上代码,那么看到存在这一种风险:sql注入。系统存在安全隐患

preparedStatement

JDBC中的preparedStatement是一种预编译的SQL语句,用于执行SQL查询和更新。与普通的Statement不同,preparedStatement在执行时会将SQL语句预编译并缓存起来,这样可以避免重复编译SQL语句,提高了执行效率。此外,preparedStatement还支持参数绑定,可以在执行时动态地设置参数值,提高了代码的灵活性和安全性。

public static void main(String[] args) throws SQLException {
// 1 让用户输入账户和密码
Scanner sc = new Scanner(System.in);
String username = sc.nextLine();
String password = sc.nextLine();
sc.close();
//2 通过账户和密码来查询用户是否存在
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "select * from users where username=? and password=?";//?占位符
PreparedStatement pstmt = conn.prepareStatement(sql);//对sql语句进行预编译
//设置sql语句中的参数 参数从左到右 依次设置 索引从1开始
pstmt.setString(1,username);
pstmt.setString(2,password);
System.out.println(sql);
ResultSet rs = pstmt.executeQuery();
//3 判断查询的结果 如果查询结构不为null 就成功 否则就失败
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//4 释放资源
rs.close();
pstmt.close();
conn.close();
}
}
@Test
public void insertTest() throws SQLException {
//2 通过账户和密码来查询用户是否存在
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "insert into users(username,password) values(?,?)";//?占位符
PreparedStatement pstmt = conn.prepareStatement(sql);//对sql语句进行预编译
//设置sql语句中的参数 参数从左到右 依次设置 索引从1开始
pstmt.setString(1,"tom");
pstmt.setString(2,"321654");
System.out.println(sql);
int rs = pstmt.executeUpdate();
//4 释放资源
pstmt.close();
conn.close();
}

将查询的结果集封装成一个对象

package cn.sxjzit.domain;
public class User {
private int id;
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}}
public static void main(String[] args) throws SQLException {
// 1 让用户输入账户和密码
Scanner sc = new Scanner(System.in);
String username = sc.nextLine();
String password = sc.nextLine();
sc.close();
//2 通过账户和密码来查询用户是否存在
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "select * from users where username=? and password=?";//?占位符
PreparedStatement pstmt = conn.prepareStatement(sql);//对sql语句进行预编译
//设置sql语句中的参数 参数从左到右 依次设置 索引从1开始
pstmt.setString(1,username);
pstmt.setString(2,password);
System.out.println(sql);
ResultSet rs = pstmt.executeQuery();
//3 判断查询的结果 如果查询结构不为null 就成功 否则就失败
User user = null;
while(rs.next()){
user = new User();
user.setId(rs.getInt(1));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString(3));
}
if (user !=null){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//4 释放资源
rs.close();
pstmt.close();
conn.close();
}

作业:完成删除和更新

自增长主键回显的实现

public class JDBCBaseDemo3 {
public static void main(String[] args) throws SQLException {
//1 注册驱动 获取连接
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "insert into users(username,password) values(?,?)";
// 第二个参数 Statement.RETURN_GENERATED_KEYS 告诉statement携带回数据库生成的主键
PreparedStatement pstmt =
conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
// 参数赋值
pstmt.setString(1,"lucy");
pstmt.setString(2,"123456");
int rows = pstmt.executeUpdate();
System.out.println(rows);
// 获取新增记录的id值
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()){
int newId= rs.getInt(1);
System.out.println("newId=" + newId);
}
// 释放资源
pstmt.close();
conn.close();
}
}

批量插入数据

public class JDBCBaseDemo3 {
public static void main(String[] args) throws SQLException {
//1 注册驱动 获取连接
Connection conn =
DriverManager.getConnection("jdbc:mysql:///studydb","root","root");
String sql = "insert into users(username,password) values(?,?)";
// 第二个参数 Statement.RETURN_GENERATED_KEYS 告诉statement携带回数据库生成的主键
PreparedStatement pstmt =
conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
// 参数赋值
pstmt.setString(1,"lucy");
pstmt.setString(2,"123456");
int rows = pstmt.executeUpdate();
System.out.println(rows);
// 获取新增记录的id值
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()){
int newId= rs.getInt(1);
System.out.println("newId=" + newId);
}
// 释放资源
pstmt.close();
conn.close();
}
}

代码的优化重构

将建立连接和断开连接的重复代码集合成一块(形成一个工具类)

public class JDBCUtil {
//1 获取连接
public static Connection getConnection(){
Connection conn = null;
try {
conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/studydb","root","root");
} catch (SQLException e) {
throw new RuntimeException(e);
}
return conn;
}
//2 释放连接
public static void releaseSource(ResultSet rs, Statement stmt,Connection conn){
try {
if(rs !=null){
rs.close();
}
if (stmt!=null){
stmt.close();
}
if (conn !=null)
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
@Test
public void queryTest() throws SQLException {
//通过工具类获得连接
conn = JDBCUtil.getConnection();
stmt = conn.createStatement();
// 4 发送sql语句
String sql = "select id,name,age,job,salary from emp where id= 1";
ResultSet rs = stmt.executeQuery(sql);
// 5 解析得到结果集
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String job = rs.getString("job");
int sal = rs.getInt("salary");
System.out.println(id +"--"+name+"--"+age+"---"+ job+"---"+sal);
}
//通过工具类释放连接
JDBCUtil.releaseSource(rs,stmt,conn);
}

将数据库连接属性写在一个配置文件中jdbc.properties

driverClassName = com.mysql.cj.jdbc.Driver
url= jdbc:mysql://localhost:3306/studydb
username=root
password=root
public class JDBCUtil {
private static String driverClassName;
private static String url;
private static String username;
private static String password;
static {
InputStream is=
JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties prop = new Properties();
try {
prop.load(is);
driverClassName = prop.getProperty("driverClassName");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//1 获取连接
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return conn;
}
//2 释放连接
public static void releaseSource(ResultSet rs, Statement stmt,Connection conn){
try {
if(rs !=null){
rs.close();
}
if (stmt!=null){
stmt.close();
}
if (conn !=null)
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

jdbc中事务的实现

涉及的动作:开启事务 提交/回滚事务
事务的特性:ACID
在这里插入图片描述
银行转钱案例

/**
* 数据访问层
*/
public class BankDao {
/**
* 加钱的方法
* @param account 被转账的账户
* @param money 转账的金额
* @return
*/
public int addMoney(Connection conn,String account, int money){
String sql = "update account set money = money+? where aname=?";
int rows = CRUDTemplate.executeUpdate(conn,sql,money,account);
return rows;
}
/**
* 减钱的方法
* @param account 转账的账户
* @param money 转账的金额
* @return
*/
public int subMoney(Connection conn,String account,int money){
String sql = "update account set money = money-? where aname=?";
int rows = CRUDTemplate.executeUpdate(conn,sql,money,account);
return rows;
}
}
/**
* 业务类 实现转账操作
*/
public class BankService {
private BankDao dao = new BankDao();
public void transfer(String addAccount,String subAccount,int money){
Connection conn = JDBCUtil.getConnection();
// 开启事务(关闭自动提交)
try {
conn.setAutoCommit(false);
dao.addMoney(conn,addAccount,money);
System.out.println(10/0);
dao.subMoney(conn,subAccount,money);
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
throw new RuntimeException(e);
}finally {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public static int executeUpdate(Connection conn,String sql,Object ... params){
PreparedStatement pstmt = null;
int rows = 0;
try {
//获取sql语句的预编译对象
pstmt = conn.prepareStatement(sql);
//给占位符赋值
for (int i= 0 ;i <params.length;i++){
pstmt.setObject(i +1,params[i]);
}
// 执行sql
rows = pstmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JDBCUtil.releaseSource(null,pstmt,null);
}
return rows;
}

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

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

相关文章

银行数字化转型导师坚鹏:商业银行数字化风控(1天)

商业银行数字化风控 课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚商业银行数字化风控发展现状&#xff1f; 不清楚对公业务数字化风控工作如何开展&#xff1f; 不知道零售业务数字化风控工作如何开展&#xff1f; 课程特色…

二叉树搜索树详解

定义 二叉搜索树&#xff08;BST&#xff0c;Binary Search Tree&#xff09; 或为一颗空树&#xff0c;或满足一下性质若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左右…

单测时尽量用fake object

1. 单元测试的难点&#xff1a;外部协作者(external collaborators)的存在 单元测试是软件开发的一个重要部分&#xff0c;它有助于在开发周期的早期发现错误&#xff0c;帮助开发人员增加对生产代码正常工作的信心&#xff0c;同时也有助于改善代码设计。**Go语言从诞生那天起…

C++支持函数重载的原理--名字修饰

这章的原理并不难&#xff0c;前提是你要理解编译和链接。不会的会可以看一下这篇博客快速过一遍。 为什么C支持函数重载&#xff0c;而C语言不支持函数重载呢&#xff1f; 在C/C中&#xff0c;一个程序要运行起来&#xff0c;需要经历以下几个阶段&#xff1a;预处理、编译、汇…

Apache Flink ML 2.2.0 发布公告

来源 | Apache Flink 官方博客 翻译 | 林东 Apache Flink 社区很荣幸地宣布 Apache Flink ML 2.2.0 版本正式发布&#xff01;本次发布的版本重点添加了 Flink ML 中的特征工程算法。现在 Flink ML 包含了 33 个开箱可用的特征工程算法&#xff0c;可以支持很多常见的特征工程任…

springboot,Flowable 流程实例的激活与挂起(一)

一.简介 要实现流程实例的挂起和激活&#xff0c;首先要知道什么是流程实例的挂起和激活。 挂起&#xff1a; ①一个定义好的流程模板&#xff08;流程定义&#xff09;&#xff0c;如果挂起了&#xff0c;那么就无法据此创建新的流程实例。 ② 一个流程实例如果挂起了&#…

Pycharm必会小技巧,用好了都不用加班,效率翻2倍

学Python必用Pycharm&#xff0c;今天就来教大家11个Pycharm最常用的技巧&#xff0c;以及一些pycharm常用的快捷键&#xff0c;让你的写代码的效率翻2倍&#xff0c;以后都不用加班了&#xff01; 跟上老司机的车速&#xff01; 文章目录 一、常用小技巧1.设置代码字体。2.…

Nature:惊人的突破!科学家们成功破译人类嗅觉感应机制的奥秘!

加州大学旧金山分校&#xff08;UCSF&#xff09;的科学家们创造了第一张关于气味分子如何激活人类气味受体的分子水平的3D图片&#xff0c;这是破译嗅觉的关键一步&#xff0c;该成果打破了长期以来研究人员对嗅觉理解的僵局。 该研究成果于2023年3月15日发表在《Nature》&…

ch6_1计算机中运算方法

计算机中数的表示计算机的运算方法运算器的设计 参考教材 本章内容主要介绍&#xff0c;计算机中的运算方法 无符号数和有符号数数的定点表示和浮点表示定点运算浮点四则运算算术逻辑单元 1. 无符号数和有符号数 1.1 无符号数 1.2 有符号数 计算机中&#xff0c; 小数点…

java新版本新特性

2. Java8新特性&#xff1a;Lambda表达式 2.1 关于Java8新特性简介 Java 8 (又称为 JDK 8或JDK1.8) 是 Java 语言开发的一个主要版本。 Java 8 是oracle公司于2014年3月发布&#xff0c;可以看成是自Java 5 以来最具革命性的版本。Java 8为Java语言、编译器、类库、开发工具与…

【华为OD机试真题】AI处理器组合(java)100%通过率

AI处理器组合 知识点数组 时间限制:1s空间限制:256MB限定语言:不限 题目描述: 某公司研发了一款高性能Al处理器。每台物理设备具备8颗Al处理器,编号分别为 0、1、2、3、4、5、6、7。编号0-3的处理器处于同一个链路中,编号4-7的处理器 处于另外一个链路中,不通链路中的…

双目立体匹配中的极线约束(Epipolar Constraint),本质矩阵(Essential Matrix),对极几何(2D-2D)

极线约束&#xff08;Epipolar Constraint&#xff09;&#xff0c;本质矩阵&#xff08;Essential Matrix&#xff09;&#xff0c;对极几何&#xff08;2D-2D&#xff09; 1. The Epipolar constraint2. Essential matrix E E E 考虑一个SLAM中一个常见的问题&#xff1a;如…

【C++11】左值、右值、将亡值

值类别 C表达式的两个独立的属性&#xff1a;类型、值类别&#xff1b; 值类别分为&#xff1a;左值、纯右值、将亡值&#xff1b; 有名字的将亡值->左值&#xff1b;没名字-->右值 左值 能用&取地址的表达式&#xff1b; 例如&#xff1a;int a&#xff1b;可以…

Python每日一练(20230422)

目录 1. 杨辉三角 &#x1f31f; 2. 最长回文子串 &#x1f31f;&#x1f31f; 3. 逆波兰表达式求值 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 杨…

转义字符(\)对JavaScript中JSON.parse的影响概述

转义字符(\)对JavaScript中JSON.parse的影响 按照ECMA262第五版中的解释&#xff0c;JSON是一个提供了stringify和parse方法的内置对象&#xff0c;前者用于将js对象转化为符合json标准的字符串&#xff0c;后者将符合json标准的字符串转化为js对象。json标准参考<a href&q…

垃圾收集器面试总结(二)

G1 收集器 G1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。 被视为 JDK1.7 中 HotSpot 虚拟机的一个重要进化特征。它具备以下特点&#xff1a; 并行与并发&am…

chatgpt智能提效职场办公-ppt怎么转换成word文档

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 将PPT转换成Word文档有多种方法&#xff0c;以下是其中的一种&#xff1a; 打开PPT文件&#xff0c;并选择“文件”选项卡中的“另存为…

光流法Optical Flow,Lucas-Kanade方法,CV中光流的约束分析

光流法Optical Flow&#xff0c;Lucas-Kanade方法&#xff0c;CV中光流的约束分析 Multiple View Geometry1. Optical Flow Estimation2. The Lucas-Kanade Method2.1 Brightness Constancy Assumption2.2 Constant motion in a neighborhood2.3 Compute the velocity vector2.…

19 calloc 和 realloc 虚拟内存分配的调试

前言 前面提到了 malloc 虚拟内存分配相关的内容 malloc 虚拟内存分配的调试(1) malloc 虚拟内存分配的调试(2) 这里提 calloc 和 realloc, 这两个函数 虽然没有 malloc 使用频率那么高 但是 还是有很大的知名度的, 本文这里 我们来看一下 calloc 此函数传入两个参数, 第…

【系统集成项目管理工程师】项目成本管理

&#x1f4a5;十大知识领域&#xff1a;项目成本管理 主要考计算题 项目进度管理包括以下 4 个过程: 制订成本管理计划成本估算成本预算成本控制 一、制订成本管理计划 制订了项目成本结构、估算、预算和控制的标准 输入工具与技术输出项目管理计划项目章程事业环境因素组织过…