java 数据库编程

1. 读写LOB

  除了数字、字符串和日期之外,许多数据库还可以存储大对象,例如图片或其它数据。在SQL中,二进制大对象称为BLOB,字符型大对象称为CLOB。

  要读取LOB,需要执行SELECT语句,然后在ResultSet上调用getBlob或getClob方法,这样就可以获得Blob或Clob类型的对象。要从Blob中获取二进制数据,可以调用getBytes或getInputStream。例如,如果你有一张保存图书封面图形的表,那么就可以像下面这样获取一张图像:

PreparedStatement stat = conn.prepareStatement("SELECT Cover FROM BookCovers WHERE ISBN=?");
stat.set(1, isbn);
ResultSet result = stat.executeQuery();
if(result.next()){
Blob coverBlob = result.getBlob(1);
Image coverImage = ImageIO.read(coverBlob.getBinaryStream());
}

  类似地,如果获取了Clob对象,那么就可以通过调用getSubString或getCharacterStream方法来获取其中的字符数据。

  要将LOB置于数据库中,需要在Connection对象上调用createBlob或createClob,然后获取一个用于该LOB的输出流或写出器,写出数据,并将该对象存储到数据库中。例如,下面展示了如何存储一张图像:

Blob coverBlob = connection.createBlob();
int offset = 0;
OutputStream out = coverBlob.setBinaryStream(offset);
ImageIO.write(coverImage, "PNG", out);
PreparedStatement stat = conn.prepareStatement("INSERT INTO Cover VALUES(?, ?)");
stat.set(1, isbn);
stat.set(2,coverBlob);
stat.executeUpdate();

2. 可滚动和可更新的结果集

  要让ResultSet可以滚动个和更新,必须在创建Statement对象的时候使用下面的方式指定对应的参数:

Statement stmt = conn.createStatement(type, concurrency);

  对于PreparedStatement,使用下面的方式指定参数:

PreparedStatement pstmt = conn.prepareStatement(sql, type, concurrency);

其中,type表示ResuleSet的类型,而concurrency表示是否可以使用ResuleSet来更新数据库。

type和concurrency的取值以及含义如下:

ResultSet类的type值
解释
ResultSet.TYPE_FORWARD_ONLY 结果集不能滚动(默认值)
ResultSet.TYPE_SCROLL_INSENSITIVE 结果集可以滚动,但ResuleSet对数据库中数据变化不敏感
 ResultSet.TYPE_SCROLL_SENSIT  IVE 结果集可以滚动,并且ResuleSet对数据库中发生的改变敏感
ResultSet类的Concurrency值
解释
ResultSet.CONCUR_READ_ONLY 结果集不能用于更新数据库(默认值)
ResultSet.CONCUR_UPDATABLE 结果集可以用于更新数据库

JDBC的结果集有很多类型。这些结果集有不同的特性,以满足各种需要。这在高性能的JDBC数据操作中有着重要应用。下面是一个应用实例:

package lavasoft.common; 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; /**
* JDBC可滚动可更新感知更新结果集测试
*
* @author leizhimin 2009-12-8 20:09:03
*/
public class TestResultSet {
public static void main(String[] args) {
testScrollResultSet();
testUpdateResultSet();
} /**
* 可更新结果集更新测试
*/
public static void testUpdateResultSet() {
Connection conn = DBToolkit.getConnection();
String sql = "SELECT * FROM book";
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql); System.out.println("---------原结果集--------");
while (rs.next()) {
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3));
} System.out.println("---------插入一条记录--------");
rs.first();
//将光标移动到插入行上
rs.moveToInsertRow();
//构建行数据
rs.updateString(2, "xxxx");
rs.updateString(3, "x");
//插入一行
rs.insertRow(); System.out.println("-------------更新一条记录-------------");
rs.absolute(3);
//构建行数据
rs.updateString(2, "uuuu");
rs.updateString(3, "u");
rs.updateRow(); System.out.println("---------插入更新后的结果集--------");
rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3));
}
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBToolkit.closeConnection(conn);
}
} /**
* 可滚动结果集滚动测试
*/
public static void testScrollResultSet() {
Connection conn = DBToolkit.getConnection();
String sql = "SELECT * FROM book";
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3));
} System.out.println("------前滚操作-----");
//将光标移动到此 ResultSet 对象的上一行
rs.previous();
rs.previous();
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3)); System.out.println("------绝对定位-----");
//将光标移动到此 ResultSet 对象的给定行编号。
rs.absolute(3);
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3)); System.out.println("------移动到第一行-----");
//将光标移动到此 ResultSet 对象的第一行。
if (rs.first()) {
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3));
} System.out.println("------移动到最后一行-----");
//将光标移动到此 ResultSet 对象的第一行。
if (rs.last()) {
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3));
} System.out.println("------移动到第一行之前-----");
//将光标移动到此 ResultSet 对象的开头,正好位于第一行之前
rs.beforeFirst();
rs.next();
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3)); System.out.println("------移动到最后一行之后-----");
//将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
rs.afterLast();
rs.previous();
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3)); System.out.println("------相对当前行做移动-----");
rs.relative(-2);
System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3)); rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBToolkit.closeConnection(conn);
}
}
}

控制台输出:

[行号:1] 1 aaa a
[行号:2] 2 bbb b
[行号:3] 3 ccc c
[行号:4] 4 ddd d
[行号:5] 5 eee e
[行号:6] 6 fff f
[行号:7] 7 ggg g
[行号:8] 8 hhh h
------前滚操作-----
[行号:7] 7 ggg g
------绝对定位-----
[行号:3] 3 ccc c
------移动到第一行-----
[行号:1] 1 aaa a
------移动到最后一行-----
[行号:8] 8 hhh h
------移动到第一行之前-----
[行号:1] 1 aaa a
------移动到最后一行之后-----
[行号:8] 8 hhh h
------相对当前行做移动-----
[行号:6] 6 fff f
---------原结果集--------
[行号:1] 1 aaa a
[行号:2] 2 bbb b
[行号:3] 3 ccc c
[行号:4] 4 ddd d
[行号:5] 5 eee e
[行号:6] 6 fff f
[行号:7] 7 ggg g
[行号:8] 8 hhh h
---------插入一条记录--------
-------------更新一条记录-------------
---------插入更新后的结果集--------
[行号:1] 1 aaa a
[行号:2] 2 bbb b
[行号:3] 3 uuuu u
[行号:4] 4 ddd d
[行号:5] 5 eee e
[行号:6] 6 fff f
[行号:7] 7 ggg g
[行号:8] 8 hhh h
[行号:9] 9 xxxx x Process finished with exit code 0

可保存性:设置提交时候是否关闭结果集。

ResultSet.HOLD_CURSORS_OVER_COMMIT :在提交后结果集还可用

ResultSet.CLOSE_CURSORS_AT_COMMIT:在提交时候关闭结果集

由于这些特性比较高级,不同数据库驱动对此实现也不一样。因此在使用JDBC高级特性的时候最好做个测试,以保证程序的可靠性。

当type设置为:ResultSet.TYPE_SCROLL_INSENSITIVE 或者 ResultSet.TYPE_SCROLL_INSENSITIVE 时,游标可以移动,但是移动的位置是[1,count],记住并不是从0开始,否则会报错。

既然可以移动,那么把移动的几个方法解释一下:

rs = statement.executeQuery();  游标指向第一行前面的位置,这个位置是不能获取数据,否则报错:结果集没有当前行

rs.next();  // 游标下移一个位置,如果所在位置有结果集那么返回true,否则返回false

rs.previous(); // 游标上移一个位置,如果所在位置有结果集那么返回true,否则返回false

rs.first(); //  游标指向第一行的位置

rs.last(); //  游标指向最后一行的位置

rs.beforeFirst(); // 游标指向第一行前面的位置 , 这个位置不能获取数据

rs.afterLast(); //  游标指向最后一行后面的位置,这个位置不能获取数据

rs.absolute(index); // 游标移动至index位置,index是[1,count]的任意数字,但是不能超出,否则报错

rs.relative(index); // 游标从当前位置算移动index个位置,也就是相对移动,index可以是负数,但是计算结果同样在[1,count]内

isAfterLast(); // 判断游标是否在最后一行之后。

isBeforeFirst();// 判断游标是否在第一行之前。

ifFirst() ;  //判断游标是否指向结果集的第一行。

isLast(); // 判断游标是否指向结果集的最后一行。

getRow();// 得到当前游标所指向行的行号,行号从1开始,如果结果集没有行,返回0。

3. 元数据

  元数据在SQL中是用来描述数据库或其组成部分的数据。我们可以获得三类元数据:关于数据库的元数据,关于结果集的元数据,关于预备语句参数的元数据。元数据是描述基本数据信息的数据,操作元数据的语法如下:
DatabaseMetaData meta=conn.getMetaData();
ResultSet mrs=meta.getTables(null,null,null,new String[]{"TABLE"});

元数据结果集中第一列代表了表目录,第二列代表了表结构模式,第三列表名,第四列表类型,第五列关于表的注释。

  下面我们编写一个简单的数据库工具,通过使用元数据来浏览数据库中的所有表,该程序还展示了如何使用带缓存的行集。

方法一:直接连接数据库,代码如下:

package view;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.sql.*;
import java.util.*; import javax.sql.*;
import javax.sql.rowset.*;
import javax.swing.*; /**
* This program uses metadata to display arbitrary tables in a database.
*
* @author DELL
*/
public class ViewDB
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new ViewDBFrame();
frame.setTitle("ViewDB");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
} /**
* The frame that holds the data panel and the navigation buttons.
*/
class ViewDBFrame extends JFrame
{
private JButton previousButton;
private JButton nextButton;
private JButton deleteButton;
private JButton saveButton;
private DataPanel dataPanel;
private Component scrollPane;
private JComboBox<String> tableNames;
private Properties props;
private CachedRowSet crs; public ViewDBFrame()
{
tableNames = new JComboBox<String>();
tableNames.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showTable((String) tableNames.getSelectedItem());
}
});
add(tableNames, BorderLayout.NORTH); try
{
Class.forName("com.mysql.jdbc.Driver"); // readDatabaseProperties();
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","1234"))
{
DatabaseMetaData meta = conn.getMetaData();
ResultSet mrs = meta.getTables(null, null, null, new String[] { "TABLE" });
while (mrs.next())
tableNames.addItem(mrs.getString(3));
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} JPanel buttonPanel = new JPanel();
add(buttonPanel, BorderLayout.SOUTH); previousButton = new JButton("Previous");
previousButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showPreviousRow();
}
});
buttonPanel.add(previousButton); nextButton = new JButton("Next");
nextButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showNextRow();
}
});
buttonPanel.add(nextButton); deleteButton = new JButton("Delete");
deleteButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
deleteRow();
}
});
buttonPanel.add(deleteButton); saveButton = new JButton("Save");
saveButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
saveChanges();
}
});
buttonPanel.add(saveButton);
pack();
} /**
* Prepares the text fields for showing a new table, and shows the first row.
* @param tableName the name of the table to display
*/
public void showTable(String tableName)
{
try
{
Class.forName("com.mysql.jdbc.Driver");
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","1234"))
{
// get result set
Statement stat = conn.createStatement();
ResultSet result = stat.executeQuery("SELECT * FROM " + tableName);
// copy into cached row set
RowSetFactory factory = RowSetProvider.newFactory();
crs = factory.createCachedRowSet();
crs.setTableName(tableName);
crs.populate(result);
} if (scrollPane != null) remove(scrollPane);
dataPanel = new DataPanel(crs);
scrollPane = new JScrollPane(dataPanel);
add(scrollPane, BorderLayout.CENTER);
validate();
showNextRow();
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* Moves to the previous table row.
*/
public void showPreviousRow()
{
try
{
if (crs == null || crs.isFirst()) return;
crs.previous();
dataPanel.showRow(crs);
}
catch (SQLException e)
{
for (Throwable t : e)
t.printStackTrace();
}
} /**
* Moves to the next table row.
*/
public void showNextRow()
{
try
{
if (crs == null || crs.isLast()) return;
crs.next();
dataPanel.showRow(crs);
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
} /**
* Deletes current table row.
*/
public void deleteRow()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","1234"))
{
conn.setAutoCommit(false);
crs.deleteRow();
crs.acceptChanges(conn);
if (crs.isAfterLast())
if (!crs.last()) crs = null;
dataPanel.showRow(crs);
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* Saves all changes.
*/
public void saveChanges()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","1234"))
{
conn.setAutoCommit(false);
dataPanel.setRow(crs);
crs.acceptChanges(conn);
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // private void readDatabaseProperties() throws IOException
// {
// props = new Properties();
// try (InputStream in = Files.newInputStream(Paths.get("database.properties")))
// {
// props.load(in);
// }
// String drivers = props.getProperty("jdbc.drivers");
// if (drivers != null) System.setProperty("jdbc.drivers", drivers);
// } /**
* Gets a connection from the properties specified in the file database.properties.
* @return the database connection
*/
// private Connection getConnection() throws SQLException
// {
// String url = props.getProperty("jdbc.url");
// String username = props.getProperty("jdbc.username");
// String password = props.getProperty("jdbc.password");
//
// return DriverManager.getConnection(url, username, password);
// }
} /**
* This panel displays the contents of a result set.
*/
class DataPanel extends JPanel
{
private java.util.List<JTextField> fields; /**
* Constructs the data panel.
* @param rs the result set whose contents this panel displays
*/
public DataPanel(RowSet rs) throws SQLException
{
fields = new ArrayList<>();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1; ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++)
{
gbc.gridy = i - 1; String columnName = rsmd.getColumnLabel(i);
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel(columnName), gbc); int columnWidth = rsmd.getColumnDisplaySize(i);
JTextField tb = new JTextField(columnWidth);
if (!rsmd.getColumnClassName(i).equals("java.lang.String"))
tb.setEditable(false); fields.add(tb); gbc.gridx = 1;
gbc.anchor = GridBagConstraints.WEST;
add(tb, gbc);
}
} /**
* Shows a database row by populating all text fields with the column values.
*/
public void showRow(ResultSet rs) throws SQLException
{
for (int i = 1; i <= fields.size(); i++)
{
String field = rs == null ? "" : rs.getString(i);
JTextField tb = fields.get(i - 1);
tb.setText(field);
}
} /**
* Updates changed data into the current row of the row set.
*/
public void setRow(RowSet rs) throws SQLException
{
for (int i = 1; i <= fields.size(); i++)
{
String field = rs.getString(i);
JTextField tb = fields.get(i - 1);
if (!field.equals(tb.getText()))
rs.updateString(i, tb.getText());
}
rs.updateRow();
}
}

方法二:使用database.properties配置文件,代码如下:

package view;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.sql.*;
import java.util.*;
import javax.sql.*;
import javax.sql.rowset.*;
import javax.swing.*; /**
* This program uses metadata to display arbitrary tables in a database.
*
* @author DELL
*/
public class ViewDB
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new ViewDBFrame();
frame.setTitle("ViewDB");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
} /**
* The frame that holds the data panel and the navigation buttons.
*/
class ViewDBFrame extends JFrame
{
private JButton previousButton;
private JButton nextButton;
private JButton deleteButton;
private JButton saveButton;
private DataPanel dataPanel;
private Component scrollPane;
private JComboBox<String> tableNames;
private Properties props;
private CachedRowSet crs; public ViewDBFrame()
{
tableNames = new JComboBox<String>();
tableNames.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showTable((String) tableNames.getSelectedItem());
}
});
add(tableNames, BorderLayout.NORTH); try
{
readDatabaseProperties();
try (Connection conn = getConnection())
{
DatabaseMetaData meta = conn.getMetaData();
ResultSet mrs = meta.getTables(null, null, null, new String[] { "TABLE" });
while (mrs.next())
tableNames.addItem(mrs.getString(3));
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
catch (IOException e)
{
JOptionPane.showMessageDialog(this, e);
} JPanel buttonPanel = new JPanel();
add(buttonPanel, BorderLayout.SOUTH); previousButton = new JButton("Previous");
previousButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showPreviousRow();
}
});
buttonPanel.add(previousButton); nextButton = new JButton("Next");
nextButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
showNextRow();
}
});
buttonPanel.add(nextButton); deleteButton = new JButton("Delete");
deleteButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
deleteRow();
}
});
buttonPanel.add(deleteButton); saveButton = new JButton("Save");
saveButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
saveChanges();
}
});
buttonPanel.add(saveButton);
pack();
} /**
* Prepares the text fields for showing a new table, and shows the first row.
* @param tableName the name of the table to display
*/
public void showTable(String tableName)
{
try
{
try (Connection conn = getConnection())
{
// get result set
Statement stat = conn.createStatement();
ResultSet result = stat.executeQuery("SELECT * FROM " + tableName);
// copy into cached row set
RowSetFactory factory = RowSetProvider.newFactory();
crs = factory.createCachedRowSet();
crs.setTableName(tableName);
crs.populate(result);
} if (scrollPane != null) remove(scrollPane);
dataPanel = new DataPanel(crs);
scrollPane = new JScrollPane(dataPanel);
add(scrollPane, BorderLayout.CENTER);
validate();
showNextRow();
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
} /**
* Moves to the previous table row.
*/
public void showPreviousRow()
{
try
{
if (crs == null || crs.isFirst()) return;
crs.previous();
dataPanel.showRow(crs);
}
catch (SQLException e)
{
for (Throwable t : e)
t.printStackTrace();
}
} /**
* Moves to the next table row.
*/
public void showNextRow()
{
try
{
if (crs == null || crs.isLast()) return;
crs.next();
dataPanel.showRow(crs);
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
} /**
* Deletes current table row.
*/
public void deleteRow()
{
try
{
try (Connection conn = getConnection())
{
conn.setAutoCommit(false);
crs.deleteRow();
crs.acceptChanges(conn);
if (crs.isAfterLast())
if (!crs.last()) crs = null;
dataPanel.showRow(crs);
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
} /**
* Saves all changes.
*/
public void saveChanges()
{
try
{
try (Connection conn = getConnection())
{
conn.setAutoCommit(false);
dataPanel.setRow(crs);
crs.acceptChanges(conn);
}
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(this, e);
}
} private void readDatabaseProperties() throws IOException
{
props = new Properties();
try (InputStream in = Files.newInputStream(Paths.get("database.properties")))
{
props.load(in);
}
String drivers = props.getProperty("jdbc.drivers");
if (drivers != null) System.setProperty("jdbc.drivers", drivers);
} /**
* Gets a connection from the properties specified in the file database.properties.
* @return the database connection
*/
private Connection getConnection() throws SQLException
{
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password"); return DriverManager.getConnection(url, username, password);
}
} /**
* This panel displays the contents of a result set.
*/
class DataPanel extends JPanel
{
private java.util.List<JTextField> fields; /**
* Constructs the data panel.
* @param rs the result set whose contents this panel displays
*/
public DataPanel(RowSet rs) throws SQLException
{
fields = new ArrayList<>();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1; ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++)
{
gbc.gridy = i - 1; String columnName = rsmd.getColumnLabel(i);
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel(columnName), gbc); int columnWidth = rsmd.getColumnDisplaySize(i);
JTextField tb = new JTextField(columnWidth);
if (!rsmd.getColumnClassName(i).equals("java.lang.String"))
tb.setEditable(false); fields.add(tb); gbc.gridx = 1;
gbc.anchor = GridBagConstraints.WEST;
add(tb, gbc);
}
} /**
* Shows a database row by populating all text fields with the column values.
*/
public void showRow(ResultSet rs) throws SQLException
{
for (int i = 1; i <= fields.size(); i++)
{
String field = rs == null ? "" : rs.getString(i);
JTextField tb = fields.get(i - 1);
tb.setText(field);
}
} /**
* Updates changed data into the current row of the row set.
*/
public void setRow(RowSet rs) throws SQLException
{
for (int i = 1; i <= fields.size(); i++)
{
String field = rs.getString(i);
JTextField tb = fields.get(i - 1);
if (!field.equals(tb.getText()))
rs.updateString(i, tb.getText());
}
rs.updateRow();
}
}

项目目录结构如下:

其中database.properties的内容如下:

 #jdbc.drivers=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=1234

程序运行结果如下:

java数据库编程——读写LOB、可滚动和可更新的结果集、元数据的更多相关文章

  1. JavaEE JDBC 可滚动和可更新的结果集ResultSet

    可滚动和可更新的结果集ResultSet @author ixenos 需求背景 1.对于一个只需要分析数据的程序来说,普通的ResultSet已够用 2.但如果ResultSet用于显示一张表或查询 ...

  2. Java数据库编程

    ava与数据库交互的主要API是jdbc.jdbc的主要目的是: 1.通过使用SQL或者专有的SQL扩展,程序员可以利用java语言开发访问数据的应用. 2.数据库开发商或者数据库工具开发商改进数据库 ...

  3. java面向对象下:Java数据库编程

    19.Java数据库编程: JDBC概述:        JDBC(Java Database Connection)是java中提供的一套数据库编程API,它定义了一套用来访问数据库的标准Java类 ...

  4. 菜鸡的Java笔记 java数据库编程(JDBC)

    java数据库编程(JDBC)        介绍 JDBC 的基本功能            content (内容)        现在几乎所有的项目开发过程之中都不可能离开数据库,所以在java ...

  5. Java数据库编程及Java XML解析技术

    1.JDBC概述 A.  什么是JDBC? Java DataBase Connectivity:是一种用于执行SQL语句的Java API,它由一组用Java语言编写的类和接口组成.通过这些类和接口 ...

  6. Java数据库编程、XML解析技术

    数据库编程 JDBC概述 是Java Database Connecive,即数据库连接技术的简称,它提供了连接各种常用数据库的能力. 是一种用于执行SQL语句的Java API,可以为多种关系数据库 ...

  7. Java 数据库编程 ResultSet 的 使用方法

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  8. java 数据库编程 学习笔记 不断更新

    最近开始学习java,感觉java的数据库编程需要发个随笔记录一下,话不多说 切入正题. 一.数据库访问技术的简介 应用程序  →  执行SQL语句 →数据库 → 检索数据结果 → 应用程序   ( ...

  9. JAVA数据库编程、JAVA XML解析技术

    JDBC概述 JDBC是JAVA中提供的数据库编程API curd :数据库增删改 链接字符串:String url = "mysql :/localhost :3306/jdbc/&quo ...

随机推荐

  1. SRM 739 Div.2

    250 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostre ...

  2. linux命令(12):ping命令

    1.ping网关:ping –b 192.168.1.1 2.ping指定次数:ping -c 10 192.168.1.100 3.时间间隔和次数限制的ping:ping -c 10 -i 0.5 ...

  3. poj 2593&&poj2479(最大两子段和)

    Max Sequence Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16850   Accepted: 7054 Des ...

  4. 在LoadRunner中转换字符串大小写的C语言函数

    在LoadRunner中转换字符串大小写的C语言函数 . loadrunner语言ccharacterstringaction 封装ConvertToXXX函数: //ConvertToUpper f ...

  5. nodejs pm2使用

    参考地址:http://www.jianshu.com/p/43525232b03b 参考地址:http://blog.csdn.net/leo_perfect/article/details/536 ...

  6. 转:攻击JavaWeb应用[7]-Server篇[1]

    转:http://static.hx99.net/static/drops/tips-604.html 攻击JavaWeb应用[7]-Server篇[1] 园长 · 2013/09/22 15:39 ...

  7. scrapy抓取拉勾网职位信息(一)——scrapy初识及lagou爬虫项目建立

    本次以scrapy抓取拉勾网职位信息作为scrapy学习的一个实战演练 python版本:3.7.1 框架:scrapy(pip直接安装可能会报错,如果是vc++环境不满足,建议直接安装一个visua ...

  8. Java实现下载BLOB字段中的文件

    概述 web项目的文件下载实现:servlet接收请求,spring工具类访问数据库及简化大字段内容获取. 虽然文章的demo中是以sevlet为平台,想必在spring mvc中也有参考意义. 核心 ...

  9. Git的入门级玩法

    作为一个还没有实际开发经验的程序员,对于版本控制多少有些陌生,我通常的做法就是项目名后面加数字标记版本,然后备注一个文档说明更新.据个人了解svn用的比较多,我也学习了一点,无非是本地下载一个服务器端 ...

  10. 洛谷P4587 [FJOI2016]神秘数(主席树)

    题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...