1. 程式人生 > >使用註解自動解釋orm,從而實現無xml配置的jdbc泛型介面dao,對資料庫單表增刪查改

使用註解自動解釋orm,從而實現無xml配置的jdbc泛型介面dao,對資料庫單表增刪查改

一、獲取資料庫連線和關閉資源

package cn.itdoer.base.utils.dao;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
/**
 * 提供獲取資料庫連線、釋放資源的介面
 */
public class JdbcDaoHelper {
	
	/**
	 * 資料庫使用者名稱
	 */
	private static final
String USER = "root"; /** * 資料庫密碼 */ private static final String PASSWORD = "123456"; /** * 連線資料庫的地址 */ private static final String URL = "jdbc:mysql://127.0.0.1:3306/visual_dev?useUnicode=true&characterEncoding=utf-8"; private static Connection conn; /** * 獲得一個數據庫連線物件 * @return java.sql.Connection例項 */
public static Connection getConnection() { try { if (conn == null) { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(URL, USER, PASSWORD); } else { return conn; } } catch (Exception e) { e.printStackTrace(); } return conn; } /** * 釋放資料庫資源 */
public static void release(PreparedStatement ps,ResultSet rs) { try { if (conn != null) { conn.close(); conn = null; } if (ps != null) { ps.close(); ps = null; } if (rs != null) { rs.close(); rs = null; } } catch (SQLException e) { e.printStackTrace(); } } }

二、建立orm註解

package cn.itdoer.base.utils.dao.anno;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 資料庫表的的名稱
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
 
	/**
	 * 表名
	 */
	String value();
	
}



package cn.itdoer.base.utils.dao.anno;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 標識資料庫欄位的名稱
 * @author [email protected]
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
	
	/**
	 * 欄位名稱
	 */
	String value();
	
	/**
	 * 欄位的型別
	 * @return
	 */
	Class<?> type() default String.class;
	
	/**
	 * 欄位的長度
	 * @return
	 */
	int length() default 0;
 
}

package cn.itdoer.base.utils.dao.anno;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 標識資料庫欄位的ID
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Id {
 
	/**
	 * ID的名稱
	 * @return
	 */
	String value();
	
}

三、定義泛型介面

package cn.itdoer.base.utils.dao;
 
import java.util.List;
import java.util.Map;
 
public interface GenericDao<T> {
	
	public void save(T t) throws Exception;
	
	public void delete(Object id,Class<T> clazz) throws Exception;
	
	public void update(T t) throws Exception;
	
	public T get(Object id,Class<T> clazz) throws Exception;
	
	/**
	 * 根據條件查詢
	 * @param sqlWhereMap key:條件欄位名 value:條件欄位值
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public List<T> findAllByConditions(Map<String,Object> sqlWhereMap,Class<T> clazz) throws Exception;
	
}

四、實現泛型介面

package cn.itdoer.base.utils.dao;
 
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import cn.itdoer.base.utils.dao.anno.Column;
import cn.itdoer.base.utils.dao.anno.Entity;
import cn.itdoer.base.utils.dao.anno.Id;
import cn.itdoer.base.utils.dao.excep.NotFoundAnnotationException;
 
/**
 * 泛型DAO的JDBC實現
 * @author 
 * @version 1.0
 */
public class JdbcGenericDaoImpl<T> implements GenericDao<T> {
	
	//表的別名
	private static final String TABLE_ALIAS = "t";
 
