Servlet開發搭建

勿以惡小而爲之,勿以善小而不爲--------------------------劉備

勸諸君,多行善事積福報,莫作惡

搭建一個基本的 Servlet 開發框架,便於後續地快速開發。只適用於 Servlet 階段。

特點: 自定義的 BaseDao,BaseDaoImpl,BaseServlet, 用 beanutils 來封裝前臺傳入參數。

一. 添加 jar包

Maven 依賴的形式,添加相應的依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.yjl.project</groupId>
  <artifactId>Servlet_Dev</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
  <properties>
		<!-- 配置java的版本 -->
		<java.version>1.8</java.version>
		<!-- mysql的版本 -->
		<mysql.version>5.1.32</mysql.version>
		<!-- 配置junit的版本 -->
		<junit.version>4.12</junit.version>
		<!-- 配置servlet的版本 -->
		<servlet.version>3.1.0</servlet.version>

	</properties>
  
  <dependencies>
  
  		<!-- junit 依賴 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<!--tomcat中 jsp與 servlet依賴 -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>
		<!-- jstl 與 standard 依賴-->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<!-- 文件上傳 的依賴-->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- 日誌依賴-->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.22</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.25</version>
		</dependency>
		
		<!-- mysql依賴 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<!-- c3p0依賴 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>		
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.2</version>
		</dependency>
  </dependencies>
  <build>
  	<plugins>
			<!-- 編譯的jdk版本 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<!--tomcat的插件名, tomcat7-maven-plugin, 用的是tomcat7版本 -->
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<port>8080</port>  <!--tomcat的端口號 -->
					<path>/Servlet_Dev</path> <!--tomcat的項目名 -->
					<uriEncoding>UTF-8</uriEncoding> <!-- 防止get 提交時亂碼 -->
				</configuration>
			</plugin>
		</plugins>
  </build>
</project>

也可以 放置 jar包。 所用到的jar包有:

有圖片

二. 讀取 jdbc.properties 數據庫配置和 DBUtils 工具類

二.一 數據庫配置文件

在 src 目錄下,放置一個 jdbc.properties 數據庫配置文件信息。

#數據庫的配置
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/rbac?characterEncoding=UTF-8
username=root
password=abc123

當修改數據庫的時候,只需要修改 jdbc.properties 的配置信息即可。

二.二 DBProperties 數據庫屬性

package com.yjl.utils;

import java.io.IOException;
import java.util.Properties;
/**
 * 
 * @author 兩個蝴蝶飛
 *
 *用於讀取數據庫的配置信息
 */
public class DBProperties {
	
	private static String DRIVER_CLASS;
	private static String URL;
	private static String USERNAME;
	private static String PASSWORD;
    static{
		
		 //創建Properties對象
		Properties pro = new Properties();
		try {
			pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties"));
		} catch (IOException e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
		}
		DRIVER_CLASS = pro.getProperty("driverClass");
		URL = pro.getProperty("url");
		USERNAME = pro.getProperty("username");
		PASSWORD = pro.getProperty("password");
	}

	public static String getDRIVER_CLASS() {
		return DRIVER_CLASS;
	}

	public void setDRIVER_CLASS(String dRIVER_CLASS) {
		DRIVER_CLASS = dRIVER_CLASS;
	}

	public static String getURL() {
		return URL;
	}

	public void setURL(String uRL) {
		URL = uRL;
	}

	public static String getUSERNAME() {
		return USERNAME;
	}

	public void setUSERNAME(String uSERNAME) {
		USERNAME = uSERNAME;
	}

	public static String getPASSWORD() {
		return PASSWORD;
	}

	public void setPASSWORD(String pASSWORD) {
		PASSWORD = pASSWORD;
	}
	
	public static void main(String []args){
		System.out.println(DBProperties.getUSERNAME());
	}
}

二.三 DBUtils 工具類

用於開啓和關閉數據庫連接

package com.yjl.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 
 * @author 兩個蝴蝶飛
 * 
 * 數據庫連接的工具
 *
 */
