一,jdbc简介
SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC。这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库。
二,api类
2.1、DriverManager类讲解
Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
- DriverManager.registerDriver(new Driver())
- DriverManager.getConnection(url, user, password),
注意:在实际开发中并不推荐采用registerDriver方法注册驱动。原因有二:
1、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
2、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
推荐方式:Class.forName("com.mysql.jdbc.Driver");
采用此种方式不会导致驱动对象在内存中重复出现,并且采用此种方式,程序仅仅只需要一个字符串,不需要依赖具体的驱动,使程序的灵活性更高。
2.2、数据库URL讲解
URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:
常用数据库URL地址的写法:
- Oracle写法:jdbc:oracle:thin:@localhost:1521:sid
- SqlServer写法:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid
- MySql写法:jdbc:mysql://localhost:3306/sid
如果连接的是本地的Mysql数据库,并且连接使用的端口是3306,那么的url地址可以简写为: jdbc:mysql:///数据库
2.3、Connection类讲解
Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法:
- createStatement():创建向数据库发送sql的statement对象。
- prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
- prepareCall(sql):创建执行存储过程的callableStatement对象。
- setAutoCommit(boolean autoCommit):设置事务是否自动提交。
- commit() :在链接上提交事务。
- rollback() :在此链接上回滚事务。
2.4、Statement类讲解
Jdbc程序中的Statement对象用于向数据库发送SQL语句, Statement对象常用方法:
- executeQuery(String sql) :用于向数据发送查询语句。
- executeUpdate(String sql):用于向数据库发送insert、update或delete语句
- execute(String sql):用于向数据库发送任意sql语句
- addBatch(String sql) :把多条sql语句放到一个批处理中。
- executeBatch():向数据库发送一批sql语句执行。
2.5、ResultSet类讲解
Jdbc程序中的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的最后面。
2.6、释放资源
Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象,特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
三,示例
3.1、编写JdbcUtils工具类
package com.xc.jdbc.util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtils { private static String driver = null; private static String url = null; private static String username = null; private static String password = null; static { try { // 读取db.properties文件中的数据库连接信息 InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties prop = new Properties(); prop.load(in); // 获取数据库连接驱动 driver = prop.getProperty("driver"); // 获取数据库连接URL地址 url = prop.getProperty("url"); // 获取数据库连接用户名 username = prop.getProperty("username"); // 获取数据库连接密码 password = prop.getProperty("password"); // 加载数据库驱动 Class.forName(driver); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /** * @Method: getConnection * @Description: 获取数据库连接对象 * @return Connection数据库连接对象 * @throws SQLException */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } /** * @Method: release * @Description: 释放资源, 要释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象 * @param conn * @param st * @param rs */ public static void release(Connection conn, Statement st, ResultSet rs) { if (rs != null) { try { // 关闭存储查询结果的ResultSet对象 rs.close(); } catch (Exception e) { e.printStackTrace(); } rs = null; } if (st != null) { try { // 关闭负责执行SQL命令的Statement对象 st.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn != null) { try { // 关闭Connection数据库连接对象 conn.close(); } catch (Exception e) { e.printStackTrace(); } } } }
3.2、使用PreparedStatement对象完成对数据库的CRUD操作
package com.xc.jdbc.curd; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Date; import org.apache.log4j.Logger; import org.junit.Test; import com.xc.jdbc.util.JdbcUtils; /** * @ClassName: JdbcCRUDByPreparedStatement * @Description: 通过PreparedStatement对象完成对数据库的CRUD操作 * * PreperedStatement是Statement的子类,它的实例对象可以通过调用Connection.preparedStatement()方法获得,相对于Statement对象而言:PreperedStatement可以避免SQL注入的问题。 * Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。 * */ public class JdbcCRUDByPreparedStatement { private static Logger log = Logger.getLogger(JdbcCRUDByPreparedStatement.class); @Test public void insert() { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { // 获取一个数据库连接 conn = JdbcUtils.getConnection(); // 要执行的SQL命令,SQL中的参数使用?作为占位符 String sql = "insert into users(name,password,email,birthday) values(?,?,?,?)"; // 通过conn对象获取负责执行SQL命令的prepareStatement对象 st = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);// 获取自动增加的id号 // 为SQL语句中的参数赋值,注意,索引是从1开始的 /** * SQL语句中各个字段的类型如下: +----------+-------------+ | Field | Type | +----------+-------------+ | id | int(11) | * | name | varchar(40) | | password | varchar(40) | | email | varchar(60) | | birthday | date | * +----------+-------------+ */ st.setString(1, "name1");// name是varchar(字符串类型) st.setString(2, "123");// password是varchar(字符串类型) st.setString(3, "bhsh@sina.com");// email是varchar(字符串类型) st.setDate(4, new java.sql.Date(new Date().getTime()));// birthday是date类型 // 执行插入操作,executeUpdate方法返回成功的条数 st.executeUpdate(); // 获取数据库自动生成的主键 rs = st.getGeneratedKeys(); while (rs.next()) { log.info(rs.getInt(1)); } log.info("插入成功!!"); } catch (Exception e) { log.error(e, e); } finally { // SQL执行完成之后释放相关资源 JdbcUtils.release(conn, st, rs); } } @Test public void delete() { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); String sql = "delete from users where id=?"; st = conn.prepareStatement(sql); st.setInt(1, 1); int num = st.executeUpdate(); if (num > 0) { log.info("删除成功!!"); } } catch (Exception e) { log.error(e, e); } finally { JdbcUtils.release(conn, st, rs); } } @Test public void update() { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); String sql = "update users set name=?,email=? where id=?"; st = conn.prepareStatement(sql); st.setString(1, "gacl"); st.setString(2, "gacl@sina.com"); st.setInt(3, 2); int num = st.executeUpdate(); if (num > 0) { log.info("更新成功!!"); } } catch (Exception e) { log.error(e, e); } finally { JdbcUtils.release(conn, st, rs); } } @Test public void find() { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); String sql = "select * from users where id=?"; st = conn.prepareStatement(sql); st.setInt(1, 1); rs = st.executeQuery(); if (rs.next()) { log.info(rs.getString("name")); } } catch (Exception e) { log.error(e, e); } finally { JdbcUtils.release(conn, st, rs); } } }
3.3、编写配置文件db.properties
#---mysql--- #5版本 #driver=com.mysql.jdbc.Driver #6.0版本以上 driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/testsvnb?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true username=root password=123456 #---oracle--- #driver=oracle.jdbc.OracleDriver #url=jdbc:oracle:thin:@127.0.0.1:1521:orcl #username=ecology #password=tlit2017 #---sql server--- #driver=net.sourceforge.jtds.jdbc.Driver #url=jdbc:jtds:sqlserver://127.0.0.1:1433;databaseName=TLManager #username=sa #password=123456 #---hana--- #driver=com.sap.db.jdbc.Driver #hana测试 #url=jdbc:sap://127.0.0.1:31015?reconnect=true #username=sapabap1 #password=Tldb_2016
参考文章:
https://www.cnblogs.com/xdp-gacl/p/3973886.html