数据库-第四天-java操作数据库

本文介绍SQLServer数据库的备份及恢复方法,并详细讲解Java程序如何操作数据库,包括使用Statement与PreparedStatement进行CRUD操作,以及如何预防SQL注入攻击。

内容:

1.sql server数据库的备份和恢复

2.java程序如何操作数据库

目标:

1.掌握sql sever数据库的备份和恢复技巧

2.掌握java对表的 crud 操作

3.掌握Statement和PreparedSatement

4.能完成一般的java数据库编程任务

分离/附加:影响原数据库

备份/恢复:不影响原数据库

--如何备份数据库
backup database liang to disk = 'f:/sp.bak'

--删除数据库
drop database liang

--恢复数据库
restore database Liang from disk = 'f:/sp.bak'

--有时,可能不需备份整个数据库,只备份表

 

java程序操作数据库

crud(增删改查):增加(Create)、查询(Retrieve)、更新(Update)和删除(delete),主要描述软件系统中数据库的基本操作功能。

jdbc

JDBC(Java Data Base Connectivity,java数据库连接)是一种执行SQL语句的javaAPI,可以为多种关系数据库提供统一的访问。它由一组由java语言编写的类和接口组成。JDBC为工具/数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯java API编写数据库应用程序。

image                                                                                 常见的两种jdbc驱动方式图

 

jdbc驱动分类

目前常见的JDBC驱动程序可以分为四个种类:

(1)jdbc-odbc桥连接

(2)本地协议纯java驱动程序

(3)网络协议纯java驱动程序

(4)本地api

jdbc的不足

JDBC在java语言层面实现了统一,但在不同数据库之间存在许多差异,为了更好的实现跨数据库操作,诞生了Hibernate(orm技术)

,实现了JDBC的再封装,实现了对数据库操作更为广泛的统一和更好的移植性

案例:

1.使用jdbc-odbc(open data base connectivity)桥接的方式操作sql server数据库。

   需要配置数据源:

   打开 管理工具-> 数据源(ODBC);在用户DSN项中添加一个数据源“mytest”,其中服务器 写/选 local 或写 . ,然后...;配置完后可测试数据源状态  

jdbc-odbc案例代码/*
 * 演示使用jdbc-odbc桥接方式操作的数据库 spdb1 (emp,dept)
 * 1.配置数据库
 * 2.在程序中连接数据库
 * 
 * */

package test1;

import java.sql.*;
public class Test1 {

