JDBC学习笔记

JDBC学习笔记

JDBC基本用法

JDBC Java DataBase Connectivity Java语言连接数据库

本质 sun公司制定的一套接口

面向接口编程 降低耦合度,提高可扩展能力

JDBC编程六步

注册驱动即将连接的是哪一个数据库型号
获取连接表示JVM进程和数据库通道打开,属于进程间的通信,重量级
获取数据库操作对象专门执行sql语句的对象
执行SQL语句DQL DML …
处理查询结果集只有上一步是selece时,才执行这一步
释放资源使用完一定要关闭资源。这数据进程间的通信,时间久会有问题

注册驱动

try{
    DriverManager.registerDriver(new come.mysql.jdbc.Driver());
}
catch(SQLException e){
    e.printStackTrace();
}
//推荐使用这种方法
try{
    String driver = "com.mysql.jdbc.Driver";
    Class.forName(driver);
}
catch(CLassNotFoundException e){
    e.printStackTrace();
}

获取连接

String url = "jdbc:mysql://127.0.0.1:3306/database";
// jdbc:mysql://ip:端口/数据库名
String user = "root";
String password = "password";
Connection conn = DriverManager.getConnection(url,user,password);

获取数据库操作对象

 Statement stmt = conn.createStatement();

执行SQL语句

//sql语句不用写分号;
String sql = "insert into ... values...";
int count  = stmt.executeUpdate(sql);
System.out.println(count == 1 ? "保存成功" : "保存失败");

释放资源

finally{
	//从小到大进行关闭
    try{
        if(stmt != null){
            stmt.close;
        }
    }
    catch(SQLException e){
        e.printStackTrace();
    }
    try{
        if(conn != null){
            conn.close;
        }
    }
    catch(SQLException e){
         e.printStackTrace();
    }
}

增删改总执行步骤

Connection conn = null;
Statement stmt = null;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://127.0.0.1:3306/database";
String user = "root";
String password = "password";
try{
	//加载驱动
	Class.forName(driver);
	//获取连接
	conn = DriverManager.getConnection(url,user,password);
	//获取数据库操作对象
	stmt = conn.createStatement();
	//执行SQL语句
	String sql = "insert into ... values...";
    int count  = stmt.executeUpdate(sql);
    System.out.println(count == 1 ? "保存成功" : "保存失败");
}
catch(SQLException e){
 	e.printStackTrace();
}
catch(ClassNotFoundException e){
    e.printStackTrace();
}
finally{
	//从小到大进行关闭
    try{
        if(stmt != null){
            stmt.close;
        }
    }
    catch(SQLException e){
        e.printStackTrace();
    }
    try{
        if(conn != null){
            conn.close;
        }
    }
    catch(SQLException e){
         e.printStackTrace();
    }
}

使用配置文件进行操作

--jdbc.proerpties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/database
user=root
password=password
Connection conn = null;
Statement stmt = null;
ResourceBundle bundle= ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");

查询

ResultSet rs = null;
String sql = "select empno,ename,sal fron emp";
//执行DQL的方法 executeQuery
rs = stmt.executeQuery(sql);
//处理查询结果集 next 下一行 每一列从1-n
//遍历结果集
while(rs.next()){
    int empno = rs.getInt("empno");
    String ename = rs.getStirng("ename");
    double sal = rs.getDouble("sal");
}
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
try{
	Class.forName(driver);
    conn = DriverManager.getConnection(url,user,password);
    stmt = conn.createStatement();
    String sql = "select empno,ename,sal fron emp";
    //执行DQL的方法 executeQuery
    rs = stmt.executeQuery(sql);
    //处理查询结果集 next 下一行 每一列从1-n
    //遍历结果集
    while(rs.next()){
        int empno = rs.getInt("empno");
        String ename = rs.getStirng("ename");
        double sal = rs.getDouble("sal");
    }
}
catch(SQLException e){
	e.printStackTrace();
}
catch(ClassNotFoundException e){
	e.printStackTrace();
}
finally{
    try{
		if(rs != null) rs.close;
	}
	catch(SQLException e){
		e.printStackTrace();
	}
	try{
		if(stmt != null) stmt.close;
	}
	catch(SQLException e){
		e.printStackTrace();
	}
	try{
		if(conn != null) conn.close;
	}
	catch(SQLException e){
		e.printStackTrace();
	}
}

数据库模型的设计工具 PowerDesigner,一款强大的数据库模型设计工具

SQL 注入

安全隐患 在用户输入信息时,输入了sql语句,导致sql语句被修改

例子

//原SQL语句
String username;
String password;
String sql = "select * from emp where username = '"+username+"' and password = '"+password+"'";
//用户输入
username = qianzi
password = qianzi' or '1' = '1
//拼接的sql为
String sql  = "select * from emp where username = 'qianzi' and password = 'qianzi' or '1' = '1'";
//导致password无论是什么都会登录成功

根本原因 用户输入的信息被拼接到SQL语句中,并且被编译,导致原sql语句被扭曲了

解决方案 只要用户提供的信息不参与编译过程,即使用户提供的信息含有sql关键字

使用 PreparedStatement 替换 Statemenet PreparedStatement 会对sql进行预编译,只能传值进去

//获取预编译的数据库操作对象
PreparedStatement ps;
//其中一个?表示一个占位符,?不需要''括起来
String sql = "select * from emp where username = ? and password = ?";
//预编译
ps = conn.prepareStatement(sql);
//设置占位符
ps.setString(1,username);
ps.setString(2,password);
//获取结果集
rs = ps.executeQuery();

PreparedStatement执行效率比Statement高

先编译,然后每次只需要执行,不需要再编译

PreparedStatement在编译时进行安全检查

PreparerStatement使用情况较多,一般情况下不使用Statement

当项目开发时需要sql注入的时候,才使用Statement,一般情况下不需要用户输入内容

JDBC 事务

JDBC事务 JDBC默认自动提交事务

在业务中,要使得几个sql语句同时成功或失败,需要使用事务

修改手动提交

conn.setAutoCommit(false);

提交和回滚

conn.commit();		//提交
conn.rollback();	//回滚

格式

try{
    conn.setAutoCommit(false);		//开启事务
    ...
    conn.commit();					//提交事务
}
catch(Exception e){
	if(conn != null){
		try{
			conn.rollback;
		}
		catch(SQLException e){
			e.printStackTrace();
		}
	}
}

JDBC 工具类

publice class DBUtil{
	//工具类中的方法是私有的
	private DBUtil() { }
	//静态代码块在类加载时执行一次
	static{
		try{
			Class.forName("com.mysql.jdbc.Driver");
		}
		catch(ClassNotFoundException e){
			e.printStackTrace();
		}
	}
	//获取数据库连接对象
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/database","root","password");
	}
	//关闭资源
	public static void close(Connection conn,Statement ps,ResultSet rs){
		 try{
         	if(rs != null) rs.close;
         }
         catch(SQLException e){
         	e.printStackTrace();
         }
         try{
         	if(stmt != null) stmt.close;
         }
         catch(SQLException e){
        	 e.printStackTrace();
         }
         try{
        	 if(conn != null) conn.close;
         }
         catch(SQLException e){
         	e.printStackTrace();
         }
	}
}

SQL 行级锁

行级锁 悲观锁,for update,在sql语句最后加。为了不让其他事务操作sql找出来的数据。事务必须排队执行,不允许并发

乐观锁 事务可以并发,并对数据设置版本号

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值