JDBC练习测试

Util类
package tarena.util;



import java.io.InputStream;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.Properties;



public class DBUtil {

	private static final String URL;

	private static final String DRIVER;

	private static final String USERNAME;

	private static final String PASSWORD;

	

	private static ThreadLocal threadLocal = 

		new ThreadLocal();

	

	static {

		try {

			InputStream in = DBUtil.class.getResourceAsStream("/db.properties");

			Properties props = new Properties();

			props.load(in);

			in.close();

			

			URL=props.getProperty("url");

			DRIVER=props.getProperty("driver");

			USERNAME=props.getProperty("username");

			PASSWORD=props.getProperty("password");

			Class.forName(DRIVER); // 注册驱动

		} catch(Exception e) {

			System.out.println("无法获得数据库连接信息");

			throw new RuntimeException(e);

		}

	}

	

	private DBUtil() {}

	

	public static Connection open() throws SQLException{

		return DriverManager.getConnection(

				URL,USERNAME,PASSWORD);

	}

	

	public static void close(

			Connection con,

			Statement stmt,

			ResultSet rs) {

		try {rs.close();} catch(Exception e) {}

		try {stmt.close();} catch(Exception e) {}

		try {con.close();} catch(Exception e) {}

	}

	

	public static Connection openInThread() throws SQLException{

		Connection con = 

			(Connection)threadLocal.get();

		if(null == con) {

			con = open();

			threadLocal.set(con);

		}

		return con;

	}

	

	public static void closeInThread() {

		try {

			Connection con = openInThread();

			con.close();

			threadLocal.remove();

		} catch(Exception e) {}

	}

}




测试类
package day02;



import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.Statement;

import java.util.Scanner;



import tarena.util.DBUtil;



public class JDBCTest3 {

	public static void main(String[] args) throws Exception {

		test1();

	}



	static void test1() throws Exception  {

		Connection con = null;

		Statement stmt = null;

		try {

			con = DBUtil.openInThread();

			con.setAutoCommit(false);

			// 输入员工数据保存

			// 如果姓名存在,删除再插入新数据

			// 如果不存在,直接插入新数据

			Emp emp = inputEmp();

			if(nameExist(emp.getFirstName(), emp.getLastName())) {

				deleteByName(emp.getFirstName(), emp.getLastName());

			}

			save(emp);

			con.commit();

		} catch(Exception e) {

			con.rollback();

			throw e;

		} finally {

			DBUtil.closeInThread();

		}

	}



	private static void save(

			Emp emp) throws Exception {

		Connection con = DBUtil.openInThread();

		PreparedStatement pstmt = 

			con.prepareStatement(

					"insert into s_emp(id,first_name, last_name, salary) " +

					"values(?,?,?,?)");

		pstmt.setInt(1, emp.getId());

		pstmt.setString(2, emp.getFirstName());

		pstmt.setString(3, emp.getLastName());

		pstmt.setDouble(4, emp.getSalary());

		pstmt.executeUpdate();

	}

	private static void deleteByName(String firstName, String lastName) throws Exception {

		Connection con = DBUtil.openInThread();

		PreparedStatement pstmt = 

			con.prepareStatement(

					"delete from s_emp " +

					"where first_name=? " +

					"and last_name=?");

		pstmt.setString(1, firstName);

		pstmt.setString(2,lastName);

		pstmt.executeUpdate();

	}

	private static boolean nameExist(String firstName, String lastName) throws Exception {

		Connection con = DBUtil.openInThread();

		PreparedStatement pstmt = 

			con.prepareStatement(

					"select * from s_emp " +

					"where first_name=? " +

					"and last_name=?");

		pstmt.setString(1, firstName);

		pstmt.setString(2,lastName);

		ResultSet rs = pstmt.executeQuery();

		// 指针下移有数据,即存在同名员工

		boolean exist = rs.next();

		rs.close();

		pstmt.close();

		return exist;

	}



	private static Emp inputEmp() {

		Scanner sc = new Scanner(System.in);

		System.out.print("请输入id:");

		int id = sc.nextInt();

		System.out.print("请输入first name:");

		String fname = sc.next();

		System.out.print("请输入last name:");

		String lname = sc.next();

		System.out.print("请输入salary:");

		double sal = sc.nextDouble();		

		Emp e = new Emp(id,fname,lname,sal);

		return e;

	}

}


引用

元数据

数据连接元数据

DatabaseMetadata

数据库品牌、版本

表.....

结果集的元数据

ResultSetMetadata



getColumnCount() - 结果集中字段数量

getColumnName(序号) - 指定字段的名字

getColumnType(序号) - 指定字段的类型数字编号

使用Types中的常量做判断

getColumnTypeName(序号) - 指定字段的类型名称



java.sql.Types

封装表示字段类型的数字变号常量

Types.DATE - 年月日

Types.TIME - 时分秒

Types.TIMESTAMP - 年月日时分秒



ResultSet

数据传输量

setFetchSize(数据行数)

0 - JDBC驱动自行决定每次抓取的数据量



int age = rs.getInt("age");

// 刚取出的字段中数据在数据表中是否为null

boolean b = rs.wasNull();

double height = rs.getDouble("height");

b = rs.wasNull();





PreparedStatement

是Statement的子接口

比Statement更常用



1, 预编译的sql语句,重复执行相同的sql语句效率较高

pstmt = con.prepareStatement("select ...");

			pstmt.executeQuery();

			pstmt.executeQuery();



2, 对sql语句中参数数据进行设置

	pstmt = con.prepareStatement(

				"insert into emp(id,name,sal) values(?,?,?)");

			pstmt.setInt(1,4534);

			pstmt.setString(2, "1' or '1' = '1");

			pstmt.setDouble(3,5000D);

			pstmt.executeUpdate(); // 执行上面已经设置好的sql语句

			

			pstmt.setInt(1, 4535);

			pstmt.executeUpdate(); 



3, 不用拼sql,不用处理sql注入





事务处理

事务

1, 启动事务

无事务:自动提交 auto commit = true

启动事务:关闭自动提交 auto commit = false

con.setAtuoCommit(false);

到达事务上边界

2, 提交

con.commit();

到达事务下边界

3, 回滚

con.rollback();

1, 在捕获到异常时执行

2, 在一定条件下



你可能感兴趣的:(java,sql,jdbc)