public class DBUtils {
	/**
	 * 加載驅動 創建連接
	 */
	public static Connection getConnection() {
		Connection conn=null;
		try {
			Class.forName(DBProperties.getDRIVER_CLASS());
			conn = DriverManager.getConnection(DBProperties.getURL(),
					DBProperties.getUSERNAME(), DBProperties.getPASSWORD());
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return conn;
	}

	/**
	 * 關閉jdbc資源
	 */
	public  static void closeAll(ResultSet rs, PreparedStatement ptmt, Connection conn) {
		try {
			if (rs != null) {
				rs.close();
			}
			if (ptmt != null) {
				ptmt.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

三. 數據庫 BaseDao 和 BaseDaoImpl

採用泛型的形式,進行開發。

三.一 BaseDao

package com.yjl.utils;

import java.util.List;

/**
 * 
 @Description 基本的dao類型轉換
*/
public interface BaseDao<T> {
	/**
	 * 插入實體
	 * @param sql  sql語句
	 * @param params 插入參數,可變參數形式
	 * @return 返回插入的條數
	 */
	public int insertEntity(String sql,Object...params);
	/**
	 * 插入實體
	 * @param sql  sql語句
	 * @param params 插入參數,集合形式
	 * @return 返回插入的條數
	 */
	public int insertEntity(String sql,List<Object> params);
	/**
	 * 根據id刪除實體
	 * @param sql 刪除語句
	 * @param id 刪除的編號id
	 * @return 返回刪除的條數
	 */
	public int deleteById(String sql,int id);
	/**
	 * 根據某一屬性值進行刪除
	 * @param sql 刪除的sql語句,不需要寫where 語句。
	 * @param name 依據刪除的屬性
	 * @param params 參數
	 * @return 返回刪除的條數
	 */
	public int deleteByNameAndValue(String sql,String name,Object params);
	/**
	 * 根據sql語句進行刪除
	 * @param sql 刪除的sql語句,需要寫where 語句
	 * @param params 傳入參數,可變參數的形式
	 * @return 返回刪除的條數
	 */
	public int deleteBySql(String sql,Object ... params);
	/**
	 * 根據sql語句進行刪除
	 * @param sql 刪除的sql語句,需要寫where 語句
	 * @param params 傳入參數,集合的形式
	 * @return 返回刪除的條數
	 */
	public int deleteBySql(String sql,List<Object> params);
	/**
	 * 根據sql語句,進行更新
	 * @param sql 更新的sql語句
	 * @param params 傳入參數,可變參數的形式
	 * @return 返回更新的條數
	 */
	public int updateEntity(String sql,Object ... params);
	/**
	 * 根據sql語句,進行更新
	 * @param sql 更新的sql語句
	 * @param params 傳入參數,集合的形式
	 * @return 返回更新的條數
	 */
	public int updateEntity(String sql,List<Object> params);
	/**
	 * 根據id進行查詢
	 * @param sql 查詢的語句,需要where 語句
	 * @param id id編號
	 * @return 返回查詢出來的唯一一條記錄
	 */
	public T getInfoById(String sql,int id);
	/**
	 * 根據某一屬性進行查詢
	 * @param sql 查詢的語句,不需要where 語句
	 * @param name 查詢的屬性
	 * @param params 參數
	 * @return 返回查詢出來的唯一一條記錄,如果有多條,則只返回第一條。
	 */
	public T getInfoByNameAndValue(String sql,String name,Object params);
	/**
	 * 根據sql語句進行查詢
	 * @param sql 查詢的語句,需要where 語句
	 * @param params 參數, 可變參數的形式
	 * @return 返回查詢出來的唯一一條記錄,如果有多條,則只返回第一條
	 */
	public T getInfoBySql(String sql,Object ...params);
	/**
	 * 根據sql語句進行查詢
	 * @param sql 查詢的語句,需要where 語句
	 * @param params 參數,集合的形式
	 * @return 返回查詢出來的唯一一條記錄,如果有多條,則只返回第一條
	 */
	public T getInfoBySql(String sql,List<Object> params);
	
	/**
	 * 根據某一屬性 進行查詢多條記錄
	 * @param sql 查詢的語句 ,不需要where 語句
	 * @param name 屬性
	 * @param params 參數值
	 * @return 返回查詢出來的多條記錄
	 */
	
	public List<T> findInfosByNameAndValue(String sql,String name,Object params);
	/**
	 * 根據sql語句查詢多條記錄
	 * @param sql sql語句,需要where 語句
	 * @param params 參數, 可變參數的形式
	 * @return 返回查詢出來的多條記錄
	 */
	public List<T> findInfosBySql(String sql,Object ...params);
	/**
	 * 根據sql語句查詢多條記錄
	 * @param sql sql語句,需要where 語句
	 * @param params 參數, 集合的形式
	 * @return 返回查詢出來的多條記錄
	 */
	public List<T> findInfosBySql(String sql,List<Object> params);
	/**
	 * 根據sql語句查詢多條記錄
	 * @param sql sql語句,不傳入篩選條件
	 * @return 返回查詢出來的多條記錄
	 */
	public List<T> findAll(String sql);
	/**
	 * 根據 sql語句的id,查詢出多條記錄
	 * @param sql sql語句
	 * @param ids id的可變參數形式
	 * @return 返回根據ids查詢出來的多條記錄
	 */
	public List<T> findInfosByIds(String sql,Object ... ids);
	/**
	 * 根據 sql語句的id,查詢出多條記錄
	 * @param sql sql語句
	 * @param ids id的集合形式
	 * @return 返回根據ids查詢出來的多條記錄
	 */
	public List<T> findInfosByIds(String sql,List<Object> ids);
	/**
	 * 根據 sql語句的任一屬性,查詢出多條記錄
	 * @param sql sql語句
	 * @param params names的可變參數形式
	 * @return 返回根據names 查詢出來的多條記錄
	 */
	public List<T> findInfosByNames(String sql,Object ...params);
	/**
	 * 根據 sql語句的任一屬性,查詢出多條記錄
	 * @param sql sql語句
	 * @param params names的 集合形式
	 * @return 返回根據names 查詢出來的多條記錄
	 */
	public List<T> findInfosByNames(String sql,List<Object> params);
	/**
	 * 分頁查詢 記錄
	 * @param sql sql語句,不需要寫 limit 語句
	 * @param params 參數,集合的形式
	 * @param currentPage 當前頁
	 * @param pageSize 頁所顯示的記錄數
	 * @return 返回 當前頁的記錄
	 */
	public List<T> pageInfosBySql(String sql,List<Object> params,int currentPage,int pageSize);
	/**
	 * 分頁查詢 記錄
	 * @param sql sql語句,不需要寫 limit 語句
	 * @param currentPage 當前頁
	 * @param pageSize 頁所顯示的記錄數
	 * @param params 參數,可變參數的形式
	 * @return 返回 當前頁的記錄
	 */
	public List<T> pageInfosBySql(String sql,int currentPage,int pageSize,Object ...params);
	/**
	 * 統計總數
	 * @param sql sql語句
	 * @return 返回總的記錄數
	 */
	public int count(String sql);
	/**
	 * 統計總數
	 * @param sql sql語句
	 * @param params 參數, 可變參數的形式
	 * @return 返回總的記錄數 
	 */
	public int count(String sql,Object ... params);
	/**
	 * 統計總數
	 * @param sql sql語句
	 * @param params 參數, 集合的形式
	 * @return 返回總的記錄數 
	 */
	public int count(String sql,List<Object> params);
	
	
}

三.二 BaseDaoImpl

package com.yjl.utils;

import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 @Description BaseDao實現類
*/
@SuppressWarnings("all")
public class BaseDaoImpl<T> implements BaseDao<T> {
	
	private T t;
	private Class clazz;
	private Object obj;
	public BaseDaoImpl() {
		//得到當前的類
		Class class1=this.getClass();
		//得到運行中的父類
		ParameterizedType parameterizedType=(ParameterizedType) class1.getGenericSuperclass();
		clazz=(Class) parameterizedType.getActualTypeArguments()[0];
		try {
			t=(T) clazz.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println("當前類的類:"+clazz.getName()+"完成初始化");
	}
	
	public BaseDaoImpl(Class cla) {
		clazz=cla;
		try {
			t=(T) clazz.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println("當前類的類:"+clazz.getName()+"完成初始化");
	}

	@Override
	public int insertEntity(String sql, Object... params) {
		return executeUpdate(sql, params);
	}

	@Override
	public int insertEntity(String sql, List<Object> params) {
		if(params!=null&&params.size()>0){
			return executeUpdate(sql);
		}
		return executeUpdate(sql,params.toArray());
		
	}

	@Override
	public int deleteById(String sql, int id) {
		return executeUpdate(sql,id);
	}

	@Override
	public int deleteByNameAndValue(String sql, String name, Object params) {
		String newSql=sql+" where "+name+" =?";
		return executeUpdate(newSql,params);
	}

	@Override
	public int deleteBySql(String sql, Object... params) {
		return executeUpdate(sql,params);
	}

	@Override
	public int deleteBySql(String sql, List<Object> params) {
		if(params!=null&&params.size()>0){
			return executeUpdate(sql);
		}
		return executeUpdate(sql,params.toArray());
	}

	@Override
	public int updateEntity(String sql, Object... params) {
		return executeUpdate(sql,params);
	}

	@Override
	public int updateEntity(String sql, List<Object> params) {
		if(params!=null&&params.size()>0){
			return executeUpdate(sql);
		}
		return executeUpdate(sql,params.toArray());
	}

	@Override
	public T getInfoById(String sql, int id) {
		return executeQuery(sql,id);
	}

	@Override
	public T getInfoByNameAndValue(String sql, String name, Object params) {
		String newSql=sql+" where "+name+" = ?";
		return executeQuery(newSql,params);
	}

	@Override
	public T getInfoBySql(String sql, Object... params) {
		return executeQuery(sql,params);
	}

	@Override
	public T getInfoBySql(String sql, List<Object> params) {
		if(params!=null&&params.size()>0){
			return executeQuery(sql);
		}
		return executeQuery(sql,params.toArray());
	}

	@Override
	public List<T> findInfosByNameAndValue(String sql, String name, Object params) {
		String newSql=sql+" where "+name+" =?";
		return executeListQuery(newSql,params);
	}

	@Override
	public List<T> findInfosBySql(String sql, Object... params) {
		return executeListQuery(sql,params);
	}

	@Override
	public List<T> findInfosBySql(String sql, List<Object> params) {
		if(params!=null&&params.size()>0){
			return executeListQuery(sql);
		}
		return executeListQuery(sql,params.toArray());
	}

	@Override
	public List<T> findAll(String sql) {
		return executeListQuery(sql);
	}

	@Override
	public List<T> findInfosByIds(String sql, Object... ids) {
		String newSql=sql+inSuffix(ids);
		return executeListQuery(newSql,ids);
	}

	@Override
	public List<T> findInfosByIds(String sql, List<Object> ids) {
		String newSql=sql+inSuffix(ids.toArray());
		return executeListQuery(newSql,ids);
	}
	@Override
	public List<T> findInfosByNames(String sql, Object... params) {
		String newSql=sql+inSuffix(params);
		return executeListQuery(newSql,params);
	}

	@Override
	public List<T> findInfosByNames(String sql, List<Object> params) {
		String newSql=sql+inSuffix(params.toArray());
		return executeListQuery(newSql,params);
	}
	//拼接in語句
	private String inSuffix(Object... params){
		StringBuilder  newSql=new StringBuilder("( ");
		for(int i=0;i<params.length;i++){
			if(i==params.length-1){
				newSql.append("?");
			}else{
				newSql.append("?,");
			}
			
		}
		newSql.append(" ) ");
		return newSql.toString();
	}
	
	private int getStart(int currentPage,int pageSize){
		return currentPage*(pageSize-1);
	}
	@Override
	public List<T> pageInfosBySql(String sql, List<Object> params, int currentPage, int pageSize) {
		String newSql=sql+" limit ?,?";
		params.add(getStart(currentPage,pageSize));
		params.add(pageSize);
		return executeListQuery(newSql,params.toArray());
	}
	@Override
	public List<T> pageInfosBySql(String sql, int currentPage, int pageSize, Object... params) {
		String newSql=sql+" limit ?,?";
		return executeListQuery(newSql,params,getStart(currentPage,pageSize),pageSize);
	}

	@Override
	public int count(String sql) {
		return countQuery(sql);
	}

	@Override
	public int count(String sql, Object... params) {
		return countQuery(sql,params);
	}

	@Override
	public int count(String sql, List<Object> params) {
		return countQuery(sql,params.toArray());
	}
	
	/**
	 * 將所有的更新操作全部放置在此方法中 不同:參數類型相同 ,值不同 通過傳入參數解決
	 * 
	 * @param sql
	 * 佔位符賦值 ?個數不同,?內值類型不同 數組 object
	 * @return
	 */
	protected int executeUpdate(String sql, Object ... params) {
		int num = -1;
		Connection conn =DBUtils.getConnection();
		PreparedStatement ptmt=null;
		ResultSet rs=null;
		try {
			ptmt = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ptmt.setObject(i + 1, params[i]);
				}
			}
			num = ptmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(rs, ptmt, conn);
		}
		return num;
	}
	/**
	 * 通過語句和佔位符的值查詢得到返回結果值
	 * 
	 * @param sql
	 * @param params
	 * @return 返回查詢後的結果集
	 */
	protected int countQuery(String sql, Object ... params) {
		Connection conn =DBUtils.getConnection();
		PreparedStatement ptmt=null;
		ResultSet rs=null;
		Object singleInfo=null;
		int count=0;
		try {
			ptmt = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ptmt.setObject(i + 1, params[i]);
				}
			}
			rs = ptmt.executeQuery();
			if(rs.next()){
				Number c=rs.getLong(1);
				count=c.intValue();
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(rs, ptmt, conn);
		}
		return count;
	}
	/**
	 * 通過語句和佔位符的值查詢得到返回結果值
	 * 
	 * @param sql
	 * @param params
	 * @return 返回查詢後的結果集
	 */
	protected T executeQuery(String sql, Object ... params) {
		Connection conn =DBUtils.getConnection();
		PreparedStatement ptmt=null;
		ResultSet rs=null;
		Object singleInfo=null;
		try {
			ptmt = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ptmt.setObject(i + 1, params[i]);
				}
			}
			rs = ptmt.executeQuery();
			
			singleInfo=ResultSetToBean.getObj(rs,t.getClass());
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(rs, ptmt, conn);
		}
		if(singleInfo!=null){
			return (T)singleInfo;
		}else{
			return null;
		}
		
	}
	protected List<T> executeListQuery(String sql, Object ... params) {
		Connection conn =DBUtils.getConnection();
		PreparedStatement ptmt=null;
		ResultSet rs=null;
		Object listInfo=null;
		try {
			ptmt = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					ptmt.setObject(i + 1, params[i]);
				}
			}
			rs = ptmt.executeQuery();
			
			listInfo=ResultSetToBean.getList(rs,t.getClass());
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DBUtils.closeAll(rs, ptmt, conn);
		}
		if(listInfo!=null){
			return (List<T>) listInfo;
		}else{
			return null;
		}
		
	}
}

