DM JDBC
DM 作为一个通用数据库管理系统,提供了多种数据库访问接口,包括 ODBC、JDBC、DPI 以及嵌入方式等。今天我们就浅谈一下DM JDBC。
文章目录
- 1、JDBC介绍
- (1)定义
- (2)JDBC 基本原理
- (3)主要功能
- 2、JDBC程序编写步骤
- 3、获取数据库连接的5种方式
- 4、ResultSet
- 5、Statement
- 6、PreparedStatement
- 7、DM JDBC特性
1、JDBC介绍
(1)定义
JDBC(Java Database Connectivity)是Java应用程序与数据库的接口规范,旨在让各数据库开发商为Java程序员提供标准的数据库应用程序编程接口(API)。JDBC定义了一个跨数据库、跨平台的通用SQL数据库API。
JDBC是访问数据库的基石,JDO、Hibernate、Mybatis等框架只是更好的封装了JDBC。
(2)JDBC 基本原理
从图中,我们发现JAVA应用程序并不是直接和数据库进行交互,而是通过JDBC这个"中间商"来完成数据的相关操作,那么为什么需要这个"中间商"呢?
从JDBC的API分析,发现包括两个层次,一个是面向应用API,及对Java应用程序开发人员使用;一个是面向数据库API,及对开发商开发数据库驱动程序用。那么,这将意味着,JAVA程序员只需要掌握面向应用API,就可以对不同商家的数据库进行交互,大大减少了开发人员的学习成本。同时,不同的开发数据库商家只要能遵循JDBC面向数据库API,那么自己开发的数据库的通用性将大大提高。
(3)主要功能
通过JDBC驱动程序,用户可以在应用程序中实现对DM数据库的连接与访问,JDBC驱动程序的主要功能包括:
- 建立与DM数据库的连接
- 转接发送SQL语句到数据库
- 处理并返回语句执行结果
2、JDBC程序编写步骤
(1)注册驱动–加载Driver类
(2)获取连接–得到Connection
(3)执行增删改查–发送SQL给DM/Mysql/…执行
(4)释放资源–关闭相关连接
下面程序以Mysql为例
package com.test.jdbc;
import com.Mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author hkw
* 这是第一个jdbc程序完成简单的操作
*/
public class Jdbc01 {
public static void main(String[] args) throws SQLException {
//1.注册驱动
Driver driver = new Driver();
//2.得到连接
//1.说明:jdbc:mysql:// 规定好表示协议,通过jdbc的方式连接mysql
//2.localhost 主机,可以是ip地址,
//3.3306 表示mysql监听的端口
//4.db02 连接到 mysql dbms 的哪个数据库
//5.mysql的连接本质就是socket连接
String url = "jdbc:mysql://localhost:3306/db02";
//将用户名和密码放到properties
Properties properties = new Properties();
properties.setProperty("user","root");//用户
properties.setProperty("password","root");//密码
Connection connect = driver.connect(url, properties);
//3.执行sql
//String sql = "insert into actor values(null,'刘德华','男','1970-11-11','110')";
//String sql ="update actor set name='周星驰' where id =1";
String sql ="delete from actor where id =1";
//
Statement statement = connect.createStatement();
int rows = statement.executeUpdate(sql);//如果是dml语句,返回的就是影响行数
System.out.println(rows>0? "成功":"失败");
//4.关闭连接资源
statement.close();
connect.close();
}
}
3、获取数据库连接的5种方式
package com.test.jdbc;
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author hkw
* 分析java的五种方式
*/
public class JdbcConn {
//方式1
@Test
public void connect01() throws SQLException {
//1.注册驱动
Driver driver = new Driver();
String url = "jdbc:mysql://localhost:3306/db02";
//将用户名和密码放到properties
Properties properties = new Properties();
properties.setProperty("user","root");//用户
properties.setProperty("password","root");//密码
Connection connect = driver.connect(url, properties);
System.out.println(connect);
}
//方式2
@Test
public void connect02() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
//使用反射创建Driver类 动态加载更加灵活,减少依赖性
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
String url = "jdbc:mysql://localhost:3306/db02";
//将用户名和密码放到properties
Properties properties = new Properties();
properties.setProperty("user","root");//用户
properties.setProperty("password","root");//密码
Connection connect = driver.connect(url, properties);
System.out.println("方式2="+connect);
}
//方式3 使用 DriverManager 替代driver
@Test
public void connect03() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
//使用反射创建Driver类 动态加载更加灵活,减少依赖性
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
String url = "jdbc:mysql://localhost:3306/db02";
String user = "root";
String password = "root";
DriverManager.registerDriver(driver);//注册driver驱动
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式3="+connection);
}
//方法4:使用Class.forName 自动完成注册驱动,简化代码
//这种方式获取连接是使用的最多的
@Test
public void connect04() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
//使用反射创建Driver类 动态加载更加灵活,减少依赖性
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
/*
1.静态代码块,在类加载时,会执行一次
2.DriverManager.registerDriver(new Driver()
2.因此注册driver的工作已经完成
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
*/
Driver driver = (Driver) aClass.newInstance();
String url = "jdbc:mysql://localhost:3306/db02";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式4="+connection);
}
//方式5,在方式4的基础上改进,增加配置文件,让连接mysql更加灵活
@Test
public void connect05() throws SQLException, ClassNotFoundException, IOException {
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
Connection connection = DriverManager.getConnection(url, user, password);
Class.forName(driver);
System.out.println("方式5="+connection);
}
}
4、ResultSet
- 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成
- ResultSet对象保持一个光标指向当前的数据行。最初,光标位于第一行之前
- next方法将光标移动到下一行,并且由于在ResultSet对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集
package com.test.jdbc.resultset_;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
@SuppressWarnings({"all"})
public class ResultSet_ {
public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
//通过properties对象获取配置文件信息
Properties properties = new Properties();
properties.load(new FileInputStream("D:/idea_workspace/chapter25/src/mysql.properties"));
//获取相关的值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.得到statement
Statement statement = connection.createStatement();
//4.组织sql
String sql = "select id, name,sex,borndate from actor";
ResultSet resultSet = statement.executeQuery(sql);
//5.使用while取出数据
while (resultSet.next()){
String id = resultSet.getString(1);
String name = resultSet.getString(2);
String sex = resultSet.getString(3);
String date = resultSet.getString(4);
System.out.println("id"+"\t"+name+"\t"+sex+"\t"+date+"\t");
}
//6.关闭连接
resultSet.close();
statement.close();
connection.close();
System.out.println("方式5="+connection);
}
@Test
public void m1() throws IOException, ClassNotFoundException, SQLException {
//通过properties对象获取配置文件信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//获取相关的值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//1.注册驱动u
Class.forName(driver);
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.得到statement
Statement statement = connection.createStatement();
//4.组织sql
String sql = "select id, name,sex,borndate from actor";
ResultSet resultSet = statement.executeQuery(sql);
//5.使用while取出数据
while (resultSet.next()){
String id = resultSet.getString(1);
String name = resultSet.getString(2);
String sex = resultSet.getString(3);
String date = resultSet.getString(4);
System.out.println("id"+"\t"+name+"\t"+sex+"\t"+date+"\t");
}
//6.关闭连接
resultSet.close();
statement.close();
connection.close();
System.out.println("方式5="+connection);
}
}
5、Statement
1.Statement对象用于执行静态SQL语句并返回其生成结果的对象
2.在连接建立后,需要对数据库进行访问,执行命令或是SQL语句,可以通过
- Statement [存在SQL注入问题]
- PreparedStatement [预处理]
- CableStatement [存储过程]
预处理的好处:
- 不再使用+拼接sql语句,减少语法错误
- 有效解决了SQL注入问题
- 大大减少了编译次数,效率较高
3.Statement对象执行SQL语句存在SQL注入风险
4.SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库
5.要防范SQL注入,只要用PreparedStatement取代Statement就可以了
6、PreparedStatement
- PreparedStatement执行SQL语句中的参数用(?)表示,调用PreparedStatement对象的setXXX()方法来设置这些参数,setXXX()方法有两个参数,第一个参数是要设置的SQL语句中的索引(从1开始),第二个是设置的SQL语句中参数的值
- 调用executeQuery(),返回ResultSet对象
调用executeUpdate():执行更新,包括增、删、修改
package com.test.jdbc.preparedstatement_;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.Scanner;
@SuppressWarnings({"all"})
public class PreparedStatement_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.println("请输入管理员的名字");//next():当接收到空格或者'表示结束
String admin_name =scanner.nextLine();//如果需要看到SQL注入,这里需要用nextLine
System.out.println("请输入管理员的密码");
String admin_password =scanner.nextLine();
//通过properties对象获取配置文件信息
Properties properties = new Properties();
properties.load(new FileInputStream("D:/idea_workspace/chapter25/src/mysql.properties"));
//获取相关的值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3 得到statement
//3.1 组织sql Sql语句的?就相当于占位符
String sql = "select name,pwd from admin where name =? and pwd =?";
//3.2 preparedStatement对象实现了PreparedStatement接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3 给?赋值
preparedStatement.setString(1,admin_name);
preparedStatement.setString(2,admin_password);
//这里执行 executeQuery(),不要再写sql
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){
//如果查询到一条记录,则说明该管理存在
System.out.println("恭喜,登录成功");
}else {
System.out.println("对不起,登录失败");
}
//关闭连接
resultSet.close();
preparedStatement.close();
connection.close();
}
}
package com.test.jdbc.preparedstatement_;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Properties;
import java.util.Scanner;
@SuppressWarnings({"all"})
public class PreparedStatementDML_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.println("请输入管理员的名字");//next():当接收到空格或者'表示结束
String admin_name =scanner.nextLine();//如果需要看到SQL注入,这里需要用nextLine
System.out.println("请输入管理员的密码");
String admin_password =scanner.nextLine();
//通过properties对象获取配置文件信息
Properties properties = new Properties();
properties.load(new FileInputStream("D:/idea_workspace/chapter25/src/mysql.properties"));
//获取相关的值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
//3 得到statement
//3.1 组织sql Sql语句的?就相当于占位符
//添加记录
String sql = "insert into admin values (?,?)";
//String sql = "update admin set pwd=? where name =?";
//String sql = "delete from admin where name =?";
//String sql = "select name,pwd from admin where name =? and pwd =?";
//3.2 preparedStatement对象实现了PreparedStatement接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3 给?赋值
// preparedStatement.setString(1,admin_password);
preparedStatement.setString(1,admin_name);
//执行 dml语句使用 executeUpdate()
int rows = preparedStatement.executeUpdate();
System.out.println(rows>0?"执行成功":"执行失败");
//关闭连接
preparedStatement.close();
connection.close();
}
}
7、DM JDBC特性
DM JDBC 驱动程序有JDBC3.0 和 JDBC4.0 两种类型。
DM JDBC3.0 驱动程序符合SUN JDBC3.0 标准,实现了JDBC3.0规范所要求的下列接口:
DM JDBC4.0 驱动程序符合SUN JDBC4.0 标准,实现了下列新特性:
- JDBC 驱动类的自动加载;
- 连接管理的增强;
- 对 RowId SQL 类型的支持;
- SQL 的 DataSet 实现使用了 Annotations;
- SQL 异常处理的增强;
- 对 SQL XML 的支持;
- 对 BLOB/CLOB 的改进支持以及对国际字符集的支持。