	@Override
	public void save(T t) throws Exception {
		Class<?> clazz = t.getClass();
		//獲得表名
		String tableName = getTableName(clazz);
		//獲得欄位
		StringBuilder fieldNames = new StringBuilder();		//欄位名
		List<Object> fieldValues = new ArrayList<Object>();	//欄位值
		StringBuilder placeholders = new StringBuilder();	//佔位符
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			PropertyDescriptor pd = new PropertyDescriptor(field.getName(),t.getClass());
			if (field.isAnnotationPresent(Id.class)) {
				fieldNames.append(field.getAnnotation(Id.class).value()).append(",");
				fieldValues.add(pd.getReadMethod().invoke(t));
			} else if(field.isAnnotationPresent(Column.class)) {
				fieldNames.append(field.getAnnotation(Column.class).value()).append(",");
				fieldValues.add(pd.getReadMethod().invoke(t));
			}
			placeholders.append("?").append(",");
		}
		//刪除最後一個逗號
		fieldNames.deleteCharAt(fieldNames.length()-1);
		placeholders.deleteCharAt(placeholders.length()-1);
		
		//拼接sql
		StringBuilder sql = new StringBuilder("");
		sql.append("insert into ").append(tableName)
		   .append(" (").append(fieldNames.toString())
		   .append(") values (").append(placeholders).append(")") ;
		PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql.toString());
		//設定SQL引數佔位符的值
		setParameter(fieldValues, ps, false);
		//執行SQL
		ps.execute();
		JdbcDaoHelper.release(ps, null);
		
