您的位置:首页 > 数据库

数据库相关(3) JDBC

2015-07-30 21:24 351 查看
1.JDBC 基础

Sun公司为简化数据库开发,定义了一套jdbc接口,这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库



demo



数据库是从1开始计数,而不是0

public class MyJDBCDemo {

public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
//加载驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//建立连接,账户密码,这是在本机上的简写方式
Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb2","root","code");
//执行语句的载体
Statement st=conn.createStatement();
String sql = "select * from users;";
//执行
ResultSet rs=st.executeQuery(sql);
//处理结果集
while(rs.next()){
System.out.println("MyJDBCDemo.main()"+rs.getObject(1)+rs.getObject(2));
}
//需要关闭
rs.close();
st.close();
}

}


返回的是第一个元素 id 和第二个 name





1.1 DriverManager

主要用来:

加载驱动:DriverManager.registerDriver(new Driver())

建立连接:DriverManager.getConnection(url, user, password)

1.2Collection

createStatement():创建向数据库发送sql的statement对象
prepareStatement(sql) :创建向数据库发送预编译sql的
setAutoCommit(boolean autoCommit):设置事务是否自动提交
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。

1.3 Statement

executeQuery(String sql) :用于向数据发送查询语句
executeUpdate(String sql):用于向数据库发送insert、update或delete语句
execute(String sql):用于向数据库发送任意sql语句
注意:insert语句执行后返回值是被影响的行数
单独的execute返回值,查询时true,增删改是false,可以利用这一点来判断传过来的SQL语句是哪一类



1.4 ResultSet

用于代表Sql语句的执行结果
ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据,所以该对象提供的都是用于获取数据的get方法:
获取任意类型数据:getObject(int index) getObject(string columnName)

获取指定类型的数据:getString(int index) getString(String columnName)

在实际应用中,更推荐使用列名获取对象而不是列表’id’

通常使用如下方式获取每一列的相关属性值,而不是采用object的方式,方便直接赋值

当某一条执行完毕到最后,光标应该移到句首执行下一条



1.5 释放资源

Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放

为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中

public class MyJDBCDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1  加载驱动
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","cskaoyan");
//3,获取statement 用于执行sql语句
st = conn.createStatement();
//4,生成sql语句,并执行
//execute
String sql = "select * from users;";
boolean flag = st.execute(sql);
//5,处理结果集
if (flag) {
rs=st.getResultSet();
while(rs.next()){
System.out.println("MyJDBCDemo.main()"+rs.getInt("id")+"\t"+
rs.getString("name")+"\t"+
rs.getString("password")+"\t"+
rs.getString("email"));
}
}

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
//6.关闭连接
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}


2.JDBC升级版

2.1 预处理

PreperedStatement是Statement的孩子,它的实例对象可以通过调用Connection.preparedStatement()方法获得

Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写,在一些其他数据一样,只是参数不同的查询情形下很适用。

public class PrepareStDemo {
public static void main(String[] arg){
Connection conn = null;
Statement st = null;
PreparedStatement prest = null;

ResultSet rs = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","rjl000");
st = conn.createStatement();

String idString = "1";
String sql = "select * from users where id ='"+ idString+"';";

String sql2 = "insert into users values (4,'zl','123456','zl@sina.com');";

int id = 6;
String name = "zl";
String password = "123456";
String email = "zl@sina.com";
String sql3 = "insert into users values ("+id+",'"+name+"','"+password+"','"+email+"')";

/* st.executeUpdate(sql3);*/

String sql4 = "insert into users values(?,?,?,?)";
prest = conn.prepareStatement(sql4);
prest.setInt(1,id);
prest.setString(2,name);
prest.setString(3,password);
prest.setString(4,email);
prest.executeUpdate();


2.2 大数据

分为大文本和二进制文件(图片、音视频)

都要设置处理方法和数据的读写





public class MyJdbcBigTestDemo {
public static void main(String[] arg) throws IOException{
Connection conn = null;
Statement st = null;
PreparedStatement prest= null;

ResultSet rs=null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb7","root","rjl000");
String sql = "insert into table1 values (?,?);";
prest = conn.prepareStatement(sql);

String sqlString = "select * from table1 where id =2;";//注意不能使index,这是保留字
st = conn.createStatement();
rs = st.executeQuery(sqlString);
while(rs.next()){
int index = rs.getInt(1);
Reader reader = rs.getCharacterStream(2);
File fileout = new File("src/b.txt");

Writer writer = new FileWriter(fileout);
char ch[] = new char[1024];
int len;
while((len=reader.read(ch))!= -1){
writer.write(ch,0,len);
}
writer.close();  //注意关闭流
reader.close();

}
}	catch(SQLException e){
e.printStackTrace();
}
finally{
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(st!=null){
try{
st.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}


public class MyJdbcBigBinaryDemo {
public static void main(String[] arg) throws IOException{
Connection conn = null;
Statement st = null;
PreparedStatement prest= null;

ResultSet rs=null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//1.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb7","root","rjl000");
//2,获取statement 用于执行sql语句
String sql = "insert into table2 values (?,?);";
prest = conn.prepareStatement(sql);
//3.从数据库里面读出的内容保存到 文件
String sqlString = "select * from table2 where id =1;";
st = conn.createStatement();
rs = st.executeQuery(sqlString);

while (rs.next()) {

int index= rs.getInt(1);
System.out.println("MyJdbcBigTestDemo.main()"+index);

InputStream fis =   rs.getBinaryStream(2);

File fileout  = new File("src/02.jpg");
FileOutputStream fos  =  new FileOutputStream(fileout);

byte[] b = new byte[1024];
int len=0;

while ((len=fis.read(b))!=-1) {
fos.write(b, 0, len);
}

fos.close();
fis.close();
}
}	catch(SQLException e){
e.printStackTrace();
}
finally{
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(st!=null){
try{
st.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}


2.3 批处理

当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率

Statement.addBatch(sql)

可以向数据库发送多条不同的SQL语句

当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句

PreparedStatement.addBatch()

发送的是预编译后的SQL语句,执行效率高。

只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据

注意内存溢出问题

executeBatch()方法:执行批处理命令

clearBatch()方法:清除批处理命令

一条一条执行






批处理1






只是参数不同是,可用循环来简化






倘若一次处理数据太多,会影响数据库性能,此时可以写一个判断语句,一次执行若干条。倘若要写20条,10条处理一次,[b]这是个常用的写法,如果不是整数条呢?就需要在循环外再添加一个执行,比如写25条

[/b]

[b] 这里数据库中已经有了18条,所以从19开始[/b]

//4,生成sql语句,并执行
String sql1 = "insert into users values (11,'a','123','xjbd');";
String sql2 = "insert into users values (12,'aa','123','xjbd');";
String sql3 = "insert into users values (13,'aaa','123','xjbd');";
String sql4 = "insert into users values (14,'aaaa','123','xjbd');";
String sql="insert into   users values (?,?,?,?);";
prest = conn.prepareStatement(sql);
for (int i = 0;i<25;i++) {
prest.setInt(1, i+19);
prest.setString(2, "aaa"+i);
prest.setString(3, "123"+i);
prest.setString(4, "aaa@163.com"+i);

prest.addBatch();
if (i%10==0) {
prest.executeBatch();
prest.clearBatch();
}
}
prest.executeBatch();
prest.clearBatch();

int i[] = prest.executeBatch();
for(int result: i){
System.out.println("MyJdbcBatchDemo.main()"+result);
}
prest.clearBatch();


2.4 调用存储过程

定义一个核心的procedure,只知道有这么一个过程接口,在一些机密要求比较高的应用场合,比如在金融机构,查询一个数据,只需要传入一个ID,传出一个数据,而隐藏了表明列名等信息。

先在数据库里定义这个procedure



public class MyProcedureDemo {
public  static void main(String[] srg){
Connection conn=null;
Statement st=null;
ResultSet rs=null;
CallableStatement callst;
try {
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","rjl000");
//3,获取statement 用于执行procedure方法
callst = conn.prepareCall("{call demofunc(?, ?)}");
//传入参数
callst.setString(1, "abcdef");
callst.registerOutParameter(2, Types.VARCHAR);
callst.execute();

String result = callst.getString(2);
System.out.println("MyProcedureDemo.main()"+result);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
//6.关闭连接
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: