以下问题为自己编程过程中遇到的问题,如果各路神通觉得我出现的问题比较低级。可以给出解决意见,但不要乱喷。心灵脆弱禁不起打击,本博作为我编程路上跳坑记录,学会之后会过来填平。但不知道什么时候才能学会。
1、针对一张表查询一条数据的通用方法
实体类
package com.company.preparedstatement.crud;
public class course {
public String CId;
public String Cname;
public String TId;
public course() {
}
public course(String CId, String cname, String TId) {
this.CId = CId;
Cname = cname;
this.TId = TId;
}
public String getCId() {
return CId;
}
public void setCId(String CId) {
this.CId = CId;
}
public String getCname() {
return Cname;
}
public void setCname(String cname) {
Cname = cname;
}
public String getTId() {
return TId;
}
public void setTId(String TId) {
this.TId = TId;
}
@Override
public String toString() {
return "course{" +
"CId='" + CId + '\'' +
", Cname='" + Cname + '\'' +
", TId='" + TId + '\'' +
'}';
}
}
工具类
package com.company.preparedstatement.Utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException {
//1、获取
InputStream is = ClassLoader.getSystemClassLoader().getSystemResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(is);
String driverClass = properties.getProperty("driverClass");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
Class.forName(driverClass);
Connection connection = DriverManager.getConnection(url, user, password);
is.close();
return connection;
}
/*
* 关闭连接和Statement的操作
* */
public static void closeResource(Connection connection, PreparedStatement preparedStatement){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
db.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=123456
查询一张表数据的方法
@org.junit.Test
package com.company.preparedstatement.crud;
import com.company.preparedstatement.Utils.JDBCUtils;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class Test {
//针对一张表查询一条数据的通用方法
public course test4(String sql,Object... args) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
//创建连接
connection = JDBCUtils.getConnection();
//获取对象
ps = connection.prepareStatement(sql);
//获取占位符对应的值
for(int i = 0;i < args.length;i++){
ps.setObject(i+1,args[i]);
}
//执行返回结果集
resultSet = ps.executeQuery();
//获取结果集的元数据:ResultSetMetaData
ResultSetMetaData metaData = resultSet.getMetaData();
//获取字段值个数
int columnCount = metaData.getColumnCount();
//判断有没有返回值
if(resultSet.next()){
//创建一个对象
course cs = new course();
//处理一行数据中的每一个列
for(int i = 0;i < columnCount;i++){
//获取列值
Object columValue = resultSet.getObject(i + 1);
//获取每个列的列名
String columName = metaData.getColumnName(i + 1);
//给对象中的给对象中columName属性用set方法赋值为columvalue:通过反射实现
//通过反射获取属性
Field field = course.class.getDeclaredField(columName);
//属性值可能是私有的,设置一下
field.setAccessible(true);
//给对象的属性赋值
field.set(cs,columValue);
}
//返回对象
return cs;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭资源
JDBCUtils.closeResource(connection,ps,resultSet);
return null;
}
}
}
测试方法
public void test44(){
String sql = "select * from course where CId=?";
course course = test4(sql, "01");
System.out.println(course);
}
出现的问题:
try中包含的代码可以顺利的执行,也能成功的向创建的对象中添加相应的数据,但到return的时候无论如何都会返回null。程序返回多条数据的时候只执行一次循环就会return null结束程序。
代码存在缺陷:
假如try中顺利执行也成功return就无法继续执行下面的代码关闭资源,程序硬伤
大发现
//cs.getClass()和course.class return出的内容不同!!!!
Field declaredField = cs.getClass().getDeclaredField(columName);
cs.getClass():可以返回一条数据
course.class :直接return null
oh,my god!一定是我太无知了
emmmmmmm他们又返回一样的值了,我真的不懂这是什么魔鬼操作!!!
2、数据库事务回滚
package com.company.trans;
import com.company.Utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TransactionTest {
/**
* 针对于数据表user_table
*
* */
@Test
public void testUpdate()
{
String sql1 = "update sc set score = score - 10 where SId = ?";
String sql2 = "update sc set score = score + 10 where SId = ?";
update(sql1,"06");
System.out.println(10/0);
update(sql2,"07");
System.out.println("分数交换成功!");
}
//=================没有考虑数据库事务情况下的分数同时增加缩小的操作===================
//增删改通用操作
public void update(String sql,Object... agrs) {
Connection connection = null;
PreparedStatement ps = null;
try {
//1.获取数据库连接
connection = JDBCUtils.getConnection();
//2.预编译sql语句,返回PrepareStatement的实例
ps = connection.prepareStatement(sql);
//3.添加占位符
for(int i = 0;i < agrs.length;i++){
ps.setObject(i + 1,agrs[i]);
}
//4.执行
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally {
//5.关闭资源
JDBCUtils.closeResource(connection,ps);
}
}
//=====================考虑数据库事务的的分数交换操作=====================
public int update1(Connection connection,String sql,Object... agrs) {
PreparedStatement ps = null;
try {
//2.预编译sql语句,返回PrepareStatement的实例
ps = connection.prepareStatement(sql);
//3.添加占位符
for(int i = 0;i < agrs.length;i++){
ps.setObject(i + 1,agrs[i]);
}
//4.执行
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally {
//5.关闭资源
JDBCUtils.closeResource(null,ps);
}
return 0;
}
@Test
public void updateTest(){
Connection connection = null;
try {
connection = JDBCUtils.getConnection();
//将数据库语句自动提交设置为false
connection.setAutoCommit(false);
String sql1 = "update examstudent set Grade = Grade - 10 where FlowID = ?";
update1(connection,sql1,2);
//设置异常
//System.out.println(10/0);
String sql2 = "update examstudent set Grade = Grade + 10 where FlowID = ?";
update1(connection,sql2,3);
//手动提交事务
connection.commit();
} catch (Exception e) {
try {
//出现异常
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.closeResource(connection,null);
}
}
}
存在问题,由于数据库关闭方法中的对象在不同的位置关闭,其中就有一方为null,有一个为null系统会报空指针异常