JDBC入门
JDBC简介
SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。
由一系列的抽象类和接口组成。一般位于JDK的java.sql和javax.sql包中
开发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实现(即数据库驱动,不同的数据库对于JDBC的实现是不同的)。
一、第一个JDBC程序
编写一个程序,这个程序从user表中读取数据,并打印在命令行窗口中。
一、搭建实验环境 :
1、在mysql中创建一个库,并创建user表和插入表的数据。
2、新建一个Java工程,并导入数据驱动。
二、编写程序,在程序中加载数据库驱动
DriverManager. registerDriver(Driver driver)
三、建立连接(Connection)
Connection conn = DriverManager.getConnection(url,user,pass);
四、创建用于向数据库发送SQL的Statement对象,并发送sql
Statement st = conn.createStatement();
ResultSet rs = st.excuteQuery(sql);
五、从代表结果集的ResultSet中取出数据,打印到命令行窗口
六、断开与数据库的连接,并释放相关资源
准备工作
创建数据库mydb: create database mydb character set utf8 collate utf8_general_ci;
使用mydb数据库: use mydb ;
创建表
create table users(
id int primary key auto_increment,
name varchar(40),
password varchar(40),
email varchar(60),
birthday date
)character set utf8 collate utf8_general_ci;
插入数据
insert into users(name,password,email,birthday) values('zs','123456','zs@sina.com','1980-12-04');
insert into users(name,password,email,birthday) values('lisi','123456','lisi@sina.com','1981-12-04');
insert into users(name,password,email,birthday) values('wangwu','123456','wangwu@sina.com','1979-12-04');
第一个JDBC程序
1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.SQLException; 4 import java.sql.Statement; 5 import java.sql.ResultSet; 6 7 /* 8 * 查询users表中的所有记录,打印字控制台上 9 * @author xushuai 10 * */ 11 public class JdbcDemo1 { 12 public static void main(String[] args) throws SQLException{ 13 //注册驱动程序,会注册两次,而且依赖mysql的jar包,不便于后期的扩展 14 DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 15 16 //创建与数据库的连接 17 Connection coon = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root"); 18 19 //创建代表SQL语句的对象 20 Statement statement = coon.createStatement(); 21 22 //执行查询语句,得到查询结果对象 23 ResultSet resultSet = statement.executeQuery("select id,name,password,email,birthday from users"); 24 //打印各种信息 25 while(resultSet.next()){ 26 System.out.println(resultSet.getObject("id")); 27 System.out.println(resultSet.getObject("name")); 28 System.out.println(resultSet.getObject("password")); 29 System.out.println(resultSet.getObject("email")); 30 System.out.println(resultSet.getObject("birthday")); 31 } 32 resultSet.close(); 33 statement.close(); 34 coon.close(); 35 } 36 }
二、JDBC常用接口的详细说明
1、DriverManager
作用:注册驱动;得到数据库的连接
注册驱动:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
缺点:
1)查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
2)程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
推荐方式:Class.forName("com.mysql.jdbc.Driver");
采用此种方式不会导致驱动对象在内存中重复出现,并且采用此种方式,程序仅仅只需要一个字符串,不需要依赖具体的驱动,使程序的灵活性更高。
得到数据库的连接:(所有与数据库交互的东西都是基于连接的)
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
Tip:连接的url参考具体版本的具体数据库的文档
Connection conn = DriverManager.getConnection(String url, Properties info) ;
2、Connection
用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的
常用方法:
createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
prepareCall(sql):创建执行存储过程的callableStatement对象。
setAutoCommit(boolean autoCommit):设置事务是否自动提交。
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。
3、Statement
作用:向数据库发送发送SQL语句的对象
常用方法:
executeQuery(String sql) :用于向数据发送查询语句。
executeUpdate(String sql):用于向数据库发送insert、update或delete语句,返回值为影响到的行数
execute(String sql): 用于向数据库发送任意sql语句,返回值如果有结果集返回true,没有结果集返回false。
addBatch(String sql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。
4、ResultSet
代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
获取任意类型的数据
getObject(int index)
getObject(string columnName)
获取指定类型的数据,(封装数据时方便)例如:
getString(int index)
getString(String columnName)
ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行
Previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast() :移动到resultSet的最后面。
5、释放占用的资源
Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。
特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
三、JDBC进行CRUD
Dbinfo.properties(位于cn.itmonkey.util包下)
1 className = com.mysql.jdbc.Driver 2 url = jdbc:mysql://localhost:3306/mydb 3 user = root 4 password =root
工具类:
1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 import java.util.ResourceBundle; 7 8 public class JdbcUtil { 9 private static String className; 10 private static String user; 11 private static String url; 12 private static String password; 13 //加载数据库配置文件,注册驱动 14 static{ 15 try { 16 ResourceBundle bundle = ResourceBundle.getBundle("cn.itmonkey.util.dbinfo"); 17 user = bundle.getString("user"); 18 url = bundle.getString("url"); 19 className = bundle.getString("className"); 20 password = bundle.getString("password"); 21 Class.forName(className); 22 } catch (ClassNotFoundException e) { 23 throw new RuntimeException("驱动加载失败"); 24 } 25 } 26 //获取连接对象 27 public static Connection getConnection(){ 28 29 try { 30 Connection conn = DriverManager.getConnection(url,user,password);//获取连接对象 31 return conn; 32 } catch (SQLException e) { 33 throw new RuntimeException(); 34 } 35 }
//释放资源 36 public static void release(ResultSet resultSet, Statement statement, 37 Connection conn) { 38 if(resultSet!=null){ 39 try { 40 resultSet.close(); 41 } catch (SQLException e) { 42 e.printStackTrace(); 43 } 44 } 45 if(statement!=null){ 46 try { 47 statement.close(); 48 } catch (SQLException e) { 49 e.printStackTrace(); 50 } 51 } 52 if(conn!=null){ 53 try { 54 conn.close(); 55 } catch (SQLException e) { 56 e.printStackTrace(); 57 } 58 } 59 } 60 61 }
增删改查
1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 7 import junit.framework.Assert; 8 import org.junit.Test; 9 import cn.itxushuai.domain.User; 10 import cn.itxushuai.util.JdbcUtil; 11 12 public class JdbcCRUD { 13 14 @Test 15 public void testQuery(){ 16 Statement statement = null; 17 Connection conn = null; 18 ResultSet resultSet = null; 19 try { 20 conn = JdbcUtil.getConnection();//获取连接对象 21 statement = conn.createStatement();//创建sql语句的发送对象 22 String sql = "select * from users where name='xs'";//要执行的sql语句 23 User user = null; 24 resultSet = statement.executeQuery(sql);//向数据库发送查找的sql语句,同时返回一个结果集对象 25 26 if(resultSet.next()){ //遍历结果集,获取信息并未user对象设置 27 user = new User(); 28 user.setId(resultSet.getInt("id")); 29 user.setName(resultSet.getString("name")); 30 user.setEmail(resultSet.getString("email")); 31 user.setPassword(resultSet.getString("password")); 32 user.setBirthday(resultSet.getDate("birthday")); 33 } 34 System.out.println(user); 35 } catch (SQLException e) { 36 e.printStackTrace(); 37 }finally{ 38 JdbcUtil.release(resultSet, statement, conn); //一定记得关闭资源 39 } 40 } 41 42 @Test 43 public void AddTest(){ 44 Statement statement = null; 45 Connection conn = null; 46 ResultSet resultSet = null; 47 48 conn = JdbcUtil.getConnection(); 49 try { 50 statement = conn.createStatement(); //创建一个sql语句发送对象 51 String sql = "insert into users(name,password,email,birthday)values('zxx','333333','zxx@123.com','1980-2-1') "; //插入一个新的user 52 int result = statement.executeUpdate(sql); //发送插入的sql语句,修改都是调用executeUpdate方法!!! 53 } catch (SQLException e) { 54 e.printStackTrace(); 55 }finally{ 56 JdbcUtil.release(resultSet, statement, conn); //释放资源 57 } 58 59 } 60 @Test 61 public void testUpdate(){ 62 Connection conn = null; 63 Statement statement = null; 64 ResultSet resultSet = null; 65 66 try { 67 conn = JdbcUtil.getConnection(); 68 statement = conn.createStatement(); 69 String sql = "update users set password='007' where name='lmy' ";//将name为‘lmy’的对象的password设为‘007’ 70 statement.executeUpdate(sql); //向数据库发送更新的sql语句 71 72 } catch (SQLException e) { 73 e.printStackTrace(); 74 }finally{ 75 JdbcUtil.release(resultSet, statement, conn); //关闭资源,切记!!! 76 } 77 } 78 @Test(timeout=300) //执行时间未300毫秒之内,否则测试不通过 79 public void testDelete(){ 80 ResultSet resultSet = null; 81 Statement statement = null; 82 Connection conn = null; 83 84 try { 85 conn = JdbcUtil.getConnection(); 86 statement = conn.createStatement(); 87 String sql = "delete from users where id=4"; //从表中删除id为4的user 88 statement.executeUpdate(sql); 89 90 } catch (SQLException e) { 91 e.printStackTrace(); 92 }finally{ 93 JdbcUtil.release(resultSet, statement, conn); //释放资源 94 } 95 96 } 97 98 }
四、java.sql.PreparedStatement
PreperedStatement是Statement的子类,它的实例对象可以通过调用Connection.preparedStatement()方法获得,相对于Statement对象而言:
PreperedStatement可以避免SQL注入的问题。
Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。
并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。
//这里只是对PreparedStatement 的使用做简单说明,所以异常以及资源都没有处理
1 public void addCustomer(Customer customer) { 2 String sql = "insert into customer (id,name,gender) values (?,?,?)"; //使用占位符的sql语句 3 Connection conn = JdbcUtil.getConnection(); 4 PreparedStatement statement = conn.prepareStatement(sql); //在创建发送对象的同时传入sql语句 5 statement.setString(1,customer.getId()); //对sql语句中的占位符进行指定,从1开始 6 statement.setString(2,customer.getName()); 7 statement.setString(3,customer.getGender()); 8 statement.executeUpdate(); //执行更新操作 9 }