아아, 나는 최근에 오랫동안 아무것도 썼다. 작업 이유로 인해 회사가 개발 한 기본 ORM 프레임 워크와 접촉했습니다. 실수로 JDBC 작업을 호출 할 때 프레임 워크는 최대 절전 모드에서 SimpleJDBCTemplate을 나타냅니다. 여기서 나는 대학에있을 때 사용한 간단한 JDBC 캡슐화를 생각했습니다. 이제 코드를 게시하고 공유하겠습니다.
구성 클래스 : 동일한 패키지에서 데이터베이스 연결 구성 파일을 읽으려면 일반화 고려 사항이 더 좋습니다.
package com.tly.dbutil; import java.io.ioexception; import java.util.properties; public class config {private static properties proper = new Properties (); static {try {// dbconfig.properties configuration file prop.load (config.class.getResourceasStream ( "dbconfig.properties")); } catch (ioexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }} // Set Constant Public Static Final String class_name = prop.getProperty ( "class_name"); public static final string database_url = prop.getProperty ( "database_url"); public static final string server_ip = prop.getProperty ( "server_ip"); public static final string server_port = prop.getProperty ( "server_port"); 공개 정적 최종 문자열 database_sid = prop.getProperty ( "database_sid"); public static final string username = prop.getProperty ( "사용자 이름"); 공개 정적 최종 문자열 비밀번호 = prop.getProperty ( "비밀번호"); }DBCONFIG.POPERTIES : 데이터베이스 구성 파일, XML 형식 등을 사용할 수도 있고 구성 클래스에서 파일의 호출 위치에주의를 기울일 수도 있습니다.
class_name = com.mysql.jdbc.driverdatabase_url = jdbc : mysqlserver_ip = localhostserver_port = 3306database_sid = EmployESUname = 1
다음은 데이터베이스 연결 보조 클래스 DBCONN입니다
package com.employees.dbutil; import java.sql.connection; import java.sql.drivermanager; import java.sql.sql.sql.sql.sql.sql.resultset; import java.sql.sqlexception; public class dbconn {// 3 개의 특성 및 3 개의 Core Interfaces, 3 개의 Core Interface; 개인 준비 상태 PSTMT = NULL; 개인 결과 세트 RS = NULL; // 4 가지 메소드 // 방법 1 : 데이터베이스에 대한 연결 생성 공개 연결 getConntion () {try {// 1 : 연결 드라이버를로드, Java 반사 원칙 class.forname (config.class_name); // 2 : MySQL 데이터베이스의 연결 객체를 얻기 위해 연결 인터페이스 객체를 만듭니다. 세 가지 매개 변수 : URL 연결 문자열 계정 비밀번호 문자열 url = config.database_url+": //"+config.server_ip+":"+config.server_port+"/"+config.database_sid; conn = drivermanager.getConnection (url, config.username, config.password); } catch (classNotFoundException e) {e.printstacktrace (); } catch (sqlexception e) {e.printstacktrace (); } return conn; } // method2 : 데이터베이스를 닫는 메소드 public void closeConn () {if (rs! = null) {try {rs.close (); } catch (sqlexception e) {e.printstacktrace (); }} if (pstmt! = null) {try {pstmt.close (); } catch (sqlexception e) {e.printstacktrace (); }} if (conn! = null) {try {conn.close (); } catch (sqlexception e) {e.printstacktrace (); }}} // method3 : 명령문 추가, 삭제 및 수정에 특별히 사용되는 메소드 public int execother (preparedstatement pstmt) {try {// 1. 명령문 객체를 사용하여 sql statement int infectedrows = pstmt.executeupdate (); // 2. 반환 결과 반환 된 영향력 손실; } catch (sqlexception e) {e.printstacktrace (); 반품 -1; }} // method4 : query 문장을 보내는 데 특별히 사용됩니다. public resultset execquery (preadstatement pstmt) {try {// 1. 명령문 객체를 사용하여 sql statement rs = pstmt.executeQuery ()를 보냅니다. // 2. 결과 반환 Rs; } catch (sqlexception e) {e.printstacktrace (); 널 리턴; }}}일반적으로 위의 코드를 사용하면 간단한 CRUD 응용 프로그램을 해결할 수 있지만 많은 제한 사항이 있습니다. 예를 들어, 프로그램이 연결될 때마다 시스템의 부담이 증가하고 거래가없고 데이터 소스가 없습니다. 오늘 저는 공원의 친구가 반사를 사용하여 객체 매개 변수에서 CRUD를 직접 해결하기 위해 정원에 기사를 작성하는 것을 보았습니다. 나는 이것을 전에 작성했지만 그것을 끝내지 못했습니다. 나는 주로 일반적인 dbutil을 쓰고 싶다. 마지막으로, 나는 그것을 연구하고 그것이 Hibernate의 Simplejdbctemplate에 가까워지고 있음을 발견 했으므로 최대 절전 모드의 소스 코드를 보러 갔다. 또한, 그 기간 동안 몇 가지가 있었고 시간이 없었기 때문에이 문제를 유휴 상태로 남겼습니다. 이제 나는이 일을 보충하고 그것을 직접 검토합니다.
Basedao 클래스
package com.employees.dao; import java.io.inputStream; import java.lang.reflect.method; import java.lang.reflect.parameterizedtype; import java.sql.connection; import java.sql.date; import java.sql.preedstatement; java.util.arraylist; import java.util.iterator; import java.util.list; import com.employees.dbconn; public class basedao <t> {dbconn conn = new dbconn (); 개인 연결 연결 = NULL; @suppresswarnings ( "미사용") 개인 클래스 <t> persistentclass; @SuppressWarnings ( "확인되지 않은") public basedao () {initConnection (); // 매개 변수화 유형을 가져옵니다. 매개 변수화 된 유형 유형 = (ParameterizedType) getClass (). getGenericSuperClass (); persistentClass = (class <t>) type.getActualTyPearGuments () [0]; } / *** 데이터베이스 연결 가져옵니다* / public void initConnection () {connection = conn.getConntion (); } /** * 저장 * /public void save (t entity)는 예외를 던집니다 {// sql statement, table name에 삽입 (string sql = "insert ingetity.getClass (). getSimplename (). tolowercase () +"(문자열 get get <method> list = this. iter = list.iterator (); // 테이블 이름으로 삽입 된 필드 주문 (id, name, email, while (iter.hasnext ()) {method method = iter.next (); substring (3) .tolowercase () + ",";}. sql.substring (0, sql.lastindexof ( ",")) +") 값 ("; "; // 사전 컴파일 된 SQL 문 삽입 테이블 이름 (ID, 이름, 이메일) 값 (?,?,? 이름 (ID, 이름, 이메일) 값 (?,?,?); SQL.SubString (0, SQL.lastIndexof ( ",") + "; // 사전 컴파일 된 객체에 대한 참조를 가져옵니다. preadingstatement statement = connection.preparestatement (SQL); int i = 0; // 반복자의 마지막 줄로 포인터를 첫 번째 줄로 이동합니다. iter = list.iterator (); while (iter.hasnext ()) {메소드 메소드 = iter.next (); // 데이터베이스에 저장할 때 일부 필드 값 형식을 변경해야하기 때문에 처음에는 리턴 값 유형을 결정합니다. 예를 들어, string, sql 문은 ' "+abc+"'if (method.getReturntype (). getSimplename (). indexof ( "String")! = -1) {attring.setString (++ i, this.getString (methys, entity)); } else if (method.getReturnType (). getSimplename (). indexof ( "date")! = -1) {state.setDate (++ i, this.getDate (method, entity)); } else if (method.getReturnType (). getSimplename (). indexof ( "inputStream")! = -1) {state.setAsciistream (++ i, this.getBlob (method, entity)), 1440); } else {state.setInt (++ i, this.getInt (메소드, 엔티티)); }} // conn.execother (statement)를 실행합니다. // CloseConn (); } / ** * 수정 * / public void update (t entity)는 예외 {string sql = "update" + entity.getClass (). getSimplename (). tolowercase () + "set"; // 모든 메소드 객체 가져 오기이 클래스 목록의 수집 <methove> list = this.matchpojomethods (엔티티, "get"); // 패션 메소드 객체를 반복 할 책임이있는 임시 메소드 객체. 메소드 tempMethod = null; // 수정할 때 ID를 수정할 필요가 없기 때문에 순서대로 매개 변수를 추가하면 ID를 끝으로 이동해야합니다. 메소드 idmethod = null; iterator <methob> iter = list.iterator (); while (iter.hasnext ()) {tempMethod = iter.next (); // 메소드 이름에 ID 문자열이 포함되어 있고 길이가 2 인 경우 ID로 간주됩니다. if (tempMethod.getName (). lastIndexOf ( "id")! = -1 && tempMethod.getName (). substring (3) .length () == 2) {// ID 필드의 개체를 변수로 저장하고 컬렉션에서 삭제합니다. idmethod = tempmethod; iter.remove (); // 메소드 이름이 제거되고 set/get 문자열이 pojo + "id"(Case Insensitive)와 호환되지 않으면 id} else} else if ((entity.getClass (). getSimplename () + "id"). iter.remove (); }} // 반복 포인터를 첫 번째 위치 iter = list.iterator ()로 이동합니다. while (iter.hasnext ()) {tempMethod = iter.next (); sql + = tempMethod.getName (). substring (3) .tolowerCase () + "=?,"; } // 마지막 것, Sympl Sql = sql.substring (0, sql.lastIndexof ( ",")); // 조건 추가 // SQL 스 플라이 싱이 완료되면 SQL 문을 인쇄합니다. Out.println (SQL); preparedstatement 문 = this.connection.preparestatement (SQL); int i = 0; iter = list.iterator (); while (iter.hasnext ()) {메소드 메소드 = iter.next (); // 이것은 데이터베이스에 저장할 때 일부 필드 값 형식을 변경해야하기 때문에 처음에는 리턴 값을 결정합니다. 예를 들어 String, sql 문은 '+abc+"'if (method.getReturntype (). getSimplename (). indexof ("String ")! = -1) {reatestring (++ i, entertring (entergring, entertity i, entertity i)). } else if (method.getReturnType (). getSimplename (). indexof ( "date")! = -1) {state.setString (++ i, this.getString (method, entity)); } else if (method.getReturnType (). getSimplename (). indexof ( "date")! = -1) {state.setDate (++ i, this.getDate (method, entity)); } else if (method.getReturnType (). getSimplename (). indexof ( "inputStream")! = -1) {state.setAsciistream (++ i, this.getBlob (method, entity)), 1440); } else {state.setInt (++ i, this.getInt (메소드, 엔티티)); }} // if (idmethod.getReturntype (). getSimplename (). indexof ( "String")! = -1) {state.setString (++ i, this.getString (idmethod, entity)) if if if if id 필드에 값을 추가합니다. } else {state.setInt (++ i, this.getInt (idmethod, entity)); } // sql statement.executeUpdate ()를 실행합니다. // 사전 컴파일 된 객체 문을 닫습니다 .Close (); // connection.close ()를 닫습니다. } / ** * delete * / public void delete (t entity)는 예외 {string sql = "삭제" + entity.getClass (). getSimplename (). tolowercase () + "where"; // 문자열이있는 필드 객체를 저장 "id"메소드 idmethod = null; // 문자열 "ID"목록 <메소드> 목록 = this.MatchPoJomEthods (엔티티, "get")로 필드 객체를 가져옵니다. iterator <methob> iter = list.iterator (); while (iter.hasnext ()) {메소드 tempmethod = iter.next (); // 메소드 이름에 ID 문자열이 포함되어 있고 길이가 2 인 경우 ID로 간주됩니다. if (tempMethod.getName (). lastIndexOf ( "id")! = -1 && tempMethod.getName (). substring (3) .length () == 2) {// ID 필드의 개체를 변수로 저장하고 세트에서 삭제합니다. idmethod = tempmethod; iter.remove (); // 메소드 이름이 제거되고 Set/Get String이 pojo + "id"(Case Insensitive)와 호환되지 않으면 id} else} else ((entity.getClass (). getSimplename () + "id"). iter.remove (); }} sql + = idmethod.getName (). substring (3) .TOLOWERCASE () + "=?"; preparedstatement 문 = this.connection.preparestatement (SQL); // ID 필드에 값을 추가 int i = 0; if (idmethod.getReturntype (). getSimplename (). indexof ( "String")! = -1) {stater.setString (++ i, this.getString (idmethod, entity)); } else {state.setInt (++ i, this.getInt (idmethod, entity)); } // conn.execother (statement)를 실행합니다. // CloseConn (); } / *** query by id* / public t findByid (Object)는 예외 {string sql = "select* from" + persistentClass.getSimplename (). tolowercase () + "where"; // 서브 클래스의 생성자를 사용하여 매개 변수화 된 유형의 특정 유형을 얻습니다. 예를 들어, Bastao <t>, 즉, 특정 유형의 t entity = persistentClass.newinstance ()를 얻습니다. // pojo (또는 작동중인 테이블)의 기본 키를 저장하는 메소드 객체를 저장하십시오. 메소드 idmethod = null; List <method> list = this.matchpojomethods (엔티티, "세트"); iterator <methob> iter = list.iterator (); // 메소드 객체를 얻기 위해 필터 (iter.hasnext ()) {메소드 tempmethod = iter.next (); if (tempMethod.getName (). indexof ( "id")! = -1 && tempMethod.getName (). substring (3) .length () == 2) {idmethod = tempMethod; } else if ((entity.getClass (). getSimplename () + "id"). equalSignoreCase (tempMethod.getName (). substring (3))) {idmethod = tempMethod; }} // 첫 번째 문자는 소문자 sql += idmethod.getName (). substring (3,4) .TolowerCase () +idmethod.getName (). substring (4) +"=?"; // 캡슐화 명령문 후에 SQL 문 System.out.println (SQL)을 인쇄합니다. // 연결 대비 statement 문 = this.connection.preparestatement (SQL); // id 유형을 판단합니다 if (Object Instancef Insteger) {state.setint (1, (정수) 개체); } else if (object instancef string) {state.setString (1, (string) 객체); } // SQL을 실행하여 쿼리 결과 세트를 가져옵니다. resultSet rs = conn.execquery (문); // 등록, 레코드 루프는 필드 수 int i = 0; // 반복자 iter = list.iterator ()의 첫 번째 줄에 대한 포인터를 가리 킵니다. // acapulate while (rs.next ()) {while (iter.hasnext ()) {메소드 메소드 = iter.next (); if (method.getParameterTypes () [0] .getSimplename (). indexof ( "string")! = -1) {// 검색 할 메소드 객체의 순서는 데이터베이스 필드의 순서와 일치하지 않기 때문에 (예 : 첫 번째 메소드는 Database의 값)를 취합니다. 이름. this.setString (메소드, 엔티티, rs.getString (method.getName (). substring (3) .tolowercase ()); } else if (method.getParameterTypes () [0] .getSimplename (). indexof ( "date")! = -1) {this.setDate (메서드, 엔티티, rs.getDate (method.getName (). substring (3) .Tolowscase ()); } else if (method.getParameterTypes () [0] .getSimplename (). indexof ( "inputStream")! = -1) {this.setBlob (메서드, 엔티티, rs.getBrob (method.getName (). getBinaryStream ()); } else {this.setInt (메소드, 엔티티, rs.getInt (method.getName (). substring (3) .TOLOWERCASE ()); }}} // 결과 세트를 닫으십시오 Rs.Close (); // 사전 컴파일 된 객체 문을 닫습니다 .Close (); 리턴 엔티티; } /*** 현재 Pojo 클래스에서 들어오는 문자열로 모든 메소드 객체를 필터링하고 목록 컬렉션을 반환합니다. */private list <method> matchpojomethods (t entity, string methodname) {// 모든 현재 pojo 메소드 개체 메서드를 가져옵니다. 메소드 = entity.getClass (). getDeclaredMethods (); // 목록 컨테이너 저장 모든 메소드 객체가 get 문자열 목록 <방법> 목록 = new ArrayList <메소드> (); // 현재 pojo 클래스에서 Get 문자열로 모든 메소드 객체를 필터링하고 (int index = 0; index <methods.length; index ++) {if (method [index]. indexof (methodName)! = -1) {list.add (methods [index]); }} 리턴 목록; } /*** 유형이 int 또는 정수 일 때 메소드가 SQL 문 값을 반환합니다. get */ public integer getint (메소드 메소드, t 엔티티)에 해당하는 예외 {return (integer) method.invoke (entity, new Object [] {}); } /*** 메소드는 유형이 문자열 일 때 SQL 문 어셈블리 값을 반환합니다. 예를 들어, get */ public string getstring (메소드 메소드, t 엔티티)에 해당하는 'ABC'는 예외 {return (string) 메서드를 던집니다. } /***이 메소드는 Blob 유형 일 때 SQL 문단 조립 된 값을 반환합니다. get */ public inputStream getBlob (메소드 메소드, t 엔티티)에 해당하는 예외 {return (inputStream) method.invoke (엔티티, 새 개체 [] {}); } / ** * 메소드는 get * / public date getDate (메소드 메소드, t entity)에 해당하는 날짜 유형이 날짜 유형을 반환합니다. 예외 {return (date) method.invoke (entity, new Object [] {}); } / ** * 매개 변수 유형이 정수 또는 int 일 때, set * / public integer setInt (메소드 메소드, t 엔티티, 정수 arg)에 해당하는 엔티티 필드의 매개 변수를 설정합니다. 예외 {return (integer) method.invoke (Entity, new Object [] {arg}); } / ** * 매개 변수 유형이 문자열 인 경우, set * / public string setstring (메소드 메소드, t 엔티티, String arg)에 해당하는 엔티티 필드에 대한 매개 변수를 설정합니다. 예외 {return (string) method.invoke (엔티티, 새 개체 [] {arg}); } / ** * 매개 변수 유형이 inputStream 일 때, set * / public inputStream setBlob (메소드 메소드, t 엔티티, inputStream arg)에 해당하는 엔티티 필드에 대한 매개 변수를 설정합니다. 예외 {return (inputStream) method.invoke (entity, new Object [] {arg}); } / ** * 매개 변수 유형이 날짜 인 경우, set * / public date setDate (메소드 메소드, t 엔티티, 날짜 arg)에 해당하는 엔티티 필드의 매개 변수를 설정합니다. 예외 {return (date) method.invoke (엔티티, 새 개체 [] {arg}); }}Employeesdao는 Basedao를 상속하고 코드 재사용 추가를 추가하여 부모 클래스 메소드를 직접 사용할 수 있습니다.
package com.employees.dao; import java.util.arraylist; import java.util.list; import com.employees.po.employees; public class Employeesdao Extandao <plasection> {// Employee Public Boolean AddemployEES (최종 직원) 추가의 운영 (직원); 진실을 반환하십시오. } // 직원 정보 추가 테이블 공개 목록 <Scount> addemployees (int id)는 예외 {list <spection> lstemployees = new Arraylist <직원> (); 직원 직원 = FindByid (ID); // 현재 밀폐 된 데이터를 객체 lstemployees.add (직원)에로드합니다. lstemployees를 반환합니다. } public void deleteemp (최종 직원 엔티티)는 예외 {this.delete (Entity); } public void updateEmp (최종 직원 엔티티)는 예외를 던졌습니다. {this.update (Entity); }}PO 계층의 코드를 게시하지 않으므로 이제 Junit4를 사용하여 테스트를 수행하십시오.
package com.employees.dao; import org.junit.test; import com.employees.po.employees; 공개 클래스 Employepserdaotest {@test public void testadd () 예외 {Employep emp = new Employep (); emp.setpname ( "tly"); emp.setpsex ( "male"); emp.setpbeliefs ( "xxxxx"); emp.setpaddr ( "tianhe"); emp.setphobby ( "농구 놀이"); emp.setpsubject ( "컴퓨터"); emp.setptel ( "123456"); Employepsdao dao = 신입 사원 dao (); dao.addeployees (EMP); } @test public void testupdate ()는 예외를 겪고 {Employepsdao dao = 신입 사원 dao (); 직원 EMP = DAO.FINDBYID (14); emp.setptel ( "999999"); dao.updateemp (emp); } @test public void testdelete ()는 예외를 겪고 {Employepsdao dao = 신입 사원 dao (); 직원 EMP = DAO.FINDBYID (15); dao.deleteemp (EMP); }}테스트 후,이 세 가지 방법은 정상적으로 실행될 수 있으며 시간이 서두르고 있습니다. 일부 코드는 다른 친구가 사용합니다. 일부 장소는 매우 포괄적 인 것으로 간주되지 않거나 일부 코드는 중복됩니다. Basionao의 일반적인 CRUD 작업은 전액 작성되지 않았습니다. 친구가 관심이 있으시면 쿼리, 배치 작업 등과 같이 다시 쓸 수 있습니다. 테스트가 통과되면 사본을 보내야합니다.
위의 간단하고 일반적인 JDBC 보조 포장 (예)는 내가 공유하는 모든 콘텐츠입니다. 나는 당신이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.