JDBC是J2SE的内容,是由java提供的访问数据库的接口,但没有提供具体的实现方法,需要数据库厂商提供,就是对应的数据库驱动。

这样的好处是可以方便的更换数据库,提高了扩展性。这也是面向接口编程的一个优点。

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class Demo {
public static void main(String[] args) throws ClassNotFoundException, SQLException{
//连接数据库,获取连接对象
Connection conn=connection();
//使用连接对象进行数据库的操作:增、删、改
sqlDemo(conn);
//使用连接对象进行数据库的操作:查
queryDemo(conn);
//sql规范写法,
sqlDemo2();
} public static Connection connection() throws ClassNotFoundException, SQLException { /*注册数据库驱动对象的简便方法:
* Java中在使用数据库对象时,需要通过相应的驱动来实现,并且要通过DriverManager类来注册这个驱动
* 上面的操作已经被写入驱动类中的静态代码块中了,所以可以直接加载该类就实现了上述操作
*
* 在jdbc4.0之后的版本中有些数据库驱动有一个配置文件可以进行注册,也就是可以省略下面一句,
* 但是并非所有驱动都可以,而且为了兼容性更好,建议使用
*/
Class.forName("com.mysql.jdbc.Driver"); //获取数据库连接对象
/*jdbc四大配置参数
* driverClassName(与使用的数据库对应):com.mysql.jdbc.Driver
* url:(Java连接数据库的地址,非http协议的url)jdbc:mysql://localhost:3306/库名
* user:数据库用户名
* password:数据库密码
*/
String url="jdbc:mysql://localhost:3306/test";
String user="root";
String password="920346";
Connection _conn=DriverManager.getConnection(url, user, password);
return _conn;
} public static void sqlDemo(Connection conn) throws SQLException {
/*发送sql语句需要使用Statement对象,语句是正常的sql语句,注意不要加;结束
* 增删改语句的发送使用executeUpdate();返回受影响行数
*/
Statement stat=conn.createStatement();
String sql="INSERT INTO test1 VALUES(2,3)";
int l=stat.executeUpdate(sql);
sql="UPDATE test1 SET num1=2 WHERE num1=1";
l=stat.executeUpdate(sql);
sql="DELETE FROM test1 WHERE num1=2";
l=stat.executeUpdate(sql);
System.out.println(l);
} private static void queryDemo(Connection conn) throws SQLException {
/*查询语句和上面的增删改的不同在于返回值:
* 1、查询返回结果集;其他返回影响行数
* 2、查询使用的是executeQuery();其他使用executeUpdate()
*/
/*在创建语句发送器对象时,就已经决定了获取的结果集对象的特性,可以通过参数进行设置
* 默认只能向下移动,即执行next()
*/
Statement stat=conn.createStatement();
String sql="SELECT * FROM test1";
/*查询得到的结果集对象就是对数据表的抽象,是一张表,有行有列,对结果集的操作就是对行和列的操作
* 对行的操作就是定位、移动和获取行数 --》结果集光标
* 对列的操作就是获取列的信息(列数/类型),获取列的值 --》元数据
*/
ResultSet rs=stat.executeQuery(sql);
while(rs.next()){
int num1=rs.getInt("num1");
int num2=rs.getInt(2);
System.out.println("num1="+num1+",num2="+num2);
} //数据库连接也是一种资源,使用之后必须关闭,而且上面的三个对象都要关闭
rs.close();
stat.close();
conn.close();
} //sql代码书写规范:包括异常处理
public static void sqlDemo2(){
Connection conn=null;
Statement stat=null;
try{
conn=connection();
stat=conn.createStatement();
String sql="INSERT INTO test1 VALUES(2,3)";
int l=stat.executeUpdate(sql);
sql="UPDATE test1 SET num1=2 WHERE num1=1";
l=stat.executeUpdate(sql);
sql="DELETE FROM test1 WHERE num1=2";
l=stat.executeUpdate(sql);
System.out.println(l);
}catch(Exception e){
throw new RuntimeException();
}finally{
//防止空指针异常
try{
if(stat!=null)
stat.close();
if(conn!=null)
conn.close();
}catch(SQLException e){
throw new RuntimeException();
}
}
}
}

JDBC第一例

