JDBC学习

JDBC

      JAVA的数据获取方式

                        ①声明变量并赋值

                        ②Scanner控制台输入

                        ③IO流(将硬盘数据读取到java)

                        ④socket+io流 

                        ⑤从数据库中获取

      概念

                Java与数据库之间的沟通不一致, 数据库厂商提供了接口以及提供了驱动包,Java实现接口就可以操作数据库。   

                      所以JDBC就是数据厂商对外提供的能够对自己操作的驱动包也就是jar文件 

       使用 

                     ①加载驱动类          Class.forname           

                     ②获取数据库连接对象    Connection conn = DriverManager.getConnection();

                     ③ 设置提交方式为手动提交           conn.setAutoCommit(false)

                     ③获取sql命令对象          Statement sta =conn.createStatement();

                     ④获取sql命令                Srtring str = ""

                     ⑤执行sql 命令           int i = sta.executeUpdate()    返回值表示成功修改的数据量 不论增删改都是executeUpdate()

                     ⑥关闭资源                    sta.close()       conn.close()

                      删除不存在的数据不报错

      常见错误

                    class not found     驱动没找到

                    SQLEXCEPTION    URL错误

                    SQLSynTaxException    SQL语句错误

       代码展示

Connection conn=null;
		Statement stmt=null;
		//声明JDBC参数
			String driver="oracle.jdbc.driver.OracleDriver";
			String url="jdbc:oracle:thin:@localhost:1521:orcl";
			String username="scott";
			String password="oracle";
		//1 加载驱动类
		try {
			Class.forName(driver);
			//2 获取数据库连接对象(连接指定的数据库)
			conn=DriverManager.getConnection(url,username,password);                                      
            conn.setAutoCommit(false);
			//3 获取sql命令对象(编译和发送sql命令给数据库)
			stmt=conn.createStatement();
			//4 创建sql命令
			String sql="insert into dept values(97,'吃鸡学院','北京')";
			//5 指定sql命令
			int i=stmt.executeUpdate(sql);
            coon.submit()
			System.out.println("执行结果:"+i);
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//6 关闭资源
			try {
				stmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
                coon.rollback
			}
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

    增删查代码基本都一样 都是用 executeUpdate 

     查是 executeQuery   返回类型为Resultset (基于指针类似枚举)  但是查询时候i不方便,尽量转换成arraylist .并且根据数据库表创建相应的类  ,则一个对象含有一组数据保证了数据的完整性。

     使用resultset时候 resultset最后要关闭 Resultset  re =new Resultset()   re.close()

 

   事务管理

                JDBC为自动提交    后一条语句错了前一条也会提交 比如银行转账 一个人给另一个人转1000 看为两个SQL语句,第二个错了即第二个人收不到钱,但是第一个人钱也已经转出去了 会出现问题。  手动提交则有一个错误就不提交。增删改设置手动提交,查可以不设置。

                    

                 概念:一个事物完成需要多个事物协助完成

                上图代码已经添加手动提价功能

  开发步骤

                 业务需求分析

                 数据库设计

                 sql语句设计

                 数据库操作功能实现

                 业务逻辑代码实现

                 联合测试

                上线测试

                 维护

PreparedStatement对象完成查询

     原因:使用statement可能存在sql注入风险

           

                     ①加载驱动类          Class.forname           

                     ②获取数据库连接对象    Connection conn = DriverManager.getConnection();

                    // ③ 设置提交方式为手动提交           conn.setAutoCommit(false)

                     ④获取sql命令                Srtring str = "select * from   where  uname=? and upwd =?"

                     ③获取sql命令对象       PrepareStatement  ps =coon.prepareStament(str)

                     ④ 给占位符赋值          ps.setString(1,“liming”)  不知道类型就setObject()

                     ⑤执行sql 命令           int i = ps.executeUpdate()    返回值表示成功修改的数据量 不论增删改都是executeUpdate()

                     ⑥关闭资源                    sta.close()       conn.close()

      优点: 

              防止了sql注入

             执行效率高因为有预编译    多次执行同一条sql语句 sql只编译一次 ,statement因为sql以字符串的形式存在所以使用一次要编译一次 

     区别:

            先预编译模板sql语句 然后再创建sql命令对象 然后再实现占位符的赋值 最后再执行                       

             statement 可以用于sql语句的拼接   prepareStatement不可以

JDBC的封装

           原因:驱动加载 数据库连接对象的代码都是重复的  

           解决: 

                  方法一:将变量设置到全局变量 比如username  url password   但是修改数据源 比如class 则必须重启程序才能完成

                 方法二: 将四个参数  driver  url  username password 存储到properties属性配置文件中, 封装工具类进行获取

              properties文件专门存储属性配置的文件  格式是键值对 以=号隔开,并且不能以;结尾 可以使用Properties对象进行读取该文件内容

                   

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtil {
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	
	static{
		//创建properties对象获取属性文件的内容
		Properties p=new Properties();
		//获取属性文件的读取流对象
		InputStream is=JdbcUtil.class.getResourceAsStream("/db.properties");
		try {
			//加载属性配置文件
			p.load(is);
			//获取jdbc参数
			driver=p.getProperty("driver");
			url=p.getProperty("url");
			username=p.getProperty("username");
			password=p.getProperty("password");
			//加载驱动
			Class.forName(driver);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//获取Connection对象
	public static Connection getConnection(){
		Connection conn=null;
		try {
			 conn=DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
		
	}
	
	//封装获取PreparedStatement对象
	public static PreparedStatement getPreparedStatement(String sql,Connection conn){
		
		PreparedStatement ps=null;
		try {
			ps =conn.prepareStatement(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ps;
		
	}
	
	//封装获取Statement对象
	public static Statement getStatement(Connection conn){
		Statement stmt=null;
		try {
			stmt = conn.createStatement();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return stmt;
		
	}
	
	//关闭资源
	public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
		try {
			rs.close();
		} catch (Exception e) {
			
		}
		try {
			stmt.close();
		} catch (SQLException e) {
			
		}
		try {
			conn.close();
		} catch (SQLException e) {
			
		}
	}
	
	//封装DML
	public static int executeDML(String sql,Object...objs){
		//创建连接对象
		Connection conn=getConnection();
		//创建sql命令对象
		PreparedStatement ps=JdbcUtil.getPreparedStatement(sql, conn);
		//给占位符赋值
			try {
				conn.setAutoCommit(false);
				for(int i=0;i<objs.length;i++){
					ps.setObject(i+1, objs[i]);
				}
				int i=ps.executeUpdate();
				conn.commit();
				return i;
			} catch (Exception e) {
					try {
						conn.rollback();
					} catch (SQLException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
			}finally{
				//关闭资源
				JdbcUtil.closeAll(null, ps, conn);
			}
			//返回结果
			return -1;
	}
}

                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值