学习笔记之《Java语言程序设计(进阶篇)》------ 第32章 Java数据库程序设计 + 《Java核心技术卷II》 第5章 数据库编程

  • 以下所有实例都以访问 MySQL 数据库为基准。注:笔者的 MySQL 位于阿里云服务器上,所以要想通过代码可以访问到远程数据库,需要先去阿里云控制台开放 3306 端口。具体可以查看:阿里云如何开放端口
  • 使用 JAVA 访问 MySQL 的五大步骤:
  1. 加载驱动。
  2. 建立与数据库的连接。
  3. 创建语句,用于执行具体语句。
  4. 执行具体语句,并获得返回结果集。
  5. 处理返回结果集。
  • 具体代码如下:
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			//创建语句
			Statement statement = connection.createStatement();
			//执行具体语句,并获得返回结果
			ResultSet resultSet = statement.executeQuery("select order_num,date(order_date),time(order_date),cust_id from orders");
			//依次获得各个返回结果
			while (resultSet.next()) {
				System.out.println(resultSet.getString(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3) + " " + resultSet.getString(4));
			}
		}
	}
}
  •  预编译语句(PrepareStatement):可以创建参数化的SQL语句,用 “?”作为占位符;使用 setX( int parameterIndex,X value) 为各个参数赋值;赋值完成后,调用 executeQuery()或 executeUpdate()执行预编译语句
  • 具体代码如下:
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			//创建预编译语句
			PreparedStatement preparedStatement = connection.prepareStatement("select order_date from orders where order_num = ? and cust_id = ?");
			//为预编译语句的各个 ?赋值
			preparedStatement.setInt(1, 1);
			preparedStatement.setInt(2, 10001);
			//执行预编译语句,并获得返回结果
			ResultSet resultSet = preparedStatement.executeQuery();
			//依次获得各个返回结果
			while (resultSet.next()) {
				System.out.println(resultSet.getString(1));
			}
		}
	}
}
  • 针对上例,需注意:占位符 “?”不能放在查询字段上,必须放在查询条件里面
  • CallableStatement:可以执行SQL存储过程。实例如下:
  • SQL存储过程代码如下:
delimiter //
create PROCEDURE ordertotal(
in onumber int,
in taxable int,
out ototal decimal(8,2)
)
begin
declare total decimal(8,2);
declare taxrate int default 6;
select sum(item_price * quantity)
from orderitems
where order_num = onumber
into total;
if taxable then
select total + (total / 100 * taxrate) into total;
end if;
select total into ototal;
end //
  •  Java代码如下:
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.CallableStatement;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			//预编译存储过程,获得CallableStatement对象
			CallableStatement callableStatement = connection.prepareCall("{call ordertotal(?,?,?)}");
			//设置第一个变量,为IN类型,值为20005
			callableStatement.setInt(1, 20005);
			//设置第二个变量,为IN类型,值为1
			callableStatement.setInt(2, 1);
			//注册第三个变量,为OUT类型,类型为Types.Double
			callableStatement.registerOutParameter(3, Types.DOUBLE);
			//执行带上述给定参数的存储过程
			callableStatement.execute();
			//获得上述存储值的第三个参数值(即输出的值)
			System.out.println(callableStatement.getDouble(3));
		}
	}
}
  • 针对以上的例子,需注意:
  1. 在SQL中,存储过程没有返回值,只有函数才有返回值
  2. 参数值所在位置从1开始
  3. IN 类型的参数需要使用 setX 方法设定值,OUT 类型(或者是 IN OUT 类型)的参数需要用 registerOutParameter 方法注册,以给定其类型。
  4. 获取 OUT 类型的值使用 getX 方法
  • 获得数据库元数据:(使用 Connection 对象的getMetaData方法,获得数据库的一个DatabaseMetaData实例)
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			DatabaseMetaData dbMetaData = connection.getMetaData();
			System.out.println("database url: " + dbMetaData.getURL());
			System.out.println("database username:" + dbMetaData.getUserName());
			System.out.println("database product name: " + dbMetaData.getDatabaseProductName());
			System.out.println("database product version: " + dbMetaData.getDatabaseProductVersion() );
		}
	}
}
  • 获取数据库表:
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			DatabaseMetaData dbMetaData = connection.getMetaData();
            //返回的rsTable是一个表,其中 TABLE_NAME 为一个列名
			ResultSet rsTables = dbMetaData.getTables(null, null, null, new String[] {"TABLE"});
			while (rsTables.next()) {
				System.out.println(rsTables.getString("TABLE_NAME") + " ");
			}
		}
	}
}
  •  结果集元数据:
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			//获得执行语句对象
			Statement statement = connection.createStatement();
			//执行具体SQL语句
			ResultSet resultSet = statement.executeQuery("select * from orderitems");
			//获得结果集的元数据
			ResultSetMetaData rsMetaData = resultSet.getMetaData();
			//getColumnCount方法返回结果集的列总数,getColumnName(i)获取第i列的列名,i从1开始
			for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
				System.out.printf("%-12s\t", rsMetaData.getColumnName(i));
			}
			System.out.println();
			//next方法遍历结果集(一行行遍历),getObject(i)取本行(遍历到的该行)的第i列数据,i从1开始
			while (resultSet.next()) {
				for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
					System.out.printf("%-12s\t", resultSet.getObject(i));
				}
				System.out.println();
			}
		}
	}
}
  • 事务:
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			connection.setAutoCommit(false);//关闭自动提交模式
			Statement statement = connection.createStatement();
			Savepoint svpt = null;
			try {
				String sql1 = "update vendors set vend_name = now() where vend_id = 1001";//update语句,在此语句执行后会设置一个savepoint
				String sql2 = "delete from vendors where vend_id = 10010";//delete语句,虽然表中没有id为10010的信息,但是也不报错
				String sql3 = "insert into vendors values('sc')";//错误的insert sql语句
				statement.executeUpdate(sql1);
				svpt = connection.setSavepoint();//设置的savepoint
				statement.execute(sql2);
				statement.execute(sql3);//执行到此出错,进入catch
				connection.commit();
				System.out.println("ok");
 			} catch (SQLException e) {
				System.out.println("error");
 				connection.rollback(svpt);//回滚到保存点svpt,此时sql2和sql3相当于没执行,sql1已执行
 				connection.commit();//提交事务,将结果写回数据库
			} finally {
				connection.releaseSavepoint(svpt);//释放保存点
			}
		}
	}
}
  • 批量更新:在使用批量更新时,一个语句序列作为一批操作将同时被收集和提交。处于同一批中的语句可以是 INSERT、UPDATE 和 DELETE 等操作,也可以是数据库定义语句,如 CREATE TABLE 和 DROP TABLE 。(可以混合出现
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Connection;

public class TestForDatabase {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载mysql驱动
		Class.forName("com.mysql.jdbc.Driver");
		//建立与mysql的连接
		try(Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/test?useSSL=True","root","root")){
			connection.setAutoCommit(false);//关闭自动提交模式
			Statement statement = connection.createStatement();
			//使用String[] 存储用于批量处理sql语句,包含 INSERT、UPDATE、DELETE以及CREATE TABLE
			String[] sqls = {
					"insert into productnotes(prod_id,note_date) values(1,now())",
					"update productnotes set note_text = 'hhh' where note_id = last_insert_id()",
					"delete from productnotes where note_id = 116",
					"create table if not exists test_table("
					+ "id int auto_increment,name varchar(20),primary key(id))",
			};
			for(String sql:sqls) {
				statement.addBatch(sql);//将各条sql语句添加到batch,相当于一个组
			}
			statement.executeBatch();//整个batch一起执行
			connection.commit();//提交结果,将结果写回数据库
			System.out.println("ok");
		}
	}
}

 

 

你可能感兴趣的:(Java,MySQL,学习笔记)