勿以惡小而爲之,勿以善小而不爲--------------------------劉備
勸諸君,多行善事積福報,莫作惡
搭建一個基本的 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&¶ms.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&¶ms.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&¶ms.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&¶ms.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&¶ms.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
謝謝您的觀看!!!