上面的查询使用的是Statement对象,但是有一个缺点就是可能存在Sql攻击德尔问题,可以使用PreapredStatement对象最为替代,

 import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import org.junit.Test; /**
* PreapredStatement的使用:
* 防SQL攻击
* @author cxf
*
*/
public class Demo2 {
/**
* 登录
* 使用username和password去查询数据
* 若查出结果集,说明正确!返回true
* 若查出不出结果,说明用户名或密码错误,返回false
* @param username
* @param password
* @return
* @throws Exception
*/
public boolean login(String username, String password) throws Exception {
/*
* 一、得到Connection
* 二、得到Statement
* 三、得到ResultSet
* 四、rs.next()返回的是什么,我们就返回什么
*/
// 准备四大参数
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test";
String mysqlUsername = "root";
String mysqlPassword = "920346";
// 加载驱动类
Class.forName(driverClassName);
// 得到Connection
Connection con = DriverManager.getConnection(url, mysqlUsername, mysqlPassword); // 得到Statement
Statement stmt = con.createStatement(); // 给出sql语句,调用stmt的executeQuery(),得到ResultSet
String sql = "select * from j_stu where username='" + username + "' and password='" + password + "'";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql); return rs.next();
} /**
* SQL攻击!
* @throws Exception
*/
@Test
public void fun1() throws Exception {
//select * from t_user where username='a' or 'a'='a' and password='a' or 'a'='a'
String username = "a' or 'a'='a";
String password = "a' or 'a'='a";
boolean bool = login(username, password);
System.out.println(bool);
} public boolean login2(String username, String password) throws Exception {
/*
* 一、得到Connection
* 二、得到Statement
* 三、得到ResultSet
* 四、rs.next()返回的是什么,我们就返回什么
*/
// 准备四大参数
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&cachePrepStmts=true";
String mysqlUsername = "root";
String mysqlPassword = "920346";
// 加载驱动类
Class.forName(driverClassName);
// 得到Connection
Connection con = DriverManager.getConnection(url, mysqlUsername, mysqlPassword); ///////////////////////////////////////
/////////////////////////////////////// /*
* 一、得到PreparedStatement
* 1. 给出sql模板:所有的参数使用?来替代
* 2. 调用Connection方法,得到PreparedStatement
*/
String sql = "select * from j_stu where username=? and password=?";
PreparedStatement pstmt = con.prepareStatement(sql); /*
* 二、为参数赋值
*/
pstmt.setString(1, username);//给第1个问号赋值,值为username
pstmt.setString(2, password);//给第2个问号赋值,值为password ResultSet rs = pstmt.executeQuery();//调用查询方法,向数据库发送查询语句 //重复使用赋值,需要关闭上次的结果流,并清空原设置
rs.close();
pstmt.clearParameters(); pstmt.setString(1, "liSi");
pstmt.setString(2, "123");
rs = pstmt.executeQuery();//调用查询方法,向数据库发送查询语句 return rs.next();
} @Test
public void fun2() throws Exception {
//select * from t_user where username='a' or 'a'='a' and password='a' or 'a'='a'
String username = "zhangSan";
String password = "123";
boolean bool = login2(username, password);
System.out.println(bool);
} /**
* 测试JdbcUtils.getConnection()
* @throws SQLException
* @throws ClassNotFoundException
* @throws IOException
*/
@Test
public void fun3() throws SQLException {
Connection con = JdbcUtils.getConnection();
System.out.println(con);
Connection con1 = JdbcUtils.getConnection();
System.out.println(con1);
}
}

使用PreapredStatement防止sql攻击

 import java.sql.Connection;
import java.sql.SQLException; import org.junit.Test; public class Demo5 {
/*jdbc中使用事务的演示:转账
* !!!事务是由连接对象管理,所以事务过程必须使用同一个连接对象
*/
public void transfers(String from,String to,Double money){
Connection conn=null;
try{
conn=JdbcUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//执行事务内容
AccountDao dao=new AccountDao();
dao.updateBalance(conn,from, -money);
dao.updateBalance(conn,to, money);
//提交事务
conn.commit();
conn.close();
}catch(Exception e){
try {
conn.rollback();
conn.close();
} catch (SQLException e1) {
throw new RuntimeException(e);
}
}
}
@Test
public void fun1(){
transfers("zs","lisi",100.00);
}
}

事务管理