三.三 ResultSet 轉換成 JavaBean

package com.yjl.utils;
/**
 * 利用反射機制從ResultSet自動綁定到JavaBean:
 * 要求:JavaBean的字段和ResultSet的字段名或 別名 一樣(不區分大小寫)
 *     注意:如果JavaBean的字段和數據庫表的字段名不一樣,那麼在查詢語句中使用對應的別名即可!
 * 
 * 用到的是jdbc進行對數據庫查詢,這裏是根據JavaBean中的屬性名進行查詢的,
 * 所以屬性名要和字段名一致,
 * 然後再利用反射,將表字段映射到JavaBean中對應的屬性。
 */
 
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
public class ResultSetToBean {
 
    /**
     * 獲取結果集的所有結果,存放到ArrayList裏
     * 
     * @param rs 查詢結果,ResultSet
     * @param clazz JavaBean類型,如Article.class
     * @return ArrayList,存放映射後的JavaBean對象
     */
    public static <T> List<T> getList(ResultSet rs, Class<T> clazz) {
        // 獲取JavaBean裏面的所有屬性
        Field[] field = clazz.getDeclaredFields();
        T obj = null;
        // 創建list容器,存放映射後的JavaBean對象
        List<T> list = new ArrayList<T>();
        try {
            ResultSetMetaData rsmd = rs.getMetaData();  
            // 獲取記錄集中的列數  
            int counts = rsmd.getColumnCount();  
            // 定義counts個String 變量  
            String[] columnNames = new String[counts];  
            // 給每個變量賦值(字段名稱全部轉換成大寫)  
            for (int i = 0; i < counts; i++) {  
                // getColumnLabel() 取別名(如有) 即SQL AS的值
                // getColumnName() 取字段名:
                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase(); 
            } 
            List<String> columnNameList = Arrays.asList(columnNames);
            // System.out.println(columnNameList);
            // 開始遍歷查詢結果
            while (rs.next()) {
                // 創建Javabean對象
                obj = clazz.newInstance();
                // 循環將查詢結果寫入對應的JavaBean屬性中
                for (Field f : field) {
                    // 獲取該字段名稱
                    String name = f.getName();
                    // 判斷該字段是否在ResultSet的字段裏,在的話纔去進行賦值操作
                    // 如果不進行判斷的話,在JavaBean字段比ResultSet字段多的情況下,會拋異常
                    if(columnNameList.contains(name.toUpperCase())) {
                        // 判斷是否查詢到對應的值
                        if (rs.getObject(name) != null) {
                        	
                        	Object newObj=rs.getObject(name);
                        	
                        	if(newObj instanceof java.sql.Date){
                        		java.sql.Date sqlD=(java.sql.Date)newObj;
                        		
                        		java.util.Date utilD=new java.util.Date(sqlD.getTime());
                        		newObj=utilD;
                        	}
                        	if(newObj instanceof java.lang.Long){
                        		Long lD=(Long)newObj;
                        		int iD=lD.intValue();
                        		newObj=iD;
                        	}
                            // 跳過檢查,這裏訪問的時私有屬性
                            f.setAccessible(true);
                            // 將查詢到的值付給對應的屬性
                            f.set(obj, newObj);
                        }
                    } 
                }
                // 把結果的每一列都添加到list中
                list.add(obj);
            }
        } catch (SQLException e) {
            System.err.println("結果集遍歷失敗");
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("數據讀取失敗");
            e.printStackTrace();
        }
        return list;
    }
    
