JDBC-day01

JDBC-day01

JDBC基本概念

  • 概念: Java DataBase Connectivity 即Java数据库连接, 用java语言操作数据库.
  • JDBC本质: 我们期望使用统一的一套java代码可以操作所有的数据库,为此,sun公司就定义了医药操作所有关系型数据库的规则(也就是接口),而其每个数据库对这个接口的实现类由该数据库公司自己实现.所以, 我们可以说JDBC的本质就是:官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口.同时各个数据库厂商自己去实现这个接口,提供数据库驱动的jar包.从而我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

JDBC快速入门

  • 步骤:
    1. 导入对应数据库的驱动jar包,要用mysql就导入mysql的.
      1. 复制jar包,到项目下(可以新建一个目录libs,jar包都放在该目录下).
      2. 将libs目录–>右键–>添加为库.
    2. 注册驱动,让程序知道是用哪个数据库.
      • Class.forName("com.mysql.jdbc.Driver");.
    3. 获取数据库连接对象Connection.
      • Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cart", "root", "root");.
    4. 定义sql语句.
      • String sql = "update product set name = '话说' where id = 1";.
    5. 获取执行sql语句的对象 Statement.
      • Statement state = conn.createStatement();.
    6. 执行sql语句,接收返回的结果.
      • int count = state.executeUpdate(sql);.
    7. 处理结果.
    8. 释放资源.

对JDBC中各个接口和类详解

  1. 详解各个对象

    • DriverManager(类): 驱动管理对象.
      • 功能
        1. 注册驱动,告诉我们的程序该使用哪个数据库的jar包.

          • 使用的方法: public static void registerDriver​(Driver driver) throws SQLException.

          • 写代码使用该方法:Class.forName("com.mysql.jdbc.Driver"),通过查看Driver的源码,我们发现,在Driver类中存在静态代码块

            static {
            try {
            DriverManager.registerDriver(new Driver());
            } catch (SQLException var1) {
            throw new RuntimeException(“Can’t register driver!”);
            }
            }

          • 注意:在导入mysql5的jar包以后,我们注册驱动的语句可以不用写,因为在jar包下的META-INF文件夹中的services中帮我们写了,不过我们还是建议写上,我们不知道驱动咋写的时候也可以去META-INF文件夹中的services中复制.

        2. 获取数据库连接.

          • 使用的方法: public static Connection getConnection​(String url, String user, String password).
          • 参数:
            • url:指定连接的路径
              • 语法: jdbc:mysql://ip地址(或者域名,用于找到计算机):端口号(用于找到mysql软件)/数据库名称
              • 例子:jdbc:mysql://localhost:3306/cart
              • 细节:如果连接的是本机的mysql服务器,并且mysql的默认端口是3306,则url中的ip和端口可以省略,所以url可以简写为:jdbc:mysql:///数据库名称
            • user:用户名
            • password:密码
    • Connection(接口): 数据库连接对象
      • 功能:
        1. 获取执行sql语句的对象
          • 方法1: Statement createStatement().
          • 方法2: PreparedStatement prepareStatement​(String sql).
        2. 管理事务:
          • 开启事务: void setAutoCommit​(boolean autoCommit),调用该方法设置参数为false则开启事务.
          • 提交事务: void commit().
          • 回滚事务: void rollback().
    • Statement(接口,重要): 执行静态sql语句对象
      • 方法1(了解): boolean execute​(String sql),返回true表示执行的是DQL语句,返回false表示执行的是 DML语句.
      • 方法2: int executeUpdate​(String sql),执行DML语句(数据操作语言,增删改,insert,update,delete),DDL语句(数据定义语言,创建/删除表和库,create,alter,drop).
        • 返回值: 表示影响的行数(针对DML语句,而对DDL永远返回0,因为它不返回任何内容).
        • 返回值作用: 可以通过影响的行数来判断DML语句是否执行成功,返回值>0则执行成功,反之则执行失败.
      • 方法3: ResultSet executeQuery(String sql),执行DQL语句(数据查询语言查询语句,select).
      • 练习,针对product表:
        1. 添加一条记录:String sql = "insert into product(id,name,price) value(null , '平板2' , 500)",其中product(id,name,price)中的括号里的参数表示增加哪一个字段内容,不写就表示增加所有字段.
          • 注意:这里value可以写成values,在插入一条数据时,用values较快,插入多行数据时,用value较快.
        2. 删除一条记录: String sql = "delete from product where id = 2";.
        3. 修改一条记录: String sql = "update product set name = '平板' where id = 1";.
        4. 创建一张表: String sql = "create table student (id int, name varchar(20))";.
        5. 删除一张表: String sql = "drop table student";.
    • ResultSet(接口): 结果集对象,封装查询结果.
      • next(): 游标向下移动一行(默认光标指向位置是表头,此时是没有数据的,向下移动一行后就有数据了),同时可以通过该方法判断是否到达最后一行末尾(即是否有数据),如果有数据,则返回true,反之则返回false.
      • getXxx(参数): 获取数据.
        • Xxx代表数据类型,因为它是一次获取一行当中某一列的值,不是一次获取一整行的,例如: int getInt().
        • 参数有两种情况:
          1. int类型: 代表列的编号,从1开始,不是从0开始,如:getInt(1).
          2. String类型: 代表列的名称,如:getString(“id”).
      • 注意:
        • ResultSet的使用步骤:
          1. 游标向下移动一行.
          2. 判断是否有数据.
          3. 获取数据.
