(本文主要讲解一些JDBC基础和一个JDBC连接数据库小实例)
JDBC的全称是Java DataBase Connectivity,即Java数据库连接。
JDBC的概念:JDBC是标准的Java访问数据库的API。JDBC定义了数据库的连接、SQL语句的执行以及查询结果集的遍历等。JDBC把这些操作定义为接口,位于包java.sql下面,如java.sql.Connection、java.sql.Statement、java.sql.ResultSet等,各个数据库提供商在自己的JDBC驱动中实现了这些接口。
JDBC支持数据库访问的两层和三层模型。两层模型是Java应用程序或Applet直接与数据库进行交互操作的模型,它需要JDBC驱动将SQL语句发送到数据库,然后将执行结果再返回给客户端应用程序;三层模型是在应用与数据库之间,有一个中间应用服务器。这个应该服务器是将程序解耦合,使得逻辑与数据分离。其具体过程,是使用JDBC驱动把命令发送给中间应用服务器,在此服务器中执行一定的逻辑操作,再将这些命令发送给数据库。数据库接收命令后,执行相关操作,将产生的结果返回给中间服务器,再通过中间服务器将数据发给应用。
JDBC API由两个部分组成,一个是核心的API,其类包路径为java.sql,二是扩展的API,其类包路径为javax.sql。常用的标准类如下。
java.sql.DriverManager:完成驱动程序的装载和建立新的数据库连接。
java.sql.Connection:表示对某一指定数据库的连接。
java.sql.Statement:用于管理在一指定数据库连接上的SQL语句的执行。
java.sql.ResultSet:一个SQL语句的执行结果。
java.sql.PreparedStatement:继承了Statement接口,用于对预编译的SQL语句的执行。
java.sql.CallableStatement:继承了Statement接口,用于对一个数据库存储过程的执行。
java.sql.SQLException:处理数据库访问时的出错信息。
java.sql.SQLWarning:处理数据库访问时的警告信息。
java.sql.Time:用于表示时、分、秒。
java.sql.Timestamp:扩展标准java.util.data类,用于表示SQL的时间戳,增加了一个以纳秒为单位的时间域。
java.sql.Types:定义区分SQL类型的常量。
java.sql.DatabaseMetaData:定义了JDBC元数据接口。
Connection连接对象
通过Connection连接对象可以获取Statement语句对象或者PreparedStatement语句对象,通过语句对象可以对数据库进行查询和更新操作。其中,查询是读取数据动作,更新是包括增加、删除、修改数据的操作。Connection的类路径为java.sql.Connection。
close():完成关闭连接
commit():完成提交
rollback():完成回滚
createStatement():该方法返回Statement对象
prepareStatement(String sql):参数sql是执行SQL的语句,该方法返回PrepareStatement对象
setAutoCommit(Boolean autoCommit):参数autoCommit表示是否自动提交,该方法用于设置自动提交。
Statement对象
执行数据库的过程是,通过Connection连接对象获取Statement对象,在通过Statement对象执行相关读取或更新操作。Statement对象有两种具体实现,分别为PreparedStatement和CallableStatement。其中,PreparedStatement主要是用来预编译SQL语句,这个对象主要是为了提高程序效率;CallableStatement继承了PreparedStatement接口,用于存储过程。
Statement对象是通过Connection对象的createStatement()方法来创建的。对于不是频繁查询记录的应用而言,使用Statement对象是一个合适的做法。因为他不必像PreparedStatement对象一样,需要预编译。
Statement对象的创建过程如下:
String URL = "jdbc:mysql://localhost:3306/bank?username=root&password=root"; Connection conn = DriverManager.getConnection(URL); Statement st = conn.createStatement();
Statement的类路劲为java.sql.Statement,它的常用方法如下:
close():完成关闭Statement。
executeQuery(String sql):参数sql表示查询SQL语句,该方法返回ResultSet对象。
executeUpdate(String sql):参数sql表示操作SQL语句,该方法返回更新的行数。
execute(String sql):参数sql表示操作SQL语句,该方法返回一个boolean值,表明是否返回了ResultSet对象。
getResultSet():该方法返回ResultSet对象。
通常使用Statement对象的3个基本方法来执行SQL命令。
executeQuery()方法主要是用来执行查询命令,返回一个ResultSet对象。
String sql = "select * from user";
ResultSet rs = statememt.executeQuery(sql);
executeUpdate()方法主要是用来执行增加,删除及修改记录操作,返回一个int整型值,此整型值是被更新的行数。
String sql = "insert into user(name ,age ,sex)values('jack',25,'男')"
int num = statement.executeUpdate(sql);
execute()方法主要是用来执行一般的SQL命令,包括增删改查以及数据定义,返回一个布尔值,它显示了是否返回一个查询结果集ResultSet对象。
String sql = "select * from user"; boolean value = statement.execute(sql);
PreparedStatement对象
PreparedStatement继承了Statement接口。所谓预编译,就是在创建语句对象时,将SQL执行语句一起进行编译,然后写入缓冲,只保留参数动态输入。这样在执行相同的数据库操作时,如查询某条记录的信息,就不必总是查询SQL命令进行编译,而只是修改相应的参数即可,如根据某个标识查询记录,就能获得查询结果,达到了提高效率的目的。
PreparedStatement对象是通过Connection对象的preparedStatement()方法来创建的。preparedStatement()方法有一个参数,这个参数需要输入所要执行的SQL语句。该SQL语句可以保留一个或多个参数作为动态输入。如果需要有参数动态输入,则此SQL语句的参数位置需要用“?“代替。然后需要根据参数的序号位置,分别调用不同类型的set方法将参数值动态输入。
String URL = "jdbc:mysql://localhost:3306/bank?username=root&password=root"; Connection conn = DriverManager.getConnection(URL); String sql = "select * from user where name = ? and age < ? and sex = ?"; PreparedStatement pstmt = conn.preparedStatement(sql); pstmt.setString(1,"jack"); pstmt.setInt(2,"20"); pstmt.setString(3,"男"); ResultSet rs = pstmt.executeQuery();
PreparedStatement的常用方法如下:
close():该方法完成关闭Statement
executeQuery():该方法输出ResultSet对象
executeUpdate():该方法输出数据更新的行数
execute():该方法输出boolean值,表明是否返回了ResultSet对象
ResultSet结果集对象
java.sql.ResultSet接口封装了这个结果集对象,其中的每条记录结果代表了一个数据库行。通常可以通过一个Statement对象、PreparedStatement对象及一些其他子接口对象的executeQuery()方法,获得结果集对象。通过Statement对象的execute()方法,执行一个SQL查询命令,也可以获得一个结果集对象,但不是直接获取。它首先通过execute()方法返回的布尔值,判断是否返回一个结果集对象,然后通过getResultSet()方法获取一个ResultSet对象。有些场合,需要同时返回多个结果集对象,这时就需要通过Statement对象的getMoreResults()方法来实现对结果集集合的遍历。
一个JDBC操作数据库的实例
1.实现JDBC连接MySQL数据库
package com.cn.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBC_Connection { static String drivername = "com.mysql.jdbc.Driver"; static String url = "jdbc:mysql://localhost:3306/bank"; static String username = "root"; static String password = "123456"; static { try{ Class.forName(drivername); //创建驱动 System.out.println("创建驱动成功!"); }catch(ClassNotFoundException e){ e.printStackTrace(); } } public static Connection getConnection(){ Connection conn = null; try{ //使用DriverManager来获取连接 conn = (Connection)DriverManager.getConnection(url,username,password); System.out.println("连接数据库成功!"); }catch(SQLException e){ e.printStackTrace(); } return conn; } public static void main(String[] args){ JDBC_Connection.getConnection(); } public static void free(ResultSet rs,Connection conn,Statement stmt){ try{ if(rs != null) rs.close(); //关闭结果集 }catch(SQLException e){ System.out.println("关闭ResultSet失败!"); e.printStackTrace(); }finally{ try{ if(conn != null) conn.close(); //关闭连接 }catch(SQLException e){ System.out.println("关闭Connection失败!"); e.printStackTrace(); }finally{ try{ if(stmt != null) stmt.close(); //关闭Statement对象 }catch(SQLException e){ System.out.println("关闭Statement失败!"); e.printStackTrace(); } } } } }
在控制台打印
使用JDBC向数据库表插入数据
实体类:UserVo.java
/*每一张数据库表要对应一个实体类, * 实体类中的属性对应着表的字段名。同时数据类型转化要正确**/ package com.cn.jdbc; public class UserVo { private int id; private String name; private int age; private String tel; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
AddUser.java
package com.cn.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class AddUser { public void add(UserVo userVo){ Connection conn = null; PreparedStatement pstm = null; ResultSet rs = null; try{ //调用JDBC_Connection类的getConnection方法连接数据库 conn = JDBC_Connection.getConnection(); //添加数据库的SQL语句 String sql = "insert into users(id,name,age,tel,address)values(?,?,?,?,?)"; pstm = conn.prepareStatement(sql); //把添加的id值存入pstm对象中,int类型的值用setInt方法 pstm.setInt(1, userVo.getId()); pstm.setString(2, userVo.getName()); pstm.setInt(3, userVo.getAge()); pstm.setString(4, userVo.getTel()); pstm.setString(5, userVo.getAddress()); pstm.executeUpdate(); //提交pstm对象 System.out.println("添加成功!添加的内容如下:"); System.out.println("id:"+userVo.getId()+"\t name:"+userVo.getName() +"\t age:"+userVo.getAge()+"\t tel:"+userVo.getTel()+ "\t address:"+userVo.getAddress()); }catch(Exception e){ e.printStackTrace(); }finally{ JDBC_Connection.free(rs, conn, pstm); } } public static void main(String[] args){ AddUser addUser = new AddUser(); UserVo userVo = new UserVo(); int id = 1; String name = "赵六"; int age = 22; String tel = "123456"; String address = "北京"; //下面是设置要添加的变量值,放入UserVo对象中 userVo.setId(id); userVo.setName(name); userVo.setAge(age); userVo.setTel(tel); userVo.setAddress(address); //调用add()方法,把UserVo对象作为参数传递 addUser.add(userVo); } }
在控制台打印
查询数据库表数据
package com.cn.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; public class Query { public List<UserVo> showUser(){ Connection conn = null; Statement stmt = null; ResultSet rs = null; List<UserVo> list = new ArrayList<UserVo>(); //声明一个List集合,用于存放查询出的数据 try{ conn = JDBC_Connection.getConnection(); //连接数据库 stmt = conn.createStatement(); //建立Statement对象 rs = stmt.executeQuery("select * from users"); while(rs.next()){ //结果集存在,则进行循环遍历 UserVo userVo = new UserVo(); userVo.setId(rs.getInt("id")); userVo.setName(rs.getString("name")); userVo.setAge(rs.getInt("age")); userVo.setTel(rs.getString("tel")); userVo.setAddress(rs.getString("address")); list.add(userVo); //把每次获得的对象数据放入list集合中 } }catch(SQLException e){ e.printStackTrace(); }finally{ JDBC_Connection.free(rs, conn, stmt); //关闭连接 } return list; } public static void main(String[] args){ Query query = new Query(); List<UserVo> list = query.showUser(); //调用查询方法 //如果list集合不为空,则循环遍历打印出所有的信息 if(list != null){ System.out.print("id "); System.out.print("name "); System.out.print("age "); System.out.print("tel "); System.out.print("address "); System.out.println(); for(int i=0;i<list.size();i++){ System.out.print(list.get(i).getId()+"\t"); System.out.print(list.get(i).getName()+"\t"); System.out.print(list.get(i).getAge()+"\t"); System.out.print(list.get(i).getTel()+"\t"); System.out.print(list.get(i).getAddress()+"\t"); System.out.println(); } } } }
在控制台打印:
查询指定条件的数据
package com.cn.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class QueryById { public UserVo queryUserById(int id){ UserVo userVo = null; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try{ conn = JDBC_Connection.getConnection(); pstmt = conn.prepareStatement("select *from users where id = ?"); pstmt.setInt(1, id); //设置条件id rs = pstmt.executeQuery(); while(rs.next()){ //结果集存在,则遍历结果,放入UserVo对象中 userVo = new UserVo(); userVo.setId(rs.getInt("id")); userVo.setName(rs.getString("name")); userVo.setAge(rs.getInt("age")); userVo.setTel(rs.getString("tel")); userVo.setAddress(rs.getString("address")); } }catch(SQLException e){ e.printStackTrace(); }finally{ JDBC_Connection.free(rs, conn, pstmt); //关闭连接 } return userVo; } public static void main(String[] args){ QueryById byId = new QueryById(); int id = 1; UserVo vo = byId.queryUserById(id); if(vo != null){ System.out.print("id\t"); System.out.print("name\t"); System.out.print("age\t"); System.out.print("tel\t"); System.out.print("address\t"); System.out.println(); System.out.print(vo.getId()+"\t"); System.out.print(vo.getName()+"\t"); System.out.print(vo.getAge()+"\t"); System.out.print(vo.getTel()+"\t"); System.out.print(vo.getAddress()+"\t"); System.out.println(); }else{ System.out.println("id为"+id+"的用户不存在!"); } } }
在控制台打印
删除表数据
package com.cn.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class DeleteUser { public void deleteUser(int id){ Connection conn = null; PreparedStatement pstmt = null; try{ conn = JDBC_Connection.getConnection(); String sql = "DELETE FROM users where id =?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, id); //给SQL语句中的id赋值 pstmt.executeUpdate(); System.out.println("删除成功!删除了id值为"+id+"数据"); }catch(SQLException e){ e.printStackTrace(); }finally{ JDBC_Connection.free(null, conn, pstmt); //关闭连接 } } public static void main(String[] args){ DeleteUser deleteUser = new DeleteUser(); int id = 1; UserVo userVo = new UserVo(); QueryById queryById = new QueryById(); userVo = queryById.queryUserById(id); //调用根据id查询的方法查询出id的数据 if(userVo != null){ //如果查询出的数据不为空,则执行删除方法 deleteUser.deleteUser(id); }else{ System.out.println("删除失败!原因:id为"+id+"的数据不存在!"); } } }
在控制台打印
修改表数据
package com.cn.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateUser { public void update(UserVo userVo){ Connection conn = null; PreparedStatement pstmt = null; String sql = "UPDATE users set id=?,name=?,age=?,tel=?,address=? where id =?"; try{ conn = JDBC_Connection.getConnection(); //连接数据库 pstmt = conn.prepareStatement(sql); pstmt.setInt(1, userVo.getId()); pstmt.setString(2, userVo.getName()); pstmt.setInt(3, userVo.getAge()); pstmt.setString(4, userVo.getTel()); pstmt.setString(5, userVo.getAddress()); pstmt.setInt(6, userVo.getId()); pstmt.executeUpdate(); }catch(SQLException e){ e.printStackTrace(); }finally{ JDBC_Connection.free(null, conn, pstmt); //关闭连接 } } public static void main(String[] args){ UpdateUser updateUser = new UpdateUser(); int id = 2; String name ="张三"; int age = 19; String tel = "123456"; String address = "上海"; QueryById queryById = new QueryById(); UserVo vo = new UserVo(); vo = queryById.queryUserById(id); //调用QueryById类中根据id查询的方法 if(vo != null){ //判断查询的结果不为空,则执行修改操作 UserVo userVo = new UserVo(); //把修改的变量值放入UserVo对象中 userVo.setId(id); userVo.setName(name); userVo.setAge(age); userVo.setTel(tel); userVo.setAddress(address); updateUser.update(userVo); System.out.println("修改成功!修改了id值为"+id+"数据"); }else{ System.out.println("修改失败!原因:id为"+id+"的数据不存在!"); } } }
在控制台打印