    /**
     * 只取結果集的第一條結果
     * 
     * @param rs 查詢結果,ResultSet
     * @param clazz JavaBean類型,如Article.class
     * @return JavaBean對象
     */
    public static <T> T getObj(ResultSet rs, Class<T> clazz) {
        //Class<T> clazz = (Class<T>) t.getClass();
        // 獲取JavaBean裏面的所有屬性
        Field[] field = clazz.getDeclaredFields();
        T obj = null;
        try {
            ResultSetMetaData rsmd = rs.getMetaData();  
            // 獲取記錄集中的列數  
            int counts = rsmd.getColumnCount();  
            // 定義counts個String 變量  
            String[] columnNames = new String[counts];  
            // 給每個變量賦值(字段名稱全部轉換成大寫)  
            for (int i = 0; i < counts; i++) {  
                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase(); 
            } 
            List<String> columnNameList = Arrays.asList(columnNames);
            // System.out.println(columnNameList);
            
            // 獲取第一條記錄
            if (rs.next()) {
                // 創建Javabean對象
                obj = clazz.newInstance();
                // 循環將查詢結果寫入對應的JavaBean屬性中
                for (Field f : field) {
                    // 獲取該字段名稱
                    String name = f.getName();
                    // 判斷該字段是否在ResultSet的字段裏,在的話纔去進行賦值操作
                    if(columnNameList.contains(name.toUpperCase())) {
                        // 判斷是否查詢到對應的值
                        if (rs.getObject(name) != null) {
                        	
                        	Object newObj=rs.getObject(name);
                        	if(newObj instanceof java.sql.Date){
                        		java.sql.Date sqlD=(java.sql.Date)newObj;
                        		
                        		java.util.Date utilD=new java.util.Date(sqlD.getTime());
                        		newObj=utilD;
                        	}
                        	if(newObj instanceof java.lang.Long){
                        		
                        		Long lD=(Long)newObj;
                        		int iD=lD.intValue();
                        		newObj=iD;
                        	}
                            // 跳過檢查,這裏訪問的時私有屬性
                            f.setAccessible(true);
                            // 將查詢到的值付給對應的屬性
                            f.set(obj, newObj);
                        }
                    } 
                }
            }
        } catch (SQLException e) {
            System.err.println("結果集操作失敗");
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("數據讀取失敗");
            e.printStackTrace();
        }
        return obj;
    }
}