while (rs.next()) {
	int id = rs.getInt(1);
	String name = rs.getString("name");
	double price = rs.getDouble("price");
	String data = "id = " + id + "name = " + name + "price = " + price;
	System.out.println(data);
	}
	*  练习:
		*  定义一个方法,查询`db_student`数据库中`studentinfo`中的数据,并将其封装为对象,然后打印.
		*  思路:表其实和类的定义很类似,定义字段名,字段类型等,而表中每一行数据和一个对象类似,有表中每个字段的内容,所以我们可以把表映射成一个类,把查询的每一行数据封装成该类对象,然后用集合将所有对象都装载在一起返回.
			1.  定义一个`Studentinfo`类,封装数据库中表的各个字段.
			2.  定义方法 public List<Studentinfo> finaAll(),实现对数据库中所有数据的查询并将数据添加到list集合中.
			3.  调用方法.
*  PreparedStatement(statement的子接口): 执行动态sql语句
	1. **SQL注入问题**: 在拼接sql语句时,有一些sql的特殊关键字参与字符串的拼接,会造成一些安全性问题
		* 例如: `select * from usertable where username = 'abc' and password = 'a' or 'a' = 'a'`,前面的账号密码是错的,但是这个sql语句是恒成立的,因为后面有个`or 'a' = 'a'`,这就会把数据库中所有数据都查出来,同时导致程序出问题.
	2. 解决sql注入问题: 使用PreparedStatement对象来解决.
	3. 预编译sql语句:参数使用`?`作为占位符,在执行的时候,给`?`赋值就行了,这个虽然步骤麻烦一点,但是安全一些.
	4. 使用步骤:
		1. 导入对应数据库的驱动jar包,要用mysql就导入mysql的.即复制jar包,到项目下(可以新建一个目录libs,jar包都放在该目录下).
		2. 将libs目录-->右键-->添加为库.
		3. 注册驱动,让程序知道是用哪个数据库.
			* `Class.forName("com.mysql.jdbc.Driver");`.
		4. 获取数据库连接对象Connection.
			* `Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cart", "root", "root");`.
		5. 定义sql语句.
			* **注意**: sql的参数使用`?`作为占位符.如`String sql = "update product set name = ? where id = ?";`. 
		6. 获取执行sql语句的对象 PreparedStatement: 方法为`PreparedStatement prepareStatement​(String sql)`.
			* `PreparedStatement ps = conn.prepareStatement(sql);`.
		7. 给`?`赋值
			* 用到PreparedStatement中的setXxx(参数1, 参数2)方法.
			* 其中,**参数1**表示?的位置编号,从1开始,**参数2**表示?的值.
		7. 执行sql语句,接收返回的结果,在这里就不需要传递sql语句了,因为在步骤6中已经传递过了.
		8. 处理结果.
		9. 释放资源. 
	5. 改造登录例子代码:***[PrepareStatement改进登录代码](https://github.com/fanfan999/WebCodes/blob/master/JdbcDemo/fan/LoginUser_PrepareStatement.java)***
	6. 注意:我们以后使用PrepareStatement来完成增删查改的所有操作
		1. 可以防止SQL注入.
		2. 效率比Statement高.

抽取JDBC工具类: JDBCUtils类

  • 目的: 简化书写
  • 分析:
    1. 抽取注册驱动.
    2. 抽取一个方法,获取连接对象.
      • 需求: 不想传递参数(url,user,password等),因为太麻烦,但是 又想保证工具类的通用性,即不同url,user等也可以运行.
      • 解决办法: 使用配置文件:
        • jdbc.properties
          • url =
          • user =
          • password =
    3. 抽取释放资源.
    4. 代码:***JDBC工具类及测试代码***
  • 练习:
    • 需求: 通过键盘录入用户名和密码判断用户是否登录成功,给出提示.
    • 步骤
      1. 创建数据库表,包括用户名和密码两个字段.
      2. 创建一个类LoginUser.java测试.
    • 代码:***用户登录测试类***

需要注意的点:

  1. JAVA中两个基1的点:
    1. 在查询语句ResultSet中,参数是从1开始的.
    2. 在预编译接口PreparedStatement对象中,参数也是从1开始的.
  2. 上面提到的对象中,只有DriverManager是类,其它的都是接口.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值