JDBC 基本使用(概述,连接数据库, *** 作访问MySQL, Statement和PreparedStatement的比较,JDBC API小结)

JDBC 基本使用(概述,连接数据库, *** 作访问MySQL, Statement和PreparedStatement的比较,JDBC API小结),第1张

JDBC 基本使用(概述,连接数据库, *** 作访问MySQL, Statement和PreparedStatement的比较,JDBC API小结)

目录

一、JDBC概述:

1、数据的持久化

2、 Java中的数据存储技术

3、 JDBC介绍

4、JDBC体系结构

5、 JDBC程序编写步骤

二、 数据库连接方式举例

 连接方式五(最终版)

三、 *** 作和访问数据库

1、在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

2、 使用Statement *** 作数据表的弊端

3 、PreparedStatement的使用  

1、 PreparedStatement介绍

2、PreparedStatement vs Statement

3、Java与SQL对应数据类型转换表

5、使用PreparedStatement实现查询 *** 作

四、JDBC API小结


一、JDBC概述:

1、数据的持久化

(1)持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。

(2)持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。

2、 Java中的数据存储技术

  • 在Java中,数据库存取技术可分为如下几类:

    • JDBC直接访问数据库

    • JDO (Java Data Object )技术

    • 第三方O/R工具,如Hibernate, Mybatis 等

  • JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。

3、 JDBC介绍

1)JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和 *** 作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。

2)JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。

3)JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。