四. BaseServlet

自己編寫的 Servlet, 需要繼承 BaseServlet.

prefix 和 suffix 是跳轉的jsp 的配置信息。

package com.yjl.utils;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
/**
 * 通用的servlet
 * @author 兩個蝴蝶飛
 *
 */
@SuppressWarnings("all")
public class BaseServlet extends HttpServlet {
	//定義前綴
	private static String prefix;
	//定義後綴
	private static String suffix;
	{
		prefix="/WEB-INF/pages/";
		suffix=".jsp";
	}
	/**
	 * 提交請求  執行方法時, User?method=login, 參數需要寫 req,resp
	 * 		 跳轉到某個頁面, User?jsp=toLogin, 參數不需要寫 req,resp
	 */
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			req.setCharacterEncoding("utf-8");
			
			//標識 0是方法,1是界面 2 是默認
			int flag=0;
			String method = req.getParameter("method");
			//判斷如果method爲空
			if(method == null) {
				method=req.getParameter("jsp");
				if(method==null){
					method = "execute";
					flag=2;
				}else{
					flag=1;
				}
			}
			//得到當前請求的servlet,當前運行的類,得到UserServlet類的Class
			Class clazz = this.getClass();
			
			String result="";
			
			if(flag==0||flag==2){
				//根據得到傳遞過來的名稱,讓名稱對應的方法去執行
				Method m1 = clazz.getMethod(method, HttpServletRequest.class,HttpServletResponse.class);
				//讓方法執行
				result= (String) m1.invoke(clazz.newInstance(), req,resp);
			}else if(flag==1){
				//根據得到傳遞過來的名稱,讓名稱對應的方法去執行
				Method m1 = clazz.getMethod(method);
				//讓方法執行
				result= (String) m1.invoke(clazz.newInstance());
			}else{
				//是默認的
				result="";
			}
			if(result != null) {
				//轉發操作
				if(result.indexOf("?method=")==-1){
					result=prefix+result+suffix;  
				}
				req.getRequestDispatcher(result).forward(req, resp);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	/**
	 * 將指定Java對象轉爲json,並響應到客戶端頁面
	 * @param o
	 * @param exclueds
	 */
	public void java2Json(HttpServletResponse resp,Object o ,String[] exclueds){
		JsonConfig jsonConfig = new JsonConfig();
		//指定哪些屬性不需要轉json
 		jsonConfig.setExcludes(exclueds);
		JSONObject objData=JSONObject.fromObject(o,jsonConfig);
		JSONObject objMap=new JSONObject();
		objMap.put("data",objData);
		objMap.put("status",true);
		resp.setContentType("text/json;charset=utf-8");
		try {
			resp.getWriter().print(objMap.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 將指定Java對象轉爲json,並響應到客戶端頁面
	 * @param o
	 * @param exclueds
	 */
	public void java2Json(HttpServletResponse resp,List o ,String[] exclueds){
		JsonConfig jsonConfig = new JsonConfig();
		//指定哪些屬性不需要轉json
		jsonConfig.setExcludes(exclueds);
		JSONArray objData=JSONArray.fromObject(o,jsonConfig);
		JSONObject objMap=new JSONObject();
		objMap.put("data",objData);
		objMap.put("status",true);
		resp.setContentType("text/json;charset=utf-8");
		try {
			resp.getWriter().print(objMap.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 將狀態返回到前臺,通常是添加,刪除,更新的操作,如果錯誤,則傳入錯誤代碼。
	 * @param o
	 * @param exclueds
	 */
	public void map2Json(HttpServletResponse resp,String ... code){
		JsonConfig jsonConfig = new JsonConfig();
		//指定哪些屬性不需要轉json
		JSONObject objMap=new JSONObject();
		if(code==null||code.length<1){
			objMap.put("status",true);
		}else{
			objMap.put("status",false);
			objMap.put("error_code",code[0]);
		}
		resp.setContentType("text/json;charset=utf-8");
		try {
			resp.getWriter().print(objMap.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 傳入是否成功,只返回狀態
	 * @param o
	 * @param exclueds
	 */
	public void boolean2Json(HttpServletResponse resp,boolean flag){
		JsonConfig jsonConfig = new JsonConfig();
		//指定哪些屬性不需要轉json
		JSONObject objMap=new JSONObject();
		objMap.put("status",true);
		objMap.put("flag",flag);
		resp.setContentType("text/json;charset=utf-8");
		try {
			resp.getWriter().print(objMap.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 將請求的參數,轉換成相應的 JavaBean 
	 * @param req
	 * @param clazz
	 * @return
	 */
	public <T> T reqParamToBean(HttpServletRequest req,Class <T> clazz){
		T t=null;
		try {
			t = clazz.newInstance();
			Map<String ,String []> paramMap=req.getParameterMap();
			BeanUtils.populate(t,paramMap);
		} catch (Exception e) {
			// TODO 自動生成的 catch 塊
			e.printStackTrace();
		}
		
		return t;
	}
	
	
	public String getPrefix() {
		return prefix;
	}
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
	public String getSuffix() {
		return suffix;
	}
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}
	
	
}

五. 開發過程舉例

以 User 信息進行相應的舉例.

結構信息如下所示:

有圖片

五.一 pojo 下的 User.java

package com.yjl.pojo;

/**
 * 
 * @author 兩個蝴蝶飛
 * 員工表, 放置實體
 *
 */
public class User {
/**
 * @param id id編號
 * @param code 員工編號
 * @param name 員工姓名
 * @param password 密碼
 */
  private Integer id;
  private String code;
  private String name;
  private String password;

  //實現setter 和getter方法
  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }


  public String getCode() {
    return code;
  }

  public void setCode(String code) {
    this.code = code;
  }


  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }


  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }
  //實現toString() 方法
	@Override
	public String toString() {
		return "User [id=" + id + ", code=" + code + ", name=" + name + ", password=" + password + "]";
	}
  
}

五.二 開發 Dao層

五.二.一 創建 UserDao

package com.yjl.dao;

import com.yjl.pojo.User;
import com.yjl.utils.BaseDao;
/**
 * 
 * @author 兩個蝴蝶飛
 * User 的接口, 可以擴展 BaseDao 裏面沒有的方法
 */
public interface UserDao extends BaseDao<User>{

}

五.二.二 實現 UserDaoImpl

package com.yjl.dao.impl;

import com.yjl.dao.UserDao;
import com.yjl.pojo.User;
import com.yjl.utils.BaseDaoImpl;

/**
 * 
 * @author 兩個蝴蝶飛
 * 放置 dao  實現類
 *
 */
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{

}

五.三 開發 service 層

五.三.一 創建 UserService

package com.yjl.service;

import com.yjl.pojo.User;
/**
 * 
 * @author 兩個蝴蝶飛
 * 業務邏輯驗證
 */
public interface UserService {

	public User login(User user);
}

五.三.二 實現UserServiceImpl

package com.yjl.service.impl;

import com.yjl.dao.UserDao;
import com.yjl.dao.impl.UserDaoImpl;
import com.yjl.pojo.User;
import com.yjl.service.UserService;
import com.yjl.utils.MD5Utils;

/**
 * 
 * @author 兩個蝴蝶飛
 * 業務驗證
 *
 */
public class UserServiceImpl implements UserService{
	//注入 userDao 對象
	private UserDao userDao;
	
	/**
	 * 舉例,登錄的方法
	 */
	@Override
	public User login(User user) {
		
		userDao=new UserDaoImpl();
		
		String sql="select * from user where code=? and password=? ";
		
		return userDao.getInfoBySql(sql,user.getCode(),MD5Utils.md5(user.getPassword()));
		
		
	}
}

五.四 開發 Servlet

package com.yjl.web.servlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.yjl.pojo.User;
import com.yjl.service.UserService;
import com.yjl.service.impl.UserServiceImpl;
import com.yjl.utils.BaseServlet;

/**
 * 
 * @author 兩個蝴蝶飛
 * 
 *  Servlet 控制器
 *
 */
@WebServlet("/User")
public class UserServlet extends BaseServlet{
	private static final long serialVersionUID = 1L;
	//注入UserService 對象
	private UserService userService;
	
	//跳轉到登錄頁面,是頁面,不需要req,resp對象 。  
	//訪問網址形式爲: /User?jsp=toLogin
	public String toLogin(){
		//完整的前綴和後綴,已經在 BaseServlet裏面定義好了
		return "login";
	}
	//具體的登錄方法, 需要接收數據,要req,resp對象。 
	public void login(HttpServletRequest req,HttpServletResponse resp){
		//將請求信息參數,封裝到對象裏面。
		User userInfo=super.reqParamToBean(req,User.class);
		//實例化service 對象
		userService=new UserServiceImpl();
		
		//從數據庫中查詢信息 
		User user=userService.login(userInfo);
		if(user!=null){
			//說明登錄成功
			HttpSession session=req.getSession();
			session.setAttribute("loginUser",user);
			super.boolean2Json(resp, true);
			
		}else{
			//代碼爲001,表示用戶名或者密碼錯誤
			 super.map2Json(resp,"001");
		}
	} 
	/**
	 * 
	 * 跳轉到登錄的頁面 
	 */
	public String toList(){
		return "user";
	}
}

五.五 測試

輸入網址: http://localhost:8080/Servlet_Dev/User?jsp=toLogin, 會跳轉到登錄的頁面

有圖片

輸入網址: localhost:8080/Servlet_Dev/User?method=login&code=1234&password=1234 ,會執行 login 的方法

有圖片

輸入網址:http://localhost:8080/Servlet_Dev/User?method=login&code=admin&password=1234, 會執行login的方法

有圖片

本章節代碼鏈接爲:


鏈接:https://pan.baidu.com/s/1Ove6HDywWcZDr9fRJO-LZg 
提取碼:q31l

謝謝您的觀看!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章