JDBC——Sql Server
sun公司设计一套java语言操作不同的数据库提供的是接口,二具体的实现类是由各大数据库厂商实现的。

private static final String driver=
"com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static final String url=
"jdbc:sqlserver://localhost:1433;DataBaseName=test";
private static final String user="sa"; //用户名
private static final String password="123456"; //密码
private static Connection con=null;
//加载驱动
Class.forName(driver);
con=DriverManager.getConnection(url,user,password);
JDBC不管是sql server还是mysql大致的原理是一样的,这里只找到了mysql的jdbc部分源码,在Driver的类中,我们找到了如下代码
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// ~ Static fields/initializers
// ---------------------------------------------
//
// Register ourselves with the DriverManager
//
static {
try {
/**
* DriverManager 管理一组 JDBC 驱动程序的基本服务
* 注册了自己,自身实例化了
*/
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
// ~ Constructors
// -----------------------------------------------------------
/**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
所以通过
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
就可以将上面jdbc的driver包下面的静态的代码块直接加载过来,完成驱动的注册,所以在后面就可以有如下代码去连接数据库
con=DriverManager.getConnection(url,user,password);
JDBC接口核心的API
在java.sql.* 和 javax.sql.*包中
|- Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。
|- connect(url, properties): 连接数据库的方法。
url: 连接数据库的URL
URL语法: jdbc协议:数据库子协议://主机:端口/数据库
user: 数据库的用户名
password: 数据库用户密码
|- DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序
|-registerDriver(driver) : 注册驱动类对象
|-Connection getConnection(url,user,password); 获取连接对象
|- Connection接口: 表示java程序和数据库的连接对象。
|- Statement createStatement() : 创建Statement对象
|- PreparedStatement prepareStatement(String sql) 创建PreparedStatement对象
|- CallableStatement prepareCall(String sql) 创建CallableStatement对象
|- Statement接口: 用于执行静态的sql语句
|- int executeUpdate(String sql) : 执行静态的更新sql语句(DDL,DML)
|- ResultSet executeQuery(String sql) :执行的静态的查询sql语句(DQL)
|-PreparedStatement接口:用于执行预编译sql语句(是Statement的子类)
|- int executeUpdate() : 执行预编译的更新sql语句(DDL,DML)
|-ResultSet executeQuery() : 执行预编译的查询sql语句(DQL)
|-CallableStatement接口:用于执行存储过程的sql语句(call xxx)(是PreparedStatement的子类)
|-ResultSet executeQuery() : 调用存储过程的方法
|- ResultSet接口:用于封装查询出来的数据
|- boolean next() : 将光标移动到下一行
|-getXX() : 获取列的值
statement
package com.gqx.api.statement;
import static org.junit.Assert.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
import com.jdbc.util.JDBCUtil;
public class Demo1 {
@Test
public void test() {
/**
* 发送DDL命令
*/
Statement stmt=null;
Connection con=null;
try {
con=JDBCUtil.getConnection();
//准备statement
stmt=con.createStatement();
//创建sql语句
String sql="create table tt(id int primary key IDENTITY(1,1),name varchar(20),password varchar(20))";
//发送sql语句,同时执行结果返回
int count=stmt.executeUpdate(sql);
System.out.println("影响了"+count+"行!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//关闭动作
//顺序:后打开的先关闭
JDBCUtil.close(con, stmt);
}
@Test
public void testDML(){
/**
* 发送DML语句
*/
Statement statement=null;
Connection connection=null;
try {
connection=JDBCUtil.getConnection();
statement=connection.createStatement();
String sql="insert into tt(name,password) values('gqx','1222')";
int count=statement.executeUpdate(sql);
System.out.println("影响了"+count+"行!");
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}
JDBCUtil.close(connection, statement);
}
/*
* DQL
*/
@Test
public void test3(){
Statement stmt=null;
Connection con=null;
//加载驱动
try {
con=JDBCUtil.getConnection();
//准备statement
stmt=con.createStatement();
//创建sql语句
/*
* ResultSet API
* 1、ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。
* next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,
* 所以可以在 while 循环中使用它来迭代结果集。
* 2、ResultSet 接口提供用于从当前行获取列值的获取 方法(getBoolean、getLong 等)。
* 可以使用列的索引编号或列的名称获取值。一般情况下,使用列索引较为高效。列从 1 开始编号。
* 为了获得最大的可移植性,应该按从左到右的顺序读取每行中的结果集列,每列只能读取一次。
*3、用作获取方法的输入的列名称不区分大小写。
*/
String sql="select * from tt";
//发送sql语句,同时执行结果返回
ResultSet result=stmt.executeQuery(sql);
//移动光标
while(result.next()){
int id=result.getInt("id");
String name=result.getString("name");
String password=result.getString("password");
System.out.println("id:"+id+",name:"+name+",password:"+password);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
//关闭动作
//顺序:后打开的先关闭
JDBCUtil.close(con, stmt);
}
}
但他有一个很大的问题,如下,很容易被一些人给玩坏
package com.gqx.api.preparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.jdbc.util.JDBCUtil;
/**
* 模拟用户登录效果
*/
public class Demo2 {
//模拟用户输入
/*
* 更有情节严重的是使用" delete from tt where id=1 or 1=1--" 去删掉你的用户,甚至是表
* 所以一般建议使用preparedStatement
*/
private static String name = "'我是来玩的' OR 1=1 -- ";
private static String password = "123456dfdfddfdf";
public static void main(String[] args) {
// TODO Auto-generated method stub
Statement stmt=null;
Connection con=null;
ResultSet result=null;
try {
con=JDBCUtil.getConnection();
//准备statement
stmt=con.createStatement();
//创建sql语句
String sql="select * from tt where name="+name+"and password="+password;
result=stmt.executeQuery(sql);
if (result.next()) {
System.out.println("登入成功,你好,"+name);
}else {
System.out.println("你登入失败了啊");
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}finally{
JDBCUtil.close(con, stmt,result);
}
}
}

就会发现在该sql语句(select * from tt where name=" '我是来玩的' OR 1=1 --and password="123456dfdfdd" )就会被原封不动的执行,导致错误登入,更有甚者还可能会将数据库的表给破坏掉了,现在可以换一种方法。
PreparedStatement
package com.gqx.api.preparedStatement;
import static org.junit.Assert.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import com.jdbc.util.JDBCUtil;
/**
*
* @author Administrator
* public interface PreparedStatementextends Statement表示预编译的 SQL 语句的对象。
* SQL 语句被预编译并存储在 PreparedStatement 对象中。
* 然后可以使用此对象多次高效地执行该语句。
*
*/
public class Demo {
@Test
public void test() {
PreparedStatement statement=null;
Connection connection=null;
try {
connection=JDBCUtil.getConnection();
//准备一条预编译的sql语句,用问号代替相应的字符串,预编译的时候,?是一个占位符
String sql="insert into tt(name,password) values(?,?)";
statement=connection.prepareStatement(sql);
//设置参数值,参数一,表示参数的位置,参数二表示值
statement.setString(1, "哈哈哈");
statement.setString(2, "222222");
//发送参数执行
int count=statement.executeUpdate();
System.out.println("影响了"+count+"行!");
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}
JDBCUtil.close(connection, statement);
}
@Test
public void Test2(){
PreparedStatement statement=null;
Connection connection=null;
ResultSet result=null;
try {
connection=JDBCUtil.getConnection();
//准备一条预编译的sql语句,用问号代替相应的字符串,预编译的时候,?是一个占位符
String sql="select * from tt where id =?";
statement=connection.prepareStatement(sql);
statement.setInt(1, 1);
//发送参数执行
result=statement.executeQuery();
while (result.next()) {
int id=result.getInt("id");
String name=result.getString("name");
String password=result.getString("password");
System.out.println("id:"+id+",name:"+name+",password:"+password);
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}finally{
JDBCUtil.close(connection, statement,result);
}
}
}
由于它的运行机制如下:

所以不会发生以上用户胡乱登入的情况。
CallableStatement
带有输入输出的存储过程
package com.gqx.api.CallableStatement;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import com.jdbc.util.JDBCUtil;
/**
* 使用CablleStatement调用存储过程
* @author Administrator
*
*/
public class Demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JDBCUtil.getConnection();
//准备sql
//第一个?是输入参数,第二个?是输出参数
String sql = "{call NOD (?,?)}"; //可以执行预编译的sql
//预编译
stmt = conn.prepareCall(sql);
//设置输入参数
stmt.setString(1, "CS");
//设置输出参数(注册输出参数)
/**
* 参数一: 参数位置
* 参数二: 存储过程中的输出参数的jdbc类型 VARCHAR(20)
*/
stmt.registerOutParameter(2, java.sql.Types.INTEGER);
//发送参数
stmt.execute(); //结果不是返回到结果集中,而是返回到输出参数中
//得到输出参数的值
/**
* 索引值: 预编译sql中的输出参数的位置
*/
String result = stmt.getString(2); //getXX方法专门用于获取存储过程中的输出参数
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JDBCUtil.close(conn, stmt ,rs);
}
}
}
程序的util包下的JDBCUtil
package com.jdbc.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.omg.CORBA.portable.InputStream;
public class JDBCUtil {
static String url=null;
static String user=null; //数据库管理员名
static String pass=null; //密码
static String driver=null; //密码
/*
* 静态代码块只加载一次
*/
static{
//读取db.propties
try {
Properties proper =new Properties();
/**
* . 代表java命令运行的目录
* 在java项目下,. java命令的运行目录从项目的根目录开始
* 在web项目下, . java命令的而运行目录从tomcat/bin目录开始
* 所以不能使用点.
*/
//FileInputStream in =new FileInputStream("./src/db.properties");
java.io.InputStream in = JDBCUtil.class.getResourceAsStream("/db.properties");
//加载信息
proper.load(in);
url=proper.getProperty("url");
user=proper.getProperty("user");
pass=proper.getProperty("pass");
driver=proper.getProperty("driver");
//读取信息
Class.forName(driver);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("驱动程序注册失败");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取JDBC连接对象的方法
*/
public static Connection getConnection(){
try {
Connection connection=DriverManager.getConnection(url,user,pass);
return connection;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException();
}
}
/*
* 关闭操作
*/
public static void close(Connection con,Statement stmt){
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (con!=null) {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
/**
* 这是方法的重载
* @param con
* @param stmt
* @param resultSet
*/
public static void close(Connection con,Statement stmt,ResultSet resultSet){
if (resultSet!=null) {
try {
resultSet.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (con!=null) {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
JDBC——Sql Server的更多相关文章
- JDBC连接SQL Server遇到的问题
需要使用到微软的JDBC sql server的驱动类,去官网下载jar包 使用的URL模式:"jdbc:sqlserver:地址:端口//;databaseName=YourDatabas ...
- 使用Apache JMeter对SQL Server、Mysql、Oracle压力测试(二)
接着第一篇的写: 第三步,测试SQL Server数据库的性能: a.加载JDBC SQL Server驱动.添加线程组和设置线程属性和第二步一样,就不再赘述了: b.设置JDBC Connectio ...
- spring boot(二): spring boot+jdbctemplate+sql server
前言 小项目或者做demo时可以使用jdbc+sql server解决即可,这篇就基于spring boot环境使用jdbc连接sql server数据库,和spring mvc系列保持一致. 在sp ...
- 喜大普奔,微软Microsoft JDBC Driver For SQL Server已发布到maven中央仓库
相信通过java和SQLServer开发应用的同学们都经历过如下类似的问题. 微软提供的JDBC官方驱动没有放置在Maven仓库中,这样如果你的Java应用需要访问SQL Server,你不得不下载s ...
- JDBC连接SQL Server代码模板
* JDBC连接SQL Server数据库 代码模板* Connection: 连接数据库并担任传送数据的任务:* Statement : 执行SQL语句:* Re ...
- JDBC连接sql server数据库及其它
JDBC连接sql server数据库的步骤如下: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的 ...
- jdbc至sql server的两种常见方法
Statement和prepareStatement sql server中已建立BookPhone数据库,包含bookPhone表,eclipse中有BookPhone类,三个string类型的值 ...
- 【J2EE】Java连接SQL Server 2000问题:“com.microsoft.sqlserver.jdbc.SQLServerException:用户'sa'登录失败。该用户与可信SQL Server连接无关联”
1.问题现象 E:\JSP\HibernateDemo\HibernateDemoProject\src\sine>java ConnectSQLServerConnect failed!com ...
- JDBC与SQL SERVER各个版本的连接方法
转至:blog.csdn.net/ying5420/article/details/4488246 1.SQL SERVER 2000 JDBC驱动程序:msbase.jar.mssqlserver. ...
随机推荐
- Python 集合(set)使用
1.python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差 ...
- python 数据运算
算数运算:
- Python深入学习笔记(一)
写在前面的话 从08年接触Python到现在,断断续续地使用,到如今Python已经成为日常事物处理.科研实验,甚至工程项目的主力语言,主要因为其敏捷性和快速实现的能力.虽然看了一些Python的教程 ...
- Apache httpd.conf的翻译
本人初学,15年暑假翻译了一些,前几天翻译完,有机器翻译,也有自己翻译的内容,不准确之处请指出. --------------------------------------------------- ...
- XSS测试用例与原理讲解
1.<a href="javascript:alert(32)">DIBRG</a>2.<img href="javascript:aler ...
- 高远介绍的好东东--django-celery
终于可以到异步消息机制的高档产品啦~~~ 不知能不能代替AJAX.. 参照官方文档试下: 中文文档: http://docs.jinkan.org/docs/celery/getting-starte ...
- Intellij IDEA快速编写代码经验总结
sout=System.out.println(); soutp=System.out.println(""); soutv=System.out.println("变量 ...
- java向文件写数据的3种方式
下边列举出了三种向文件中写入数据的方式,当然还有其他方式,帮助自己理解文件写入类的继承关系.类的关系: file->fileoutputstream->outputstreamWriter ...
- 使用IRP进行文件操作
使用IRP进行文件操作 首先声明这个是菜鸟—我的学习日记,不是什么高深文章,高手们慎看. 一定要先感谢为技术的进步而付出辛勤汗水的人,感谢他们对技术的共享. 一个通用IRP访问文件的十六进制编辑器(开 ...
- 備份Sqlite DB到XML文件:
转载请注明出处:http://blog.csdn.net/krislight 项目中遇到备份与还原App数据的需求,需要把DB数据备份到一个XML文件中,然后保存到SD卡上,还原的时候直接从XML文件 ...