一、SqlHelper的编写
PreperedStatement是Statement的子类,它的实例对象可以通过调用Connection.preparedStatement()方法获得,相对于Statement对象而言:PreperedStatement可以避免SQL注入的问题。
Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。
在进行jdbc 程序编写的时候,因为对数据库操作很多,所有都会把对数据库的各种操作,封装到一个类(SqlHelper/DBUtil)。
如果访问数据库很频繁,则我们的Connection 、PreparedStatement,ResultSet..就不要搞成static
#这是我的oracle配置
url=jdbc:oracle:thin:@127.0.0.1:1521:orclhsp
username=liu
driver =oracle.jdbc.driver.OracleDriver
password=tiger
public class SqlHelper{
//定义需要的变量
private static Connection ct=null;
//在大多数情况下使用PrepareStatement替代Statement
//这样可以防止sql注入漏洞
private static PrepareStatement ps=null;
private static ResultSet rs=null;
private static CallableStatement cs=null;
//连接数据库参数
private static String url="";
private static String username="";
private static String driver="";
private static String password="";
private static Properties pp=null;
private static FileInputStream fis=null;
//加载驱动,只需要一次
static{
try{
//从dbinfo.propertis文件中读取配置文件
pp=new Properties;
fis=new FileInputStream("dbinfo.propertis");
pp.load(fis);
url=pp.getProperty("url");
username=pp.getProperty("username");
driver=pp.getProperty("driver");
password=pp.getProperty("password");
Class.forName(driver);
} catch(Exception e){
e.printStackTrace();
}finally({
fis.close();
fis=null;
}
}
//得到连接
public static Connection getConnection(){
ct=DriverManager.getConnection(url.user,password)
return ct;
}
//调用存储过程(有返回Result)
public static CallableStatement callPro2(String sql,String []inparameters,Integer []outparameters){
try{
ct=getConnection();
cs=ct.prepareCall(sql);
//?赋值
if(inparameters=null){
for(int i=0;i<inparameters.length;i++){
cs.setObject(i+1,inparameters[i]);
}
}
//给out参数赋值
if(outparameters!=null){
for(int i=0;i<outparameters.length;i++){
cs.registerOutParameter(inparameters.length+1+i,outparmeters[i]);
}
}
cs.execute();
} catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally({
//不需要关闭
}
return cs;
}
//调用存储过程
//sql 像 {call 过程(?,?,?)}
public static void callPro1(String sql,String []parameters){
try{
ct=getConnection();
cs=ct.prepareCall(sql);
//?赋值
if(parameters!=null){
for(int i=0;i<parameters.length;i++){
cs.setObject(i+1,parameters[i]);
}
cs.execute();
}
} catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally({
close(rs,cs,ct);
}
}
//分页问题
public static Result executeQuery2(){
return null;
}
//统一的select
public static ResultSet executeQuery(Stringsql,Strin[]parameters){
try{
if(parameters!=null){
for(int i=0;i<parameters.length;i++){
ps.setString(i+1,parameters[i]);
}
}
rs=ps.executeQuery();
} catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally({
}
return rs;
}
//如果有多个update/delete/insert
//考虑事物
public void executeUpdate2(String sql[],String []{}parameters){
try{
//获得连接
ct=getConnection();
//因为这时,用户传入的可能是多个sql语句
ct.setAutoCommit(false);
for(int i=0;i<sql.length;i++){
if(parameters[i]!=null){
ps=ct.prepareStatement(sql[i])
for(int j=0;j<parameters[i].length;j++){
ps.setString(j+1,parameters[i][j])
}
ps.executeUpdate();
}
}
ct.commit;
//执行
ps.executeUpdate();
}catch(Exception){
e.printStackTrace();//开发阶段
ct.rollback();
//抛出异常,抛出运行异常,可以给调用该函数的函数一个选择
//可以处理,也可以放弃处理
throw new RuntimeException(e.getMessage());
}finally{
//关闭资源
close(rs,ps,ct);
}
}
//先写一个update/delete/insert
//sql格式: update 表名 set 字段名=? where 字段=?
public void executeUpdate(String sql,String []parameters){
//创建一个ps
try{
ct=getConnection();
ps=ct.prepareStatement(sql);
//给?赋值
if(parameters!=null){
for(int i=o;i<parameters.length;i++){
ps.setString(i+1,parameter[i]);
}
}
//执行
ps.executeUpdate();
}catch(Exception){
e.printStackTrace();//开发阶段
//抛出异常,抛出运行异常,可以给调用该函数的函数一个选择
//可以处理,也可以放弃处理
throw new RuntimeException(e.getMessage());
}finally{
//关闭资源
close(rs,ps,ct);
}
}
//关闭资源的函数
public static void close(ResultSet rs,Statement ps,Connection ct){
//关闭资源[先开后闭];
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rs=null;//使用垃圾回收
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ps=null;
}
if(ct!=null){
try {
ct.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ct=null;
}
}
public static Connection getCt() {
return ct;
}
public static PrepareStatement getPs() {
return ps;
}
public static ResultSet getRs() {
return rs;
}
public static CallableStatement getCs() {
return cs;
}
}
public class TestJdbc3{
//测试SqlHelper是否可以正常使用
@Test
public void testSqlHelper(){
String sql="insert into user1 values"
+"(USER1_SEQ.nextval,?,?,sysdate,?)";
String parameters[]={"xiaohong","123","xiaohong@163.com","18"}
SqlHelper.executeUpdate(sql,parameters);
}
//测试SqlHelper考虑事务的executeUpdate2
@Test
public void testSqlHelper2(){
String sql1="update emp set sal=sal-10 where ename=?";
String sql2="update emp set sal=sal+10 where ename=?";
String sqls[]={sql1,sql2};
String sql1_paras[]={"SMITH"};
String sql2_paras[]={"KING"};
String [][]parameters={sql1_paras,sql2_paras};
SqlHelper.executeUpdate2(sqls,parameters);
}
public void testSqlHelper3(){
String sql="select * from emp";
try{
ResultSet rs=SqlHelper.executeQuery(sql,null)
while(rs.next()){
System.out.println(rs.getString("ename")+rs.getFloat("sal"));
}
}catch (Exception e){
e.printStackTrace();
}finally{
//关闭
SqlHelp.close(SqlHelp.getRs(),SqlHelp.getPs(),SqlHelp.getCt());
}
}
@Test
public void testSql4(){
try{
String sql="{call pro1(?,?)}";
String parameters []={"56","shunping"};
SqlHelper.callPro1(sql,parameters);
}catch (Exception e){
e.printStackTrace();
}
}
//调用有返回值的存储过程
@Test
public void testSql5(){
ResultSet rs=null;
try{
String sql="{call pro2(?,?)}";
String []in={"10"};
Integer []out={oracle.jdbc.OracleTypes.CURSOR};
CallableStatement cs=SqlHelper.callPro2(sql,in,out);
rs=(ResultSet) cs.getobject(2);
while(rs.next()){
System.out.print(rs.getInt(1)+" "+rs.getString(2))
}
}catch (Exception e){
e.printStackTrace();
}finally{
SqlHelper.close(rs,SqlHelper.getCs(),SqlHelper.getCt());
}
}
}