练习1
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/** * 用来管理连接 */
public class DBUtil {
private static String driverclass="oracle.jdbc.OracleDriver";
private static String url="jdbc:oracle:thin:@172.96.24.252:1521:orcl";
private static String user="jsd1602";
private static String password="jsd1602";
/** * 1.加载驱动 * 调这个类就是要创建连接,创建连接首先要加载驱动,所以放在静态块中 */
static{
try {
Class.forName(driverclass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("加载驱动错误",e);
}
}
/** * 2.创建连接 * 如何定义一个创建连接的方法 * 返回值类型:看是否有运算结果,若有,结果的类型即为返回值类型 * 参数列表:功能中是否有不确定的数据参与运算,若有,即为参数 */
public static Connection getConnection() throws SQLException{
Connection conn=DriverManager.getConnection(url,user,password);
return conn;
}
/** * 3.关闭连接 */
public static void close(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("关闭连接失败!",e);
}
}
}
//测试该类方法是否可用
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
}
练习2
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
import day01.DBUtil;
/** * junit测试类 * 可以让满足条件的任意方法单独直接执行 * 条件: * 1.该方法必须是public的 * 2.返回值类型必须为void * 3.无参数 * 4.方法前必须加@Test(注解) */
public class TestDay02 {
/** * 使用PreparedStatement解决注入攻击的问题 */
@Test
public void test6(){
//假设用户输入的数据如下
String username="admin";
String password="a' or 'b'='b";
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM users WHERE username=? and password=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,password);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println("登录成功!");
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查询用户失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示PreparedStatement的删除 */
@Test
public void test5(){
//假设要删除的员工ID是
int empno=103;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="DELETE FROM emp WHERE empno=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setInt(1,empno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("删除信息失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示PreparedStatement的修改 */
@Test
public void test4(){
//假设要修改的数据是
int empno=103;
String ename="悟空";
String job="保镖";
int mgr=103;
Date date=new Date(System.currentTimeMillis());
double sal=5000.0;
double comm=0.0;
int deptno=20;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="UPDATE emp SET ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? WHERE empno=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,date);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.setInt(8,empno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("修改信息失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示PreparedStatement的增加 */
@Test
public void test3(){
//假设用户要传入以下数据
String ename="唐僧";
String job="领导";
int mgr=7839;
Date date=new Date(System.currentTimeMillis());
double sal=4500.0;
double comm=500.0;
int deptno=20;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="INSERT INTO emp VALUES(seq_emp.nextval,?,?,?,?,?,?,?)";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,date);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("增加员工失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示PreparedStatement的查询 * 查询工资高于某值的所有员工 */
@Test
public void test2(){
//假设传入的工资是
double salary=3000.0;
//创建连接
Connection con=null;
try{
con=DBUtil.getConnection();
String sql="SELECT * FROM emp WHERE sal>=?";
//创建PreparedStatement对象,发送SQL并建立执行计划
PreparedStatement ps=con.prepareStatement(sql);
//设置参数 ps.set类型(?的索引,?的值)
ps.setDouble(1,salary);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno")+","+rs.getString("ename")+","+rs.getInt("sal"));
}
}catch(SQLException e){
e.printStackTrace();
throw new RuntimeException("查询员工失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示根据ID查询员工 */
@Test
public void test1(){
//假设传入的员工ID是
int id=7900;
//加载驱动-创建连接
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM emp WHERE empno="+id;
Statement smt=con.createStatement();
//执行查询 返回结果集
ResultSet rs=smt.executeQuery(sql);
//结果集中封装了多行数据,需要遍历
while(rs.next()){
//rs.get类型(字段名)或者rs.get类型(字段索引) 可以查看指定字段信息
System.out.println(rs.getInt("empno"));
System.out.println(rs.getString("ename"));
System.out.println(rs.getString("job"));
}
} catch (SQLException e) {
//1.记录日志
e.printStackTrace();
//2.自己能处理则自己处理(如返回默认值)
//3.处理不了则上报(向上抛给调用者)
throw new RuntimeException("查询员工失败!",e);
}finally{
//归还连接
if(con!=null){
DBUtil.close(con);
}
}
}
}
练习3
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.junit.Test;
import dao.EmpDao;
import day01.DBUtil;
import entity.Emp;
public class TestDay03 {
/** * 演示oracle数据库的真分页查询 */
@Test
public void test5(){
//假设需求要求每页显示10条数据
int size=10;
//假设用户当前点击了第2页
int page=2;
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM(SELECT e.*,ROWNUM r FROM (SELECT * FROM emp ORDER BY empno) e)WHERE r BETWEEN ? AND ?";
PreparedStatement ps=con.prepareStatement(sql);
//起始行
ps.setInt(1,(page-1)*size+1);
//终止行
ps.setInt(2,page*size);
ResultSet rs=ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno")+","+rs.getString("ename"));
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查询失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 添加部门,然后向此部门内添加一些员工 */
@Test
public void test4(){
//假设要添加的部门数据如下
String dname="财务部";
String loc="北京";
//假设要添加的员工数据如下
String ename="张三";
String job="经理";
int mgr=0;
double sal=8000.0;
double comm=2000.0;
String ename2="李四";
String job2="职员";
int mgr2=0;
double sal2=5000.0;
double comm2=500.0;
Connection con=null;
try {
con=DBUtil.getConnection();
con.setAutoCommit(false);
//先添加部门
String sql="INSERT INTO depts VALUES(depts_seq.nextval,?,?)";
//参数2是一个数组,存放的是希望被ps记住的字段名
PreparedStatement ps=con.prepareStatement(sql,new String[]{"deptno"});
ps.setString(1,dname);
ps.setString(2,loc);
ps.executeUpdate();
//从ps中获取它之前记录的字段的值 返回的结果集中只有一条数据,存的就是记录的那些字段的值
ResultSet rs=ps.getGeneratedKeys();
rs.next();
int deptno=rs.getInt(1);
//再添加员工1
sql="INSERT INTO emps VALUES(emps_seq.nextval,?,?,?,?,?,?,?)";
ps=con.prepareStatement(sql);
ps.setString(1,ename);
ps.setString(2,job);
ps.setInt(3,mgr);
ps.setDate(4,null);
ps.setDouble(5,sal);
ps.setDouble(6,comm);
ps.setInt(7,deptno);
ps.executeUpdate();
//添加员工2
ps=con.prepareStatement(sql);
ps.setString(1,ename2);
ps.setString(2,job2);
ps.setInt(3,mgr2);
ps.setDate(4,null);
ps.setDouble(5,sal2);
ps.setDouble(6,comm2);
ps.setInt(7,deptno);
ps.executeUpdate();
con.commit();
} catch (SQLException e) {
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
throw new RuntimeException("添加信息失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 演示批量处理数据 添加员工 */
@Test
public void test3(){
Connection con=null;
try {
con=DBUtil.getConnection();
con.setAutoCommit(false);//取消自动提交 使其控制在一个事务中
//批量处理数据的前提是他们的SQL是一样的
String sql="INSERT INTO emp values(seq_emp.nextval,?,?,?,?,?,?,?)";
PreparedStatement ps=con.prepareStatement(sql);
for(int i=1;i<=108;i++){
ps.setString(1,"好汉"+i);
ps.setString(2,"劫匪");
ps.setInt(3,0);
ps.setDate(4,null);
ps.setDouble(5,1000.0);
ps.setDouble(6,7000.0);
ps.setInt(7,3);
//将本条数据暂存到ps内
ps.addBatch();
//每隔30次批量发送一次数据
if(i%30==0){
ps.executeBatch();
//清楚缓存的数据
ps.clearBatch();
}
}
//对于余下的数据单独发送一次
ps.executeBatch();
con.commit();//手动提交
}catch(SQLException e) {
try {
con.rollback(); //回滚
}catch(SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
throw new RuntimeException("批量添加失败!",e);
}finally{
DBUtil.close(con);
}
}
/** * 测试JDBC对事务的控制 演示模拟转账 * 1.验证收款方账号是否存在(查) * 2.验证付款方账号的余额是否充足 * 3.付款方账号-n元 * 4.收款方账号+n元 */
@Test
public void test2(){
//假设用户在ATM上输入了如下信息:
String payID="00001"; //付款账号
String recID="00002"; //收款账号
double money=1000.0; //转账金额
Connection con=null;
try {
con=DBUtil.getConnection();
//1.验证收款方账号是否存在
String sql="SELECT * FROM accounts WHERE id=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1,recID);
ResultSet rs=ps.executeQuery();
if(!rs.next()){
System.out.println("收款账户不存在!");
throw new SQLException("收款账户不存在!");//抛异常
}
double recMoney=rs.getDouble("money"); //记录收款方余额
//2.验证付款方账号的余额是否充足
sql="SELECT * FROM accounts WHERE id=?";
ps=con.prepareStatement(sql);
ps.setString(1,payID);
rs=ps.executeQuery();
rs.next();
double payMoney=rs.getDouble("money");
if(payMoney<money){
System.out.println("账户余额不足!");
throw new SQLException("账户余额不足!");
}
//设置手动管理事务(取消自动提交事务)
con.setAutoCommit(false);
//3.付款方账号-n元
sql="UPDATE accounts SET money=? WHERE id=?";
ps=con.prepareStatement(sql);
ps.setDouble(1,payMoney-money);
ps.setString(2,payID);
ps.executeUpdate();
//Integer.valueOf("a");
//4.收款方账号+n元
sql="UPDATE accounts SET money=? WHERE id=?";
ps=con.prepareStatement(sql);
ps.setDouble(1,recMoney+money);
ps.setString(2,recID);
ps.executeUpdate();
//当转账流程结束时,统一提交事务
con.commit();
}catch(SQLException e) {
//当转账过程发生异常时,回滚事务
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
throw new RuntimeException("回滚失败!",e);
}
e.printStackTrace();
throw new RuntimeException("转账失败!",e);
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil.close(con);
}
}
/** * ResultSetMetaData结果集元数据 */
@Test
public void test1(){
Connection con=null;
try {
con=DBUtil.getConnection();
String sql="SELECT * FROM emp";
PreparedStatement ps=con.prepareStatement(sql);
ResultSet rs=ps.executeQuery();
//获取结果集元数据
ResultSetMetaData md=rs.getMetaData();
//元数据中存储了描述该结果集的信息
System.out.println(md.getColumnCount());
System.out.println(md.getColumnName(1));
System.out.println(md.getColumnClassName(1));//返回的是类型名
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查询失败!",e);
}finally{
DBUtil.close(con);
}
}
}