JAVA的数据库编程
JDBC
-
JDBC基础
- JDBC( Java Database Connectivity 是一个 独立于特定数据库管理系统 、通用的 SQL 数据库存取和操作的公共接口 (一组 API ),定义了用来访问数据库的标准 Java 类库,( java.sql,javax.sql )使用这个类库可以以一种标准的方法、方便地访问数据库资源
- JDBC 为访问不同的数据库提供了一种 统一的途径 ,为开发者屏蔽了一些细节问题。
- JDBC 的目标是使 Java 程序员使用 JDBC 可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
-
JDBC连接方式
- 加载驱动的类名
Class.forName("com.mysql.jdbc.Driver");
-
建立连接
- 调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
- JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
- JDBC URL 的标准由三部分组成,各部分间用冒号分隔。
- jdbc 子协议 子名称
- 协议:JDBC URL 中的协议总是 jdbc
- 子协议:子协议用于标识一个数据库驱动程序
- 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含 主机名 (对应服务端的 ip 地址 ),端口号,数据库名
- jdbc 子协议 子名称
-
方法:
java.sql.DriverManager static Connection getConnection(String url,String user,String password) //建立一个到指定数据库的连接,并返回一个Connection对象
JDBC Statement执行sql语句
-
每个Connection对象都可以创建多个Statement对象。同一个Statement对象可以用多个不相关的命令和查询。但是,一个Statement对象最多只能有一个打开的结果集。
-
java.sql.Connection Statement createStatement() //创建一个Statement对象,用以执行不带参数的SQL查询和更新 void close() //立即关闭当前的连接,并释放由它所创建的JDBC资源 java.sql.Statement ResultSet executeQuery(String sqlQuery) //执行给定字符串中的SQL语句,并返回一个用于查看查询结果的ResultSet对象 int executeUpdate(String sqlStatment) long executeLargeUpdate(String sqlStatement) //执行字符串中指定的INSERT、update、或Delete等SQL语句。还可以执行DDL语句。返回受影响的行数,如果是没有更新计数的语句,则返回0。 boolean execute(String sqlStatement) //执行字符串中指定的sql语句。可能会产生多个结果集和更新计数。 ResulSet getResultSet() //返回前一条查询语句的结果集。如果前一条语句未产生结果集,则返回null值 int getUpdateCount() long getLargeUpdateCount() //返回受前一条更新语句影响的行数。 void close() //关闭该语句对象以及它所对应的结果集 boolean isColsed() //如果该语句被关闭,则返回true void closeOnCompletion() //一旦该语句的所有结果集都被关闭,则关闭该语句 java.sql.ResultSet boolean next() //将结果集中的当前行向前移动一行 Xxx getXxx(int columnNuber) Xxx getXxx(String columnLabel) //(Xxx指数据类型,例如 int、double、String和Date等) <T> T getObject(int columnIndex,Class<T> type) <T> T getObject(String columnIndex,Class<T> type) //用给定的列序号或列标签返回或更新该列的值,并将值转换成指定的类型 int findColumn(String columnName) //根据给定的列名,返回该列的序号。 void close() //立即关闭当前的结果集 boolean isClosed() //如果该语句被关闭,则返回true //ResultSetMetaData //可用于获取关于 ResultSet 对象中列的类型和属性信息的对象 //ResultSetMetaData meta = rs.getMetaData(); getColumnName(int column):获取指定列的名称 getColumnLabel(int column):获取指定列的别名 getColumnCount():返回当前 ResultSet 对象中的列数。 getColumnTypeName(int column):检索指定列的数据库特定的类型名称。 getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。 isNullable(int column):指示指定列中的值是否可以为 null。 isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
-
分析SQL异常
java.sql.SQLException SQLException getNextException() //返回链接到该SQL异常的下一个SQL异常,或者在到达链尾时返回null Iterate<Throwable> iterator() //获取迭代器,可以迭代链接的SQL异常和它们的成因 String getSQLState() //获取"SQL状态",即标准化的错误代码 int getErrorCode() //获取提供商相关的错误代码
JDBC Prepared statement
-
PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的SQL 语句
-
可以通过调用 Connection 对象的 preparedStatement() 方法获取PreparedStatement 对象
-
PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从1 开始),第二个是设置的 SQL 语句中的参数的值
-
PreparedStatement 能最大可能提高性能:
- DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。
- 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次.
-
方法
java.sql.Connection PreparedStatement prepareStatement(String sql) //返回一个含预编译语句的PreparedStatement对象。 java.sql.PreparedStatement void setXxx(int n,Xxx x) //设置第n个参数值为x void clearParamenters() //清除预备语句中的所有当前参数 ResultSet executeQuery() //执行预备SQL查询,并返回一个ResultSet对象 int executeUpdate() //执行准备SQL语句INSERT、UPDATE或DELETE
获取自动生成的键
java.sql.Statement
boolean execute(String statement,int autogenerated)
int executeUpdate(String statement,int autogenerated) //如果autogenerated被设置为Statement.RETURN_GENERATED_KEYS,并且该语句是一条INSERT语句,那么第一列是自动生成的键
可滚动和可更新的结果集
-
默认情况下,结果集是不可滚动和不可更新的。需要调用下面的方法
conn.prepareStatement(command,type,concurrency)
值(ResultSet类的type值) 解释 TYPE_FORWARD_ONLY 结构集不能滚动(默认值) TYPE_SCROLL_INSENSITIVE 结果集可以滚动,但对数据库变化不敏感 TYPE_SROLL_SENSITIVE 结果集可以滚动,但对数据库变化敏感 值(ResultSet类的Concurrency值) 解释 CONCUR_READ_ONLY 结果集不能用于更新数据库(默认值) CONCUR_UPDATABLE 结果集可以用于更新数据库 -
缺点:在与用户的整个交互过程中,必须始终与数据库保持连接。可以考虑使用行级
-
java.sql.RowSet String getURL() void setURL(String url) //获取或设置数据库的URL String getUsername() void setUsername(String username) //获取或设置连接数据库所需的用户名 String getPassword() void setPassword(String password) //获取或设置连接数据库所需的密码 String getCommand() void setCommand(String command) //获取或设置向行集中填充数据时需要执行的命令 void execute() //通过执行使用setCommand方法设置的语句集来填充行集。 java.sql.rowset.CachedRowSet void execute(Connection conn) //通过执行使用setCommand方法设置的语句集来填充行集 void populate(ResultSet result) //将指定的结果集中的数据填充到被缓存的行集中 String getTableName() void setTableName(String tableName) //获取或设置数据库表名称,填充被缓存的行集时所需的数据来自该表 int getPageSize() void setPageSize(int size) //获取和设置页的尺寸 boolean nextPage() boolean previousPage() //加载下一页或上一页,如果要加载的页存在,则返回true void acceptChanges() void acceptChanges(Connection conn) //重新连接数据库,并写回行集中修改过的数据 java.x.sql.rowset.RowSetProvider static RowSetFactory newFactory() //创建一个行集工厂 javax.sql.rowset.RowSetFactory CachedRowSet createCachedRowSet() FilteredRowSet createFileredRowSet() JdbcRowSet createJdbcROwSet() JoinRowSet createJoinRowSet() WebRowSet createWebRowSet() //创建一个指定类型的行集。
事务和批量更新
-
事务
- 将一组语句构建成一个事务
java.sql.Connection boolean getAutoCommit() void setAutoCommit(boolean b) //获取改连接中的自动提交模式,或将其设置为b void commit() //提交自上次提交以来所有执行过的语句 void rollback() //撤销自上次提交以来所有执行过的语句所产生的影响 Savepoint setSavepoint() Savepoint setSavepoint(String name) //设置一个匿名或具名的保存点 void rollback(Savepoint svpt) //回滚到给定保存点 void releaseSavepoint(Savepoint svpt) //释放给定的保存点 java.sql.SqvePoint int getSavepointId() //获取该匿名保存点的ID号 String getSavepointName() //获取该保存点的名称 java.sql.Statement void addBatch(String command) //添加命令到该语句当前的批量命令中 int[] executeBatch() long[] executeLargeBatch() //执行当前批量更新中的所有命令。 java.sql.DatabaseMetaData boolean supportsBatchUpdates() //如果驱动程序支持批量更新,则返回true