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. ...
随机推荐
- ∑–△型模数转换器(ADC)简介
∑–△型模数转换器(ADC) 1.概述 近年来,随着超大规模集成电路制造水平的提高,Σ-Δ型模数转换器正以其分辨率高.线性度好.成本低等特点得到越来越广泛的应用.Σ-Δ型模数转换器方案早在20世纪60 ...
- 基于jsp+servlet图书管理系统之后台用户信息查询操作
上一篇的博客写的是插入操作,且附有源码和数据库,这篇博客写的是查询操作,附有从头至尾写的代码(详细的注释)和数据库! 此次查询操作的源码和数据库:http://download.csdn.net/de ...
- Codeforces Round #197 (Div. 2) : C
哎....这次的比赛被安叔骂的好惨! 不行呢,要虐回来: 这道搜索,老是写错,蛋疼啊! 果然是基础没打好! #include<cstdio> using namespace std; ], ...
- WordPress 全方位优化指南(上)
作为一个全面的 WordPress 性能优化教程,本文旨在帮助读者排查 WordPress 网站的性能问题,同时也提供网站前端优化加速的建议. 如果你曾经遇到过 WordPress 管理界面加载缓慢. ...
- windows远程桌面连接配置
我的电脑 -> 属性 -> 远程 把两个checkbox勾上 运行(win + r) -> 输入secpol.msc回车 -> 找到本地策略 -> 安全选项 ->账 ...
- 23个移动app界面上的旋钮和刻度盘设计示例
摘要: 从最初进入电子设备领域,旋钮和刻度盘的由最初的功能性设计转变为时尚的外观设计元素,比如在移动app中.这种转变并意外,旋钮和刻度盘不需要占用移动设备的太多空间,并可以简单地为用户提供一些列 ...
- 【HDOJ】3047 Zjnu Stadium
带权并查集. /* 3047 */ #include <iostream> #include <string> #include <map> #include &l ...
- bzoj2553
似乎挂精度了,不过这是一道好题 很明显看题知算法,知道这道题肯定是AC自动机上矩阵乘法 首先要明确一点,对一个字符串,怎样划分禁忌串最多 根据求最多不相交线段可知,从头到尾能划分出禁忌串就划分 根据这 ...
- POJ_2100_Graveyard_Design_(尺取法)
描述 http://poj.org/problem?id=2100 求连续平方和=n的序列个数,并输出序列. Graveyard Design Time Limit: 10000MS Memory ...
- IE浏览器下读取客户端上传的文件大小
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...