	public static void main(String[] args) {

		Connection ct = null;
		Statement sm = null;
		try{
			//1.加载驱动(把需要的驱动程序加入内存)
			Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
			//2.得到连接(引入包sql) connect to a data source
			//指定连接到哪个数据源,若是window nt验证,则不需要用户名与密码
			ct = DriverManager.getConnection("jdbc:odbc:mytest");
			
			//3.创建Statement或者PreparedStatement【区别?】
			//Statement用处是:主要用于发送SQL语句 到数据库
			sm = ct.createStatement();
			
			//4.执行(crud,创建数据库,备份数据库,删除数据库)
			
			//1.添加一条数据到dept表
			// executeUpdate可以执行cud操作
	//		int i = sm.executeUpdate("insert into dept values(50,'保安部','深圳')");
    // 	    int i = sm.executeUpdate("delete from detp where DeptNO=50");

	/*		int i = sm.executeUpdate("update dept set loc='北京' where deptNo=50 ");	
			if (i==1)
			{
				System.out.println("修改成功!");
			}
			else
			{
				System.out.println("修改失败");
			}
		*/	
			
			//查询,显示所有的部门
			//ResultSet结果集,可以理解成一个表行的结果集
			ResultSet rs = sm.executeQuery("select * from dept");
	/*		rs.next();
			int deptNo = rs.getInt(1);
			String dName = rs.getString(2);
			String loc = rs.getString(3);
			System.out.println(deptNo+"\n"+dName+"\n"+loc);
			
	*/		
		//	取出查询的所有结果
			while(rs.next())
			{
				int deptNo = rs.getInt(1);
				String dName = rs.getString(2);
				String loc = rs.getString(3);
				System.out.println(deptNo+""+dName+""+loc);
			}
			
		}catch(Exception e)
		{
			e.printStackTrace();
			
		}finally{
			//资源关闭!!!!
			//关闭顺序是:谁后创建,谁先关闭
			try {
				if(sm!=null)
				{
				    sm.close();
				}
				if(ct!=null)
				{	   
				    ct.close();
				}
			
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	

	}

}

 

 

 

注:此时的jdbc-odbc桥接驱动为:sun.jdbc.odbc.JdbcOdbcDriver

在cmd中使用 netstat –an 可查看连接状态。

注:资源 ResultSet 也要删除!

Statement和PreparedStatement的区别:

Statement和PreparedStatement都可以用于把sql语句从java程序中发送到指定的数据库,并执行sql语句,但存在如下区别:

(1)直接使用Statement,驱动程序一般不会对sql语句做处理而直接交给数据库;使用PreparedStatement,形成预编译的过程(在客户端程序中预先编译成数据库能直接执行的二进制代码),并能对语句做字符集的转换(至少在sql server)中如此。

好处:对于多次重复执行的语句,使用PreparedStatement效率会更高一些(提供小部分缓存),并且在此种情况下也较适合使用batch(批处理);另外可以比较好的解决系统本地化问题。

PreparedStatement将数据库的压力分散到客户端。

(2)PreparedStatement还能有效的防止危险字符的注入。

 image

 

 

--演示sql注入漏洞

create table users(
username varchar(30),
passwd varchar(30)
)

insert into users values('baiweiguo','baiweiguo')

select * from users where username = 'dekjg' and passwd='gasdj' or 1='1' 

 

    使用PreparedStatement编码: 

preparedStatement代码javapackage test1;
import java.sql.*;
public class Test2 {

	
	public static void main(String[] args) {
		
		//定义需要的对象
		PreparedStatement ps = null;
		Connection ct = null;
		ResultSet rs = null;
		
		try{
			//1.加载驱动
			Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
			//2.得到连接
			ct = DriverManager.getConnection("jdbc:odbc:mytest");
			//3.创建ps
			ps = ct.prepareStatement("select * from dept where deptNo=? and loc=?");
			
			//可以给?赋值
			ps.setInt(1, 20);  //第一个参数表示第几个问号
			ps.setString(2, "dallas");
			
			//preparedStatement通过使用?机制可放置注入漏洞
			//如果不用 ? 机制,达不到注入密码
			
			
			rs = ps.executeQuery();
			
			while(rs.next())
			{
				int deptNo = rs.getInt("deptNO");
				String Dname = rs.getString(2);
				String loc = rs.getString(3);
				System.out.println(deptNo+""+Dname+""+loc);
			}						
			
		}catch(Exception e)
		{
			e.printStackTrace();
		}finally{
			//关闭资源!!!
			try{
				if(rs!=null)
				{
					rs.close();
				}
				if(ps!=null)
				{
					ps.close();
				}
				if(ct!=null)
				{
					ct.close();
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();		
				
			}
		}

	}

}

 

 

注:

PreparedStatement中使用 ? 机制才能防止注入漏洞,否则不能防止。

如下代码同样能获取用户姓名与密码:

ps = ct.prepareStatement("select * from users " +
					"where username = 'ba' and passwd = 'gjk' or 1=1");
rs = ps.executeQuery();
			
while(rs.next())
{
	System.out.println(rs.getString("username")+""+rs.getString("passwd"));
}

 

总结:

     1.PreparedStatement可以提供执行的效率(它有预编译的功能)

     2.PreparedStatement可以防止sql注入,但是要求用?赋值的方式才行。

2.使用 jdbc 驱动程序直接操作sql server数据库。

注意:

1.sql server 2008的驱动名字(记):com.microsoft.sqlserver.jdbc.SQLServerDriver

2.不需要创建数据源,但需要加载包 sqljdbc4.jar

127.0.0.1表示要连接的数据库的ip,此处为本地ip,可以是 localhost

1433表示sql server的默认端口

jdbc方式操作数据库/*
 * jdbc方式操作数据库
 * 1.把java.sql.*引入
 * 2.SQL server 2008需要引入包 sqljdbc4.jar
 * 
 * */

package com.test2;
import java.sql.*;
public class Test1 {

	
	public static void main(String[] args) {
		//PreparedStatement 【火箭车】
		
		//定义所需要的对象
		PreparedStatement ps = null;
		Connection ct = null;
		ResultSet rs = null;
		
		try{
			//初始化对象:
			//1.加载驱动
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
			//2.得到连接
			ct = DriverManager.getConnection
					("jdbc:sqlserver://localhost:1433;databaseName=spdb1","sa","119035");
		
			//创建火箭车
	/*		ps = ct.prepareStatement("select * from dept");
			//执行(增删改查)
			rs = ps.executeQuery();
			
			while(rs.next())
			{
				System.out.println(rs.getInt("deptNo")+" "+rs.getString("Dname")+" "+rs.getString("loc"));
			}
		*/
			//多表查询
			ps = ct.prepareStatement("select eName,sal,dName from emp,dept where emp.deptNo=dept.deptNo");
			rs = ps.executeQuery();
			while(rs.next())
			{
				String eName = rs.getString(1);//eName = rs.getString("eName");
				float sal = rs.getFloat(2);
				String dName = rs.getString(3);
				System.out.println(eName+""+sal+""+dName);
			}
			
			//添加、删除和修改
			ps = ct.prepareStatement("update dept set dName = ?, loc = ? where deptNo=60 ");
			//给?赋值
			
			ps.setString(1, "销售");
			ps.setString(2, "北京");
			
			int i = ps.executeUpdate();
		
			if(i==1)
				System.out.println("修改成功!");
			
			
		}catch(Exception e)
		{
			e.printStackTrace();
		}finally
		{
			
		}

		
	}

}

 

转载于:https://www.cnblogs.com/baiweiguo/archive/2013/02/21/2920638.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值