目录
一、自定义BaseDao/DBHelper类
1.一般,我们把JDBC中加载驱动类,创建连接等方法放在这个类中;
2.加载驱动类的方法我们一般让它最先执行,并且只执行一次;
public class BaseDao {
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8";
private static final String USERNAME = "test";
private static final String PASSWORD = "3325434";
static {
try {
// 加载驱动类
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接对象
* @return 返回连接对象
*/
public Connection getConn(){
Connection conn = null;
try {
conn = DriverManager.getConnection(URL,USERNAME,PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭连接,释放资源
* @param conn 连接对象
* @param state 语句对象
* @param rs 结果集对象
*/
public void close(Connection conn, Statement state, ResultSet rs){
try {
if(rs != null){
rs.close();
}
if(state != null){
state.close();
}
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 通用的不带参数的增删改方法
* @param sql 要执行的sql语句
* @return 受影响行数
*/
public int update(String sql){
Connection conn = getConn();
Statement state = null;
int result = -1;
try {
state = conn.createStatement();
result = state.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn,state,null);
}
return result;
}
/**
* 通用的不带参数的查询方法
* @param sql 要执行的sql语句
* @return 结果集对象
*/
public ResultSet query(String sql){
Connection conn = getConn();
Statement state = null;
ResultSet rs = null;
try {
state = conn.createStatement();
rs = state.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
/**
* 通用的带参数的查询方法
* @param sql 要执行的sql语句
* @param objs 可变参数
* @return 结果集对象
*/
public ResultSet query(String sql,Object ... objs){
Connection conn = getConn();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < objs.length; i++) {
ps.setObject(i+1,objs[i]);
}
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
}
二、先有静态的,再有动态的
三、先有属性,后有方法
四、(个数)可变参数
1.语法:参数类型 ... 参数名;
2.可以将可变参数看作是数组;
/**
* 通用的带参数的增删改方法
* @param sql 要执行的sql语句
* @param objs 可变参数
* @return 受影响的行数
*/
public int update(String sql,Object ... objs){
Connection conn = getConn();
PreparedStatement ps = null;
int result = -1;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < objs.length; i++) {
ps.setObject(i+1,objs[i]);
}
result = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn,ps,null);
}
return result;
}
五、高级结果集
1.使用预编译语句(带四个参数的)
// newBaseDao的对象
BaseDao dao = new BaseDao();
// 获取连接对象
Connection conn = dao.getConn();
// 创建sql语句
String sql = "select sno sid,sname,ssex,sbirthday,class from student";
// 通过连接对象创建语句对象
PreparedStatement ps = conn.prepareStatement( sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE,ResultSet.CLOSE_CURSORS_AT_COMMIT);
// 执行sql语句
ResultSet rs = ps.executeQuery();
(1)第一个参数:sql语句
(2)第二个参数:
- ResultSet.TYPE_FORWARD_ONLY:只进结果集;
- ResultSet.TYPE_SCROLL_SENSITIVE:结果集可以任意滚动,对于数据库的改变是敏感的;
- ResultSet.TYPE_SCROLL_INSENSITIVE:结果集可以任意滚动,对于数据库的改变是不敏感的;
- 注意:这个参数对于SQL Server是有一点用的,但是对于MySQL是没有什么用的;
(3)第三个参数:
- ResultSet.CONCUR_READ_ONLY:表示结果集只读;
- ResultSet.CONCUR_UPDATABLE:表示结果集可以修改;
(4)第四个参数:
- ResultSet.HOLD_CURSORS_OVER_COMMIT:表示游标一直打开,直到提交完成;
- ResultSet.CLOSE_CURSORS_AT_COMMIT:表示执行完之后就马上关闭结果集;
2.高级结果集的常用方法
(1)结果集对象名.next():
- 结果集中的下一条内容;
-
// 下一条 rs.next();
(2)结果集对象名.absolute(行数):
- 将结果集中的内容定位到某一行,当读取数据的时候,会从这一行开始读取;
- 这是绝对定位,就是从第一条结果开始定位;
-
// 绝对定位到指定行 rs.absolute(5);
(3)结果集对象名.relative():
- 将结果集中的内容定位到某一行,当读取数据的时候,会从这一行开始读取;
- 这个相对定位,就是从当前行开始定位;
-
// 相对定位 rs.relative(2);
(4)结果集对象名.previous()
- 结果集中的上一条内容;
-
// 上一条 rs.previous();
(5)结果集对象名.last()
- 跳到结果集中的最后一条内容;
-
// 最后一条 rs.last();
(6)结果集对象名.deleteRow()
- 删除结果集中当前行;
-
// 删除结果集中第八条的数据 rs.absolute(8); rs.deleteRow();
(7)在结果集中插入数据
- 结果集对象名.moveToInsertRow();
- 结果集对象名.updateString();
- 结果集对象名.insertRow();
-
// 在结果集中插入数据 rs.moveToInsertRow(); rs.updateString("sno","131"); rs.updateString("sname","张小小"); rs.updateString("ssex","女"); rs.updateString("sbirthday","2001-09-09"); rs.updateString("class","95010"); rs.insertRow();
- 注意:这个操作会影响到数据库中的内容;
(8)在结果集中修改数据
- 结果集对象名.last();
- 结果集对象名.updateString();
- 结果集对象名.updateRow();
-
// 在结果集中修改最后一条数据 rs.last(); rs.updateString("sname","小小"); rs.updateRow();
- 注意:这个操作会影响到数据库中的内容;
(9)关于元数据的操作(可以用到excel的导出中)
- 结果集对象名.getMetaData();
-
// 关于元数据的操作 ResultSetMetaData rsmd = rs.getMetaData();
- 上面的方法会返回ResultSetMetaData类型对象;
- ResultSetMetaData类型对象.getColumnCount():获取列数;
-
// 获取列数 System.out.println(rsmd.getColumnCount());
- ResultSetMetaData类型对象.getColumnName():获取数据表的列名;
-
// 获取数据表的列名 System.out.println(rsmd.getColumnName(1));
- ResultSetMetaData类型对象.getColumnLabel():获取数据表的列名的别名;
-
// 获取数据表的列名的别名 System.out.println(rsmd.getColumnLabel(1));
- ResultSetMetaData类型对象.getColumnTypeName():获取到数据表的列的类型;
-
// 获取到数据表的列的类型 System.out.println(rsmd.getColumnTypeName(1));
- ResultSetMetaData类型对象.getColumnClassName():获取到数据表的列在java中对应的类型;
-
// 获取到数据表的列在java中对应的类型 System.out.println(rsmd.getColumnClassName(1));
- ResultSetMetaData类型对象.getTableName():获取到数据表的表名;
-
// 获取到数据表的表名 System.out.println(rsmd.getTableName(1));