4)JDBC(Java Database Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现,本文中的代码都是针对MySQL数据库实现的。

4、JDBC体系结构

JDBC接口(API)包括两个层次:
1、面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。

2、面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。

JDBC是sun公司提供一套用于数据库 *** 作的接口,java程序员只需要面向这套接口编程即可。

不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。

                                                                                                             ————面向接口编程

5、 JDBC程序编写步骤

 补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。

二、 数据库连接方式举例

连接方式一

 public void testConnection1() {
        try {
            //1.提供java.sql.Driver接口实现类的对象
            Driver driver = null;
            driver = new com.mysql.jdbc.Driver();

            //2.提供url,指明具体 *** 作的数据
            String url = "jdbc:mysql://localhost:3306/test";

            //3.提供Properties的对象,指明用户名和密码
            Properties info = new Properties();
            info.setProperty("user", "root");
            info.setProperty("password", "123");

            //4.调用driver的connect(),获取连接
            Connection conn = driver.connect(url, info);
            System.out.println(conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

连接方式二

 public void testConnection2() {
        try {
            //1.实例化Driver
            String className = "com.mysql.jdbc.Driver";
            Class clazz = Class.forName(className);
            Driver driver = (Driver) clazz.newInstance();

            //2.提供url,指明具体 *** 作的数据
            String url = "jdbc:mysql://localhost:3306/test";

            //3.提供Properties的对象,指明用户名和密码
            Properties info = new Properties();
            info.setProperty("user", "root");
            info.setProperty("password", "abc123");

            //4.调用driver的connect(),获取连接
            Connection conn = driver.connect(url, info);
            System.out.println(conn);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 连接方式三

public void testConnection3() {
        try {
            //1.数据库连接的4个基本要素:
            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "abc123";
            String driverName = "com.mysql.jdbc.Driver";

            //2.实例化Driver
            Class clazz = Class.forName(driverName);
            Driver driver = (Driver) clazz.newInstance();
            //3.注册驱动
            DriverManager.registerDriver(driver);
            //4.获取连接
            Connection conn = DriverManager.getConnection(url, user, password);
            System.out.println(conn);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

连接方式四

 public void testConnection4() {
        try {
            //1.数据库连接的4个基本要素:
            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "abc123";
            String driverName = "com.mysql.jdbc.Driver";

            //2.加载驱动 (①实例化Driver ②注册驱动)
            Class.forName(driverName);


            //Driver driver = (Driver) clazz.newInstance();
            //3.注册驱动
            //DriverManager.registerDriver(driver);
            


            //3.获取连接
            Connection conn = DriverManager.getConnection(url, user, password);
            System.out.println(conn);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
 连接方式五(最终版)
 public  void testConnection5() throws Exception {
    	//1.加载配置文件
        InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties pros = new Properties();
        pros.load(is);
        
        //2.读取配置信息
        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");

        //3.加载驱动
        Class.forName(driverClass);

        //4.获取连接
        Connection conn = DriverManager.getConnection(url,user,password);
        System.out.println(conn);

    }

其中,配置文件声明在工程的src目录下:【jdbc.properties】

user=root
password=123
url=jdbc:mysql://localhost:3306/test
driverClass=com.mysql.jdbc.Driver

说明:使用配置文件的方式保存配置信息,在代码中加载配置文件

使用配置文件的好处:

①实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码 ②如果修改了配置信息,省去重新编译的过程

三、 *** 作和访问数据库

数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。

1、在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

        1、Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。

        2、PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。

        3、CallableStatement:用于执行 SQL 存储过程

2、 使用Statement *** 作数据表的弊端

  • 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。

  • Statement 接口中定义了下列方法用于执行 SQL 语句:

  • int excuteUpdate(String sql):执行更新 *** 作INSERT、UPDATE、DELETE
    ResultSet executeQuery(String sql):执行查询 *** 作SELECT

  • 但是使用Statement *** 作数据表存在弊端:

    • 问题一:存在拼串 *** 作,繁琐

    • 问题二:存在SQL注入问题

3、 PreparedStatement的使用  

1、 PreparedStatement介绍

                1)可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取                 PreparedStatement 对象

                2)PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句

                3)PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用  PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一 个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值

2、PreparedStatement vs Statement
  • 代码的可读性和可维护性。

  • PreparedStatement 能最大可能提高性能:

  •         DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。

  • 在statement语句中,即使是相同 *** 作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。

  • 在statement语句中,即使是相同 *** 作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。

  • PreparedStatement 可以防止 SQL 注入

3、Java与SQL对应数据类型转换表

        

4、使用PreparedStatement实现增、删、改 *** 作

//通用的增、删、改 *** 作(体现一:增、删、改 ; 体现二:针对于不同的表)
	public void update(String sql,Object ... args){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//1.获取数据库的连接
			conn = JDBCUtils.getConnection();
			
			//2.获取PreparedStatement的实例 (或:预编译sql语句)
			ps = conn.prepareStatement(sql);
			//3.填充占位符
			for(int i = 0;i < args.length;i++){
				ps.setObject(i + 1, args[i]);
			}
			
			//4.执行sql语句
			ps.execute();
		} catch (Exception e) {
			
			e.printStackTrace();
		}finally{
			//5.关闭资源
			JDBCUtils.closeResource(conn, ps);
			
		}
	}
5、使用PreparedStatement实现查询 *** 作

// 通用的针对于不同表的查询:返回一个对象 (version 1.0)
	public  T getInstance(Class clazz, String sql, Object... args) {

		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			// 1.获取数据库连接
			conn = JDBCUtils.getConnection();

			// 2.预编译sql语句,得到PreparedStatement对象
			ps = conn.prepareStatement(sql);

			// 3.填充占位符
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}

			// 4.执行executeQuery(),得到结果集:ResultSet
			rs = ps.executeQuery();

			// 5.得到结果集的元数据:ResultSetmetaData
			ResultSetmetaData rsmd = rs.getmetaData();

			// 6.1通过ResultSetmetaData得到columnCount,columnLabel;通过ResultSet得到列值
			int columnCount = rsmd.getColumnCount();
			if (rs.next()) {
				T t = clazz.newInstance();
				for (int i = 0; i < columnCount; i++) {// 遍历每一个列

					// 获取列值
					Object columnVal = rs.getObject(i + 1);
					// 获取列的别名:列的别名,使用类的属性名充当
					String columnLabel = rsmd.getColumnLabel(i + 1);
					// 6.2使用反射,给对象的相应属性赋值
					Field field = clazz.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(t, columnVal);

				}

				return t;

			}
		} catch (Exception e) {

			e.printStackTrace();
		} finally {
			// 7.关闭资源
			JDBCUtils.closeResource(conn, ps, rs);
		}

		return null;

	}

说明:使用PreparedStatement实现的查询 *** 作可以替换Statement实现的查询 *** 作,解决Statement拼串和SQL注入问题。

四、JDBC API小结

两种思想:

一、面向接口编程的思想

二、ORM思想(object relational mapping)     

        1、一个数据表对应一个java类

        2、表中的一条记录对应java类的一个对象

        3、表中的一个字段对应java类的一个属性

sql是需要结合列名和表的属性名来写。注意起别名。

两种技术:

一、JDBC结果集的元数据:ResultSetmetaData

        1、获取列数:getColumnCount()

        2、获取列的别名:getColumnLabel()

二、通过反射,创建指定类的对象,获取指定的属性并赋值

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5481011.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存