从上面的基础代码可以看出有三个对象非常重要:Connection,Statement/PreparedStatement,ResultSet.还有就是注册驱动有多种方式,上面使用的是推荐用法。

以上就是JDBC的基本使用,但是也存在一些问题,

①数据库连接使用完之后需要释放,如果经常需要连接影响性能。

②数据库的使用代码有很多都是重复的,例如获取Connection对象,异常处理等。

③对查询结果集Result对象的处理

针对上面问题的解决方案:

①使用连接池代替原始的数据库连接,连接池就是一种装饰者模式,对连接对象的close()进行增强。

 import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException; import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test; import com.mchange.v2.c3p0.ComboPooledDataSource; public class Demo6 {
/*使用数据库连接池获取连接对象,连接池的配置还可以在配置文件中作为资源进行配置,称为JNDI,
* 1、DBCP连接池
* 2、C3P0连接池
*/
@Test
public void fun1() throws SQLException{
//数据库连接池是装饰者模式,是对Connection对象进行增强,
//获取连接池对象
BasicDataSource dataSource=new BasicDataSource();
//配置连接参数,因为连接池也要依靠四大参数连接数据库,并且也需要使用数据库驱动
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("920346");
//配置池参数:有默认值,
dataSource.setMaxActive(20); //最大活动连接数
dataSource.setMaxIdle(3); //最大空闲连接数 //获取连接对象
Connection conn=dataSource.getConnection();
System.out.println(conn.getClass().getName()); //注意这里的close()被增强,不是关闭连接,而是将连接对象归还连接池
conn.close();
} @Test
public void fun2() throws SQLException, PropertyVetoException{
//获取连接池对象,和上面操作相似,只是名字有所不同
ComboPooledDataSource dataSource=new ComboPooledDataSource(); //注意方法名和上面不同
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("root");
dataSource.setPassword("920346"); //配置池参数:有默认值,
dataSource.setAcquireIncrement(5);
dataSource.setInitialPoolSize(20); //获取连接对象
Connection conn=dataSource.getConnection();
System.out.println(conn.getClass().getName()); //注意这里的close()被增强,不是关闭连接,而是将连接对象归还连接池
conn.close();
}
@Test
public void fun3() throws SQLException{
/*c3p0连接池的配置参数可以直接写在配置文件中,
* 只要将配置文件保存在类路径下即可在创建类时自动寻找
* 注意:默认情况下使用的是默认配置,如果在代码中在进行配置就会将配置文件中的覆盖
*/
ComboPooledDataSource dataSource=new ComboPooledDataSource(); Connection conn=dataSource.getConnection();
System.out.println(conn.getClass().getName()); conn.close();
}
public void fun4() throws SQLException{
//在配置文件中可以有多个配置,如果不使用默认配置二使用其他配置,只要将节点名作为参数传入即可
ComboPooledDataSource dataSource=new ComboPooledDataSource("oracle-config"); Connection conn=dataSource.getConnection();
System.out.println(conn.getClass().getName()); conn.close();
}
}

数据库连接池的使用

②使用Apache Commons dbUtils包进行处理

③使用Apache Commons dbUtils包将结果集与java中的对象,集合等结构进行操作

对Apache Commons dbUtils包的说明参见

http://www.jb51.net/article/61886.htm

http://lavasoft.blog.51cto.com/62575/222771/

http://www.cnblogs.com/xdp-gacl/p/4007225.html

