JDBC 와 데이터베이스 연결 탱크 에 대해 얼마나 알 고 있 습 니까?

74818 단어 #JavaEE
글 목록
  • 1 JDBC
  • 1.1 JDBC 사용 의 기본 절차
  • 1.2 JDBC 도구 류 구축
  • 1.3 데이터베이스 의 CRUD
  • 1.4 Dao 모드
  • 1.5 Statement 안전 문제
  • 1.6 PrepareStatement
  • 2 데이터베이스 연결 탱크
  • 2.1 사용자 정의 데이터베이스 연결 탱크
  • 2.2 사용자 정의 데이터베이스 연결 탱크 에 발생 하 는 문 제 를 해결한다.
  • 2.3 어떤 방법 을 어떻게 확장 합 니까?
  • 3 개원 연결 풀
  • 3.1 DBCP
  • 3.2 C3P0
  • 3.3 DBUtils
  • 3.3.1 첨삭
  • 3.3.2 조회
  • 3.3.3 ResultSetHandler 가 자주 사용 하 는 실현 류
  • 1 JDBC

  • JAVA 데이터베이스 연결 자바 데이터베이스 연결
  • 왜 JDBC 가 나 왔 을 까?
    SUN 회사 가 제공 하 는 데이터베이스 접근 규칙, 규범 은 데이터베이스 종류 가 비교적 많 고 자바 언어 사용 이 광범 위 하기 때문에 sun 회 사 는 규범 을 제공 하여 다른 데이터 베이스 공급 업 체 로 하여 금 기본 적 인 방문 규칙 을 실현 하 게 한다.우리 자바 프로그램 은 sun 회사 가 제공 하 는 jdbc 드라이브 만 사용 하면 됩 니 다.

  • 1.1 JDBC 를 사용 하 는 기본 절차
  • 등록 구동
    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    
  • 연결 구축
    //   
    DriverManager.getConnection("jdbc:mysql://localhost/test?user=root&password=root");
    //   :   +       ,   :   ,   :  。
    //   
    conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "root");
    
  • 창설 statement
    //  statement,       ,        
    st = conn.createStatement();
    
  • sql 을 실행 하여 ResultSet
    //    ,     
    String sql = "select * from stu";
    rs = st.executeQuery(sql);
    
  • 을 얻 었 습 니 다.
  • 결과 집 옮 겨 다 니 기
    //         
    while (rs.next()) {
    	int id = rs.getInt("id");
    	String name = rs.getString("name");
    	int age = rs.getInt("age");
    	System.out.println("id=" + id + "==name==" + name + "==age==" + age);
    }
    
  • 자원 방출
    if (rs != null) {
    	try {
    		rs.close();
    	} catch (SQLException sqlEx) { } // ignore 
    	rs = null;
    }
    ...
    
  • 1.2 JDBC 도구 류 구축
  • 자원 방출 작업 의 통합
  • 구동 방 2 차 등록
    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    // Driver            ,       ,              。         。
    //       --->     ,   。 java.sql.DriverManager.registerDriver(new Driver());
    //           。
    Class.forName("com.mysql.jdbc.Driver");	
    
  • properties 프로필 사용 하기
  • src 아래 에 xxx. properties 파일 을 설명 합 니 다. 그 내용 은 다음 과 같 습 니 다.
  • driverClass=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost/student
    name=root
    password=root
    
  • 도구 류 에서 정적 코드 블록 을 사용 하여 속성 을 읽 습 니 다.
  • // JDBC  
    public class JDBCUtil {
    	static String driverClass = null;
    	static String url = null;
    	static String name = null;
    	static String password= null;
    	static {
    		try {
    			//1.           
    			Properties properties = new Properties();
    			InputStream is = new FileInputStream("jdbc.properties");
    			
    			//       ,   src       
    			// InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
    			//      。
    			properties.load(is);
    			
    			//    
    			driverClass = properties.getProperty("driverClass");
    			url = properties.getProperty("url");
    			name = properties.getProperty("name");
    			password = properties.getProperty("password");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	/**
    	*       
    	* @return
    	*/
    	public static Connection getConn() {
    		Connection conn = null;
    		try {
    			Class.forName(driverClass);
    			conn = DriverManager.getConnection(url, name, password);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return conn;
    	}
    	/**
    	*     
    	* @param conn
    	* @param st
    	* @param rs
    	*/
    	public static void release(Connection conn , Statement st , ResultSet rs){
    		closeRs(rs);
    		closeSt(st);
    		closeConn(conn);
    	}
    	private static void closeRs(ResultSet rs) {
    		try {
    			if (rs != null) {
    				rs.close();
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			rs = null;
    		}
    	}
    	private static void closeSt(Statement st) {
    		try {
    			if (st != null) {
    				st.close();
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			st = null;
    		}
    	}
    	private static void closeConn(Connection conn) {
    		try {
    			if (conn != null) {
    				conn.close();
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			conn = null;
    		}
    	}
    }
    

    1.3 데이터베이스 의 CRUD
  • insert
    INSERT INTO t_stu (name, age) VALUES ('wangqiang', 28);
    INSERT INTO t_stu VALUES (NULL, 'wangqiang2', 28);
    
    // 1.       
    conn = JDBCUtil.getConn();
    // 2.       ,  statement
    st = conn.createStatement();
    // 3.     
    String sql = "insert into t_stu values(null , 'aobama' , 59)";
    //     ,    0      ,    
    int result = st.executeUpdate(sql);
    if (result > 0) {
    	System.out.println("    ");
    } else {
    	System.out.println("    ");
    }
    
  • delete
    DELETE FROM t_stu WHERE id = 6;
    
    // 1.       
    conn = JDBCUtil.getConn();
    // 2.       ,  statement
    st = conn.createStatement();
    
    // 3.     
    String sql = "delete from t_stu where name='aobama'";
    //      ,    0      ,    
    int result = st.executeUpdate(sql);
    if (result > 0) {
    	System.out.println("    ");
    } else {
    	System.out.println("    ");
    }
    
  • query
    SELECT * FROM t_stu;
    
    // 1.       
    conn = JDBCUtil.getConn();
    // 2.       ,  statement
    st = conn.createStatement();
    // 3.   sql  ,  ResultSet
    String sql = "select * from t_stu";
    rs = st.executeQuery(sql);
    
    // 4.      
    while (rs.next()) {
    	String name = rs.getString("name");
    	int age = rs.getInt("age");
    	System.out.println(name + "   " + age);
    }
    
  • update
    UPDATE t_stu SET age = 38 WHERE id = 1;
    
    // 1.       
    conn = JDBCUtil.getConn();
    // 2.       ,  statement
    st = conn.createStatement();
    // 3.     
    String sql = "update t_stu set age = 26 where name ='qyq'";
    //      ,    0      ,    
    int result = st.executeUpdate(sql);
    
    if (result > 0) {
    	System.out.println("    ");
    } else {
    	System.out.println("    ");
    }
    

  • 1.4 Dao 모드

  • Data Access 개체 데이터 액세스 대상
  • dao 인 터 페 이 스 를 새로 만 들 었 습 니 다. 데이터베이스 접근 규칙
    /**
    *           
    */
    public interface UserDao {
    	/**
    	*     
    	*/
    	void findAll();
    }
    
  • 을 설명 합 니 다.
  • dao 의 실현 류 를 새로 만 들 고 이전에 정 의 된 규칙
    public class UserDaoImpl implements UserDao{
    	@Override
    	public void findAll() {
    		Connection conn = null;
    		Statement st = null;
    		ResultSet rs = null;
    		try {
    			//1.       
    			conn = JDBCUtil.getConn();
    			//2.   statement  
    			st = conn.createStatement();
    			String sql = "select * from t_user";
    			rs = st.executeQuery(sql);
    			while(rs.next()){
    				String userName = rs.getString("username");
    				String password = rs.getString("password");
    				
    				System.out.println(userName+"="+password);
    			}
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally {
    			JDBCUtil.release(conn, st, rs);
    		}
    	}
    }
    
  • 을 구체 적 으로 실현 합 니 다.
  • 직접 사용 실현
    @Test
    public void testFindAll(){
    	UserDao dao = new UserDaoImpl();
    	dao.findAll();
    }
    
  • 1.5 Statement 안전 문제
  • Statement 실행 은 사실 sql 문 구 를 연결 하 는 것 입 니 다.먼저 sql 문 구 를 맞 춘 다음 에 같이 실행 합 니 다.
    String sql = "select * from t_user where username='"+ username  +"' and password='"+ password +"'";
    
    UserDao dao = new UserDaoImpl();
    dao.login("admin", "100234khsdf88' or '1=1"); //         
    // SELECT * FROM t_user WHERE username='admin' AND PASSWORD='100234khsdf88' or '1=1' 
    //      sql  ,                ,          。          。 
    rs = st.executeQuery(sql);
    

  • 1.6 PrepareStatement

  • 이 대상 은 앞의 statement 대상 을 교체 하 는 것 입 니 다.
  • 이전의 statement 과 비교 하여 주어진 sql 문 구 를 미리 처리 하고 문법 검 사 를 실시한다.sql 구문 에서 사용 합 니까?다음 에 전달 할 변 수 를 대체 하기 위해 자리 표시 자 를 사용 합 니 다.뒤에 들 어 오 는 변수 값 은 문자열 로 간주 되 며 어떤 키워드 도 생 성하 지 않 습 니 다.
    String sql = "insert into t_user values(null , ? , ?)";
    ps = conn.prepareStatement(sql);
    //              ,1        , 1  。
    ps.setString(1, userName);
    ps.setString(2, password);
    

  • 2 데이터베이스 연결 풀
  • 데이터베이스 의 연결 대상 생 성 작업 은 성능 을 소모 합 니 다.
  • 처음에 메모리 에 공간 (집합) 을 열 고 연못 에 여러 개의 연결 대상 을 설치한다.뒤에 연결 이 필요 하면 바로 연못 에서 꺼 내세 요.스스로 연결 을 만 들 지 마 세 요.사용 이 끝 났 으 니 연결 을 돌려 주 는 것 을 기억 하 세 요.연결 대상 이 순환 적 으로 이용 할 수 있 도록 확보 하 다.

  • 2.1 사용자 정의 데이터베이스 연결 풀
  • 코드 구현
    /*
    * 	1.     10   。
    * 	2.       getConnection    
    * 	3.     ,  addBack    。
    * 	4.   。
    */
    public class MyDataSource implements DataSource {
    	
    	List <Connection> list = new ArrayList<Connection>();
    	
    	public  MyDataSource() {
    		for (int i = 0; i < 10; i++) {
    			Connection conn = JDBCUtil.getConn();
    			list.add(conn);
    		}
    	}
    	
    	//                 
    	@Override
    	public Connection getConnection() throws SQLException {
    		//       ,   ,        。
    		if(list.size() == 0 ){
    			for (int i = 0; i < 5; i++) {
    				Connection conn = JDBCUtil.getConn();
    				list.add(conn);
    			}
    		}
    		
    		//remove(0) --->      。           。           
    		Connection conn = list.remove(0);
    		return conn;
    	}
    	/**
    	*     ,    。
    	* @param conn
    	*/
    	public void addBack(Connection conn){
    		list.add(conn);
    	}
    	......
    }
    
  • 나타 난 문제:
  • addBack 방법 을 추가 로 기억 해 야 합 니 다
  • 인 터 페 이 스 를 향 해 프로 그래 밍 할 수 없습니다.
    UserDao dao = new UserDaoImpl();
    dao.insert();
    DataSource dataSource = new MyDataSource();
    //           addBack  。
    
  • 어떻게 해결 합 니까?addBack 을 착안점 으로 합 니 다.


  • 2.2 사용자 정의 데이터베이스 연결 탱크 에 발생 하 는 문 제 를 해결한다.
    addBack 방법 이 하나 더 생 겼 기 때문에 이 연결 탱크 를 사용 하 는 곳 은 이 방법 을 추가 로 기억 해 야 하 며 인터페이스 프로 그래 밍 을 할 수 없습니다.
    우 리 는 인터페이스 에 있 는 그 close 방법 을 수정 할 계획 이다.원래 의 Connection 대상 의 close 방법 은 정말 연결 을 닫 는 것 입 니 다.이 close 방법 을 수정 하려 고 합 니 다. 나중에 close 를 호출 하려 고 합 니 다. 실제 닫 는 것 이 아니 라 연결 대상 을 돌려 주 는 것 입 니 다.
    2.3 어떤 방법 을 어떻게 확장 합 니까?
    원래 있 는 방법의 논 리 는 우리 가 원 하 는 것 이 아니다.자기 논 리 를 고치 고 싶 어 요.
  • 원본 코드 를 직접 바 꾸 기 - > 실현 할 수 없습니다.
  • 계승 - > 이 인터페이스의 구체 적 인 실현 이 누구 인지 알 아야 한다.
  • 장식 자 모드 를 사용 합 니 다.

  • 3. 오픈 소스 연결 풀
    3.1 DBCP
  • jar 파일 가 져 오기
  • 설정 파일 을 사용 하지 않 습 니 다:
    public void testDBCP01() {
    	Connection conn = null;
    	PreparedStatement ps = null;
    	try {
    		// 1.        
    		BasicDataSource dataSource = new BasicDataSource();
    		//            ,          ,   ,  。。
    		// jdbc:mysql://localhost/bank    :    ://  /   
    		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    		dataSource.setUrl("jdbc:mysql://localhost/bank");
    		dataSource.setUsername("root");
    		dataSource.setPassword("root");
    		
    		// 2.       
    		conn = dataSource.getConnection();
    		String sql = "insert into account values(null , ? , ?)";
    		ps = conn.prepareStatement(sql);
    		ps.setString(1, "admin");
    		ps.setInt(2, 1000);
    		ps.executeUpdate();
    	} catch (SQLException e) {
    		e.printStackTrace();
    	} finally {
    		JDBCUtil.release(conn, ps);
    	}
    }
    
  • 프로필 방식 사용:
  • 파일 xxx. properties 를 설명 합 니 다. 그 내용 은 다음 과 같 습 니 다.
  • #     
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/bank
    username=root
    password=root
    
    #
    initialSize=10
    
    #      
    maxActive=50
    
    #
    maxIdle=20
    
    #
    minIdle=5
    
    #
    maxWait=60000
    
    
    #JDBC                        :[   =property;] 
    #  :"user"   "password"            ,           。
    connectionProperties=useUnicode=true;characterEncoding=gbk
    
    #                 (auto-commit)  。
    defaultAutoCommit=true
    
    #driver default                  (TransactionIsolation)。
    #        :(    javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED
    
    Connection conn = null;
    PreparedStatement ps = null;
    try {
    	BasicDataSourceFactory factory = new BasicDataSourceFactory();
    	Properties properties = new Properties();
    	InputStream is = new FileInputStream("src//dbcpconfig.properties");
    	properties.load(is);
    	DataSource dataSource = factory.createDataSource(properties);
    	
    	//2.       
    	conn = dataSource.getConnection();
    	String sql = "insert into account values(null, ? , ?)";
    	ps = conn.prepareStatement(sql);
    	ps.setString(1, "liangchaowei");
    	ps.setInt(2, 100);
    	ps.executeUpdate();
    	
    } catch (Exception e) {
    	e.printStackTrace();
    } finally {
    	JDBCUtil.release(conn, ps);
    }
    

    3.2 C3P0
  • jar 파일 가 져 오기
  • 설정 파일 방식 을 사용 하지 않 음
    Connection conn = null;
    PreparedStatement ps = null;
    try {
    	// 1.   datasource
    	ComboPooledDataSource dataSource = new ComboPooledDataSource();
    	// 2.          
    	dataSource.setDriverClass("com.mysql.jdbc.Driver");
    	dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
    	dataSource.setUser("root");
    	dataSource.setPassword("root");
    	
    	// 2.       
    	conn = dataSource.getConnection();
    	String sql = "insert into account values(null , ? , ?)";
    	ps = conn.prepareStatement(sql);
    	ps.setString(1, "admi234n");
    	ps.setInt(2, 103200);
    	ps.executeUpdate();
    } catch (Exception e) {
    	e.printStackTrace();
    } finally {
    	JDBCUtil.release(conn, ps);
    }
    
  • 프로필 방식 사용
    //      xml    default-config   。 
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    // 1.          
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
    dataSource.setUser("root");
    dataSource.setPassword("root");
    
    // 2.       
    conn = dataSource.getConnection();
    String sql = "insert into account values(null , ? , ?)";
    ps = conn.prepareStatement(sql);
    ps.setString(1, "admi234n");
    ps.setInt(2, 103200);
    
  • 3.3 DBUtils
    3.3.1 첨삭
  • //dbutils         CRUD    ,              。         
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    
    //  
    queryRunner.update("insert into account values (null , ? , ? )", "aa" ,1000);
    
    //  
    queryRunner.update("delete from account where id = ?", 5);
    
    //  
    queryRunner.update("update account set money = ? where id = ?", 10000000 , 6);
    

  • 3.3.2 조회
  • 직접 new 인터페이스의 익명 실현 류
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    
    Account  account =  queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>(){
    	@Override
    	public Account handle(ResultSet rs) throws SQLException {
    		Account account  =  new Account();
    		while(rs.next()){
    			String name = rs.getString("name");
    			int money = rs.getInt("money");
    			
    			account.setName(name);
    			account.setMoney(money);
    		}
    		return account;
    	}	
    }, 6);
    System.out.println(account.toString());
    
  • 프레임 워 크 가 이미 작 성 된 실현 류 를 직접 사용 합 니 다.
  • 단일 대상 조회
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    //      
    Account account = queryRunner.query("select * from account where id = ?", new BeanHandler<Account>(Account.class), 8);
    
  • 여러 대상 조회
    QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    
    List<Account> list = queryRunner.query("select * from account ",new BeanListHandler<Account>(Account.class));
    
  • 3.3.3 ResultSetHandler 가 자주 사용 하 는 실현 류
  • //             
    BeanHandler,        //                 
    BeanListHandler,    //               List
    // -------------------------------------------------
    ArrayHandler,       //                
    ArrayListHandler,   //                 ,          。 
    MapHandler,         //              map
    MapListHandler,     //                 ,        map。 
    
  • 좋은 웹페이지 즐겨찾기