		System.out.println(sql + "\n" + clazz.getSimpleName() + "新增成功!");
	}
 
 
	@Override
	public void delete(Object id,Class<T> clazz) throws Exception {
		//獲得表名
		String tableName = getTableName(clazz);
		//獲得ID欄位名和值
		String idFieldName = "";
		boolean flag = false;
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if(field.isAnnotationPresent(Id.class)) {
				idFieldName = field.getAnnotation(Id.class).value();
				flag = true;
				break;
			}
		}
		if (!flag) {
			throw new NotFoundAnnotationException(clazz.getName() + " object not found id property.");
		}
		
		//拼裝sql
		String sql = "delete from " + tableName + " where " + idFieldName + "=?";
		PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql);
		ps.setObject(1, id);
		//執行SQL
		ps.execute();
		JdbcDaoHelper.release(ps,null);
		
		System.out.println(sql + "\n" + clazz.getSimpleName() + "刪除成功!");
	}
 
	@Override
	public void update(T t) throws Exception {
		Class<?> clazz = t.getClass();
		//獲得表名
		String tableName = getTableName(clazz);
		//獲得欄位
		List<Object> fieldNames = new ArrayList<Object>();	//欄位名
		List<Object> fieldValues = new ArrayList<Object>();	//欄位值
		List<String> placeholders = new ArrayList<String>();//佔位符
		String idFieldName = "";
		Object idFieldValue = "";
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			PropertyDescriptor pd = new PropertyDescriptor(field.getName(),t.getClass());
			if (field.isAnnotationPresent(Id.class)) {
				idFieldName = field.getAnnotation(Id.class).value();
				idFieldValue = pd.getReadMethod().invoke(t);
			} else if(field.isAnnotationPresent(Column.class)) {
				fieldNames.add(field.getAnnotation(Column.class).value());
				fieldValues.add(pd.getReadMethod().invoke(t));
				placeholders.add("?");
			}
		}
		//ID作為更新條件,放在集合中的最後一個元素
		fieldNames.add(idFieldName);
		fieldValues.add(idFieldValue);
		placeholders.add("?");
		
		//拼接sql
		StringBuilder sql = new StringBuilder("");
		sql.append("update ").append(tableName).append(" set ");
		int index = fieldNames.size() - 1;
		for (int i = 0; i < index; i++) {
			sql.append(fieldNames.get(i)).append("=").append(placeholders.get(i)).append(",");
		}
		sql.deleteCharAt(sql.length()-1).append(" where ").append(fieldNames.get(index)).append("=").append("?");
		
		//設定SQL引數佔位符的值
		PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql.toString());
		setParameter(fieldValues, ps, false);
		
		//執行SQL
		ps.execute();
		JdbcDaoHelper.release(ps, null);
		
		System.out.println(sql + "\n" + clazz.getSimpleName() + "修改成功.");
	}
 
	@Override
	public T get(Object id,Class<T> clazz) throws Exception {
		String idFieldName = "";
		Field[] fields = clazz.getDeclaredFields();
		boolean flag = false;
		for (Field field : fields) {
			if (field.isAnnotationPresent(Id.class)) {
				idFieldName = field.getAnnotation(Id.class).value();
				flag = true;
				break;
			} 
		}
		
		if (!flag) {
			//throw new NotFoundAnnotationException(clazz.getName() + " object not found id property.");
		}
		
		//拼裝SQL
		Map<String,Object> sqlWhereMap = new HashMap<String, Object>();
		sqlWhereMap.put(TABLE_ALIAS + "." + idFieldName, id);
		
		List<T> list = findAllByConditions(sqlWhereMap, clazz);
		return list.size() > 0 ? list.get(0) : null;
	}
 
	@Override
	public List<T> findAllByConditions(Map<String,Object> sqlWhereMap,Class<T> clazz) throws Exception {
		List<T> list = new ArrayList<T>
            
           

相關推薦

使用註解自動解釋orm從而實現xml配置jdbc介面dao資料庫增刪

一、獲取資料庫連線和關閉資源 package cn.itdoer.base.utils.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepa

jfinal+hbase+eclipse開發web專案詳細步驟04---在web頁面實現hbase資料庫資料的增刪功能

首先提醒大家,本節是在步驟01、步驟02、步驟03都成功的基礎上做進一步開發。如果在之前的任何一個步驟出現問題,那麼希望你先解決好問題之後,再做本次的開發。 步驟1:建表。 1、開啟我們虛擬機器,並且啟動hadoop、hbase start-all.sh start

【spring boot+mybatis】註解使用方式(xml配置)設定自動駝峰明明轉換(mapUnderscoreToCamelCase)IDEA中xxDao報錯could not autowi

最近使用spring boot+mybatis,使用IntelliJ IDEA開發,記錄一些問題的解決方法。1、在使用@Mapper註解方式代替XXmapper.xml配置檔案,使用@Select等註解配置sql語句的情況下,如何配置資料庫欄位名到JavaBean實體類屬性命

C# 鼠標點擊移動窗體代碼可以實現邊框窗體的拖動

點擊 obj cat += tar sender see sed false private static bool IsDrag = false; private int enterX; private int enterY;

gparted燒錄到U盤使其成為live usb從而實現U盤啟動並啟動gparted

  1.把zip包中的檔案解壓縮到U盤中,並且保持原目錄結構不變!也就是說,解壓縮到U盤根目錄中!自己不要增加目錄! 2.執行你U盤中utils/linux/目錄中的makeboot.bat檔案!(特別注意,此檔案一定要在U盤中執行,絕不允許在你的硬碟上執行!) 以上操作完畢後,即可用

程式設計師的中年該如何度過從而實現自律方能自由

最近看了不少關於中年危機的文章,一直覺得自己只是一個看客,中年危機似乎離自己還有一段時間。然而,突然又覺得自己是不是已經邁入了中年?自己有沒有認真思考過這個問題?看看自己已經三十出頭,臉龐漸寬,不注重形象與健身,自從有了孩子生活也被填的滿滿的,所有時間是在路上,在上班,看娃,睡覺,一切似乎都很正常,按這個節奏

在前後端分離的專案中後臺使用shiro框架時怎樣使用它的會話管理系統(session)從而實現許可權控制

在前後端分離的專案中,ajax跨域和儲存使用者資訊是其中的重點和難點。 如果在後臺使用shiro框架來進行許可權控制,就需要用到cookie+session的模式來儲存使用者的資訊。 在前一篇文章《在前後端分離的專案中,ajax跨域請求怎樣附帶cookie》中,我具體寫了怎

檢視與修改位元組碼從而實現替換他人jar包中class檔案的目的

一、檢視二進位制位元組碼檔案的方式: 1.通過cmd命令:javap -v ClassA 2.通過jclasslib工具 二、將Android的apk中的dex反編成smail檔案,直接修改smail檔案後再回編成dex; 三、修改二進位制位元組碼檔案的方式: 1.反編

菜鳥學習shiro之實現自定義的Realm從而實現登入驗證身份驗證和許可權驗證4

講了那麼多使用的內建的類從而實現四郎,現在講自定義的境界 首先行家的依賴依然是第一篇的那個依賴 下邊是自定義的境界: import org.apache.shiro.authc.AuthenticationException; import org.apache.shi

Spring MVC的WebMvcConfigurerAdapter用法收集(零配置XML配置

clas security net turn 信息 xxx jsonview frame ppi 原理先不了解,只記錄常用方法 用法: @EnableWebMvc 開啟MVC配置,相當於 <?xml version="1.0" encoding="UTF-

用shell寫一個簡易計算器可以實現加、減、乘、除運算假如腳本名字為1.sh執行示例:./1.

a-z 依次 腳本 als 示例 內置 數位 特殊字符 使用 用shell寫一個簡易計算器,可以實現加、減、乘、除運算,假如腳本名字為1.sh,執行示例:./1.sh 1 + 2#!/bin/bash if [ $# -ne 3 ] then echo "參

spring事務管理基於xml配置完成事務回滾;spring中資料庫中欄位名和pojo中屬性名不一致時候實現RowMapper介面手動封裝

宣告使用JDK8,spring5.0.7, 測試說明: service 層 宣告介面進行轉賬,從A轉賬B ,然後對AB 進行更新操作,在事務中對find方法開啟 只讀許可權,無法進行更新操作,造成事務回滾進行測試事務; 主要測試方法:* void tra

Spring Boot入門 (二) :xml配置實現

無xml配置的實現 自Spring3.X 以後 spring 提供了很多的註解來代替XML檔案的配置,最核心的是下面兩個註解。 ::@Configuration:: 標註該類是配置類,類似於我們定義的applicationContext.xml ::@B

C語言:實現一個通訊錄可以進行增刪等多項功能(動態版本)

基於前一篇文章的靜態通訊錄,新增malloc函式,realloc函式以及free,將其改變為一個動態的通訊錄,可以動態記憶體開闢,儘可能防止記憶體的浪費。 具體程式碼如下: contact.h #ifndef __CONTACT_H__ #define __CO

IDEA java連線mysql資料庫實現資料庫的增刪改

先上程式碼: package Database_Demo; import java.sql.*; public class DataBase { public static void main(String[] args) { Connect

C#裡面的(T)方法介面等簡單解釋

只是比較簡單的解釋,在實際使用中,如果遇到需要深入研究的場景,再翻閱相關資料深入研究下。 一、泛型T 這個T在實際使用中很常見,比如List<T>。其實我們還可以寫成List<object>。但是這樣寫會有一個問題。比如我把一個int資料存入到一個List<ob

hibernate簡單程式實現從頁面資料庫的增刪改(主從關聯)

      前段時期一直使用三層來寫從頁面對資料庫的增刪改查,今天用hibernate框架來實現從頁面對資料庫的增刪改查, 首先介紹下今天我們要實現的功能, 1、使用者能夠註冊,2、註冊成功後直接跳到登入頁面,3、登入成功後直接跳到對公司、人員的增刪改查, 4、要有對人員介

在MVC程式中使用倉儲模式和工作單元實現增刪

在這片文章中,我將自己動手為所有的實體:寫一個泛型倉儲類,還有一個工作單元。 工作單元的職責就是:為每一個實體,建立倉儲例項。倉儲(倉庫)的職責:增刪查改的功能實現。 我們將會在控制器中,建立工作單元類(UnitOfWork)的例項,然後根據實體,建立倉儲例項,再就是

android遠端呼叫sql server實現增刪sql server配置+android端程式碼+常見問題

1.sql server環境的搭建: 注意:本例項用的是sql server2008 r2,jtds 1.2.7 2. sql server遠端呼叫的配置 3. android端如何對sql server的呼叫 http://blog.csdn.net/conowen/