javaweb三、JDBC访问数据库的更多相关文章

  1. java web中Jdbc访问数据库步骤通俗解释(吃饭),与MVC的通俗解释(做饭)

    一.Jdbc访问数据库步骤通俗解释(吃饭) 1)加载驱动 Class.forName(“com.microsoft.jdbc.sqlserver.SQLServer”); 2) 与数据库建立连接 Co ...

  2. 如何通过JDBC访问数据库

    Java数据库连接(JDBC)用与在Java程序中实现数据库操作功能,它提供了执行SQL语句.访问各种数据库的方法,并为各种不同的数据库提供统一的操作接口,java.sql包中包含了JDBC操作数据库 ...

  3. Jdbc访问数据库篇

    一万年太久,只争朝夕 What JDBC 上部 JDBC(Java DataBase Connectivity)Java 数据库连接,主要提供编写 Java 数据库应用程序的 API 支持 java. ...

  4. 2017.10.3 JDBC访问数据库的建立过程

    1·JDBC访问数据库,其访问流程: (1)注册驱动 (2)建立连接(Connection) (3)创建数据库操作对象用于执行SQL语句 (4)执行语句 (5)处理执行结果 (6)释放资源 2·注册驱 ...

  5. JDBC访问数据库的具体步骤(MySql + Oracle + SQLServer)

    * 感谢DT课堂颜群老师的视频讲解(讲的十分仔细,文末有视频链接) import java.sql.Connection; import java.sql.DriverManager; import ...

  6. Spring实战6:利用Spring和JDBC访问数据库

    主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇文章的学习,我们掌握了如何写web应用的控制器层,不过由于只定义了SpitterRep ...

  7. 【jdbc访问数据库获取执行sql转换json】

    Talk is cheap.Show me your code. import java.sql.*; import java.util.HashMap; import java.util.Map; ...

  8. Java Spring JDBC访问数据库

    一.首先采用org.springframework.jdbc.datasource.DriverManagerDataSource类进行实现 1.applicationContext.xml配置如下: ...

  9. java之连接数据库之JDBC访问数据库的基本操作

    1.将数据库的JDBC驱动加载到classpath中,在基于JavaEE的web应用实际开发过程中通常要把目标数据库产品的JDBC驱动复制到WEB—INF/lib下. 2.加载JDBC驱动并将其注册到 ...

随机推荐

  1. .NET简谈——跨进高级编程门槛的必经之路

    我们继续C#基础知识的学习,这篇文章对前面基础知识学习的朋友有着举足轻重的作用:为了延续基础知识学习的热情,我编写了这篇特殊的文章. 本篇文章的中心是想借“.NET简谈反射(动态调用)”一文继续发挥下 ...

  2. PostgreSQL Replication之第四章 设置异步复制(6)

    4.6 有效的清理和恢复结束 最近几年, recovery.conf 已经变得越来越强大了.早在初期(在 PostgreSQL 9.0之前), 仅有 restore_command 和一些 recov ...

  3. js实现图片上传后即时预览

    //关于FileReader对象 http://blog.csdn.net/zk437092645/article/details/8745647 <!DOCTYPE html> < ...

  4. HDU 4324 Triangle LOVE【拓扑排序】

    题意:给出n个人,如果a喜欢b,那么b一定不喜欢a,如果b不喜欢a,那么a一定喜欢b 就是这n个点里面的任意两点都存在一条单向的边, 所以如果这n个点不能构成拓扑序列的话,就一定成环了,成环的话就一定 ...

  5. ios发布以后关键信息确认与nslog

    发布以后信息查看的路径: xcode->window->devices and …->查看如图的log. 通常在发布以后,处于安全和性能的考虑,会禁止打印log:但是在关键的信息需要 ...

  6. Tiles入门及项目实战

    1.Apache Tiles™ Apache Tiles是一个模板布局框架.最初是为了简化Web应用界面开发,如今已不限于JavaEE Web环境. Tiles允许开发人员定义页面片段,它们在运行时会 ...

  7. 同门不同类—创新Aurvana Live2/Air简评(附随身视听设备心路历程)

    (注,本文把live2/air并成一起写的,同时本人是木耳,请轻拍) 本命年各种坏东西,很是无语,终于坏到耳塞耳机了来了,之前用的拜亚DT235无缘无故就一边不响了,无奈只能扔了. 纠结了好几个月,终 ...

  8. mesg---设置当前终端的写权限

    mesg命令用于设置当前终端的写权限,即是否让其他用户向本终端发信息.将mesg设置y时,其他用户可利用write命令将信息直接显示在您的屏幕上. 语法 mesg(参数) 参数 y/n:y表示运行向当 ...

  9. Chrome无界面浏览模式与自定义插件加载问题

    环境:Python 3.5.x + Selenium 3.4.3 + Chromedriver 2.30 + Chrome 60 beta或Chromium Canary 61 + WIN10 Chr ...

  10. Redis中的持久化操作

       本篇博客主要来解说一下怎样Redis中的持久化操作,当然了不是一篇理论性的博客,主要还是分享一下在redis中怎样来配置持久化操作.  1.介绍  redis为了内部数据的安全考虑,会把本身的数 ...