1.数据库中行级锁:在sql语句后+for update
2.DBHelper
public class DBHelper {
// 1.对于老版本的不支持SPI机制的驱动,是用静态块加载驱动,驱动程序只加载一次,使用静态块
static {
try {
System.out.println("加载驱动");
Class.forName(DbProperties.getInstance().getProperty("driverClassName"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 2.将获取数据连接封装成一个方法
public Connection getConnection() {
DbProperties p = DbProperties.getInstance();
Connection con = null;
try {
con = DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"), p.getProperty("password"));
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
// 增删改统称为更新,可以用一个方法来完成,不同部分在于sql语句,还有?的问题
// Object... values 代表一个动态数组 可以为空 也可以是任意长度 另外 动态数组只能在参数列表的最后一个参数
public int doUpdate(String sql, Object... values) throws SQLException {
int result = 0;
try (Connection con = getConnection(); PreparedStatement pstmt = con.prepareStatement(sql); // 预编译
) {
// 调用设置参数的方法,设置参数
setParams(pstmt, values);
// 发出更新操作
result = pstmt.executeUpdate(); //更新
// 标准的jdbc是隐式事务提交,不需要写事务代码
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
// 设置参数
private void setParams(PreparedStatement pstmt, Object... values) throws SQLException {
// 循环参数列表 values ,给pstmt中的sql的?设置参数
if (values != null && values.length > 0) {
for (int i = 0; i < values.length; i++) {
// 所有参数都当成Object处理
pstmt.setObject(i + 1, values[i]);
}
}
}
// 聚合函数查询
public double selectAggreation(String sql, Object... values) {
double result = 0;
try (
Connection con = getConnection();
PreparedStatement pstmt = con.prepareStatement(sql) // 预编译
) {
// 设置参数
setParams(pstmt, values);
ResultSet rs = pstmt.executeQuery(); //查询
if (rs.next()) {
result = rs.getDouble(1);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//查询 返回值:List<Map<String,Object>>
public List<Map<String,Object>> select(String sql,Object... values){
System.out.println(sql);
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
try(
Connection con = getConnection();
PreparedStatement pstmt = con.prepareStatement(sql);
){
//设置参数
setParams(pstmt,values);
//查询
ResultSet rs = pstmt.executeQuery();
//根据rs获取结果集的元数据,取所有的字段名,用于Map的键
ResultSetMetaData rsmd = rs.getMetaData();
int cc = rsmd.getColumnCount();//结果集中中的列数
List<String> columnName = new ArrayList<String>();
for(int i= 0; i < cc; i++) {
columnName.add(rsmd.getColumnName(i+1));
}
//循环结果集,取出每一行
while(rs.next()) {
//循环所有的列,一个列一个列的取值,存到Map中
Map<String,Object> map = new HashMap<String,Object>();
//循环所有的列
for(int i = 0; i < columnName.size(); i++) {
String cn = columnName.get(i); //取列名
Object value = rs.getObject(cn); // 根据列名取值
//存到map中
map.put(cn, value);
}
list.add(map);
}
}catch(Exception e) {
e.printStackTrace();
}
return list;
}
}
3.DbProperties
/*
* DbProperties是java.util包下的类,表示一个资源文件,通常都是键=值,他有一个load();
* DbProperties类用于读取db.properties数据库配置信息文件
* 此操作的特点:在整个项目中只操作一次,写成单例,(只有一个此类的实例)
* 构造方法必须私有化,对外提供一个操作方法来获取唯一的实例
*
*/
public class DbProperties extends Properties{
//静态,类一加载就执行
private static DbProperties dbProperties = new DbProperties();
//单例要求构造噢方法必须私有化
private DbProperties() {
try (
//获取类加载器,此加载器从类路径下(bin)读取文件
InputStream fis = DbProperties.class.getClassLoader().getResourceAsStream("db.properties");
){
super.load(fis);
}catch(Exception e) {
e.printStackTrace();
}
}
public static DbProperties getInstance() {
if(dbProperties == null) {
dbProperties = new DbProperties();
}
return dbProperties;
}
}
4.db.properties
driverClassName = oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@//localhost:1521/orcl
username=****
password=****