Erstellen Sie Ihre eigene Persistenz FW (Java)

Wenn Sie die Template-Engine voll ausnutzen, Ist es nicht einfach, eine persistente FW mit SQL in einer externen Datei wie MyBatis oder Doma zu erstellen? Ich dachte und machte es.

Sie können jetzt die Daten für user_mst mit nur dem folgenden Code erhalten.

selectById.sql


select *
from user_mst
where id = {{ p.bind(id) }}

user_Java-Code, um mst zu bekommen


SqlTemplate sqlTemplate = new SqlTemplate();
DbAccess dbAccess = new DbAccess(connection);//java.sql.Verbindung

Map<String, Object> context = new HashMap<>();
context.put("id", id);
QueryBuilder query = sqlTemplate.evaluate( "selectById.sql", context);
UserMst userMst = dbAccess.selectOne( query, UserMst.class );

Dieses Mal verwendet die Vorlagen-Engine Pebble. Aber ich denke, Sie können es wahrscheinlich mit "Apache Velocity", "FreeMarker" oder "Moustache.java" tun. Ich denke, Sie können Ihre Lieblingsvorlagen-Engine verwenden. Der Punkt ist, dass Sie die Methode in der Vorlage aufrufen können. Die direkte Arbeit mit JDBC ist mühsam. Verwenden Sie daher Apache Commons DBUtils. Der Wert wird automatisch eingestellt, indem die Reflexion voll genutzt wird.

build.groovy


// https://mvnrepository.com/artifact/com.mitchellbosecke/pebble
compile group: 'com.mitchellbosecke', name: 'pebble', version: '2.4.0'
// https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils
compile group: 'commons-dbutils', name: 'commons-dbutils', version: '1.7'

Template Engine für SQL


/**Template Engine für SQL*/
import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import java.io.StringWriter;

public class SqlTemplate{
	private static PebbleEngine engine;
	/**Holen Sie sich die Template-Engine*/
	private PebbleEngine getEngine(){
		if( null == engine){
			engine = new PebbleEngine.Builder()
					.autoEscaping(false)//HTML-Escape ist überflüssig, entfernen Sie es also
					.strictVariables(true)//Eine Einstellung, die eine Ausnahme auslöst, wenn versucht wird, eine Variable zu verwenden, die sich nicht im Kontext befindet
					.build();
		}
		return engine;
	}

	/**Abfrage basierend auf dem Namen der SQL-Vorlage und dem Wert der Vorlage abrufen*/
	public QueryBuilder evaluate(String templateFileName, Map<String, Object> context) throws Exception{
		SqlParametors sqlParametors = new SqlParametors();
		context.put( "p", sqlParametors );
		String result = simpleEvaluateTemplate(templateFileName, context );
		QueryBuilder query = new QueryBuilder( result, sqlParametors.getParams() );
		return query;
	}

	/**Eine Methode, die nur die Vorlage auswertet und die resultierende Zeichenfolge zurückgibt*/
	private String simpleEvaluateTemplate(String templateFileName, Map<String, Object> context) throws Exception{
		StringWriter writer = new StringWriter();
		PebbleTemplate template = getEngine().getTemplate(templateFileName);
		template.evaluate(writer, context);
		return writer.toString();
	}
}

SQL-Parameter


import java.util.List;

/**Klasse zum Speichern von SQL-Parametern.Zugriff innerhalb der Template Engine.*/
public class SqlParametors {
	/**Parameter*/
	private List<Object> params = new ArrayList<>();
	/**Parameter binden*/
	public String bind(Object param){
		params.add(param);
		return "?";
	}
	/**Parameter abrufen*/
	public List<Object> getParams(){
		return params;
	}
}

Speicherklasse abfragen


import java.util.List;
import java.util.Arrays;

/**Speicherklasse abfragen*/
public class QueryBuilder {
	/**SQL-Anweisung*/
	private StringBuilder sql = new StringBuilder();
	/**Parameter*/
	private List<Object> params = new ArrayList<>();

	public QueryBuilder(){
	}

	public QueryBuilder(CharSequence sql, List<Object>params){
		this.sql.append(sql);
		this.params.addAll(params);
	}

	public StringBuilder getSql() {
		return sql;
	}

	public void setSql(CharSequence sql) {
		this.sql = new StringBuilder( sql.toString() );
	}

	public Object[] getParams() {
		return params.toArray();
	}

	public void setParams(Object[] params) {
		this.params = Arrays.asList(params);
	}


}

DB-Zugriff


import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**DB-Zugriffsklasse. DB-Operation mit QueryBuilder-Objekt als Argument*/
class DbAccess{
	/**Abfrageausführung(dbutils) */
	private QueryRunner queryRunner = new QueryRunner();

	/**Verbindung*/
	private java.sql.Connection conn;

	/**Konstrukteur*/
	public DbAccess(java.sql.Connection conn){
		this.conn = conn;
	}

	/**Zum Einfügen und Aktualisieren von Anweisungen*/
	public int update(QueryBuilder query ) throws Exception{
		int rows = queryRunner.update(conn, query.getSql().toString(), query.getParams() );
		return rows;
	}

	/**Für den Fall, dass Sie das Ergebnis auswählen und in einer Liste abrufen möchten*/
	public <T> List<T>  selectList(QueryBuilder query, Class<T> clazz) throws Exception{
		ResultSetHandler<List<Map<String, Object>>> h = new MapListHandler();
		List<Map<String, Object>> mapList = queryRunner.query(conn, query.getSql().toString(), h, query.getParams() );
		List<T> beanList = convMapList2BeanList(mapList, clazz);
		return beanList;
	}

	/**Für den Fall, dass Sie nur eine Zeile auswählen und das Ergebnis erhalten möchten*/
	public <T> T selectOne(QueryBuilder query, Class<T> clazz) throws Exception{
		ResultSetHandler<Map<String, Object>> h = new MapHandler();
		Map<String, Object> map = queryRunner.query(conn, query.getSql().toString(), h ,query.getParams());
		if( null == map )
			return null;
		T bean = convMap2Bean(map, clazz );
		return bean;
	}

	/**Wenn Sie nur eine Spalte des Ergebnisses auswählen und abrufen möchten*/
	public <T> T selectOneColumn(QueryBuilder query, Class<T> clazz) throws Exception{
		Object value = queryRunner.query(conn, query.getSql().toString(), new ScalarHandler<T>(), query.getParams() );
		return clazz.cast(value);
	}
	
	/**
	 *Setzen Sie die Map-Objektliste auf die Bean-Liste.
	 * @param mapList Liste der Kartenobjekte
	 * @param clazz Ziel festlegen Bean-Klasse
	 * @throws Exception
	 */
	private <T> List<T> convMapList2BeanList(List<Map<String, Object>> mapList, Class<T> clazz) throws Exception{
		List<T> list = new ArrayList<>();
		for( int i = 0; i < mapList.size(); i++ ){
			list.add( convMap2Bean(mapList.get(i), clazz) );
		}
		return list;
	}

	/**
	 *Setzen Sie das Map-Objekt auf Bean.
	 * @param map Kartenobjekt
	 * @param clazz Ziel festlegen Bean-Klasse
	 * @throws Exception
	 */
	private <T> T convMap2Bean(Map<String, ?> map, Class<T> clazz) throws Exception{
		T bean = clazz.newInstance();
		//Feldliste abrufen
		Field[] fields = clazz.getDeclaredFields();

		for( Field f : fields ){
			f.setAccessible(true);
			f.set(bean, map.get(f.getName()) );//TODO Snake Case => Sie können den Konvertierungsprozess in Kamel durchführen.
		}
		return bean;
	}
}

Recommended Posts

Erstellen Sie Ihre eigene Persistenz FW (Java)
Machen Sie Ihren eigenen Pomodoro
Erstellen Sie Ihre eigenen Java-Anmerkungen
Erstellen Sie Ihr eigenes Elasticsearch-Plugin
Behandeln Sie Ihre eigenen Anmerkungen in Java
Erstellen Sie mit Java Ihren eigenen einfachen Server und verstehen Sie HTTP
Java: Versuchen Sie, einen durch Kommas getrennten Formatierer selbst zu implementieren
Erstellen Sie Ihre eigene Android-App für das Java-Lernen
Machen Sie einen Blackjack mit Java
So lesen Sie Ihre eigene YAML-Datei (*****. Yml) in Java
Java: Starten Sie WAS mit Docker und stellen Sie Ihre eigene Anwendung bereit
Java - So erstellen Sie JTable
Refactoring: Machen Sie Blackjack in Java
[Java] Mach es konstant
Machen Sie einen Diamanten mit Java
Erstellen Sie in Docker Ihre eigene Tastatur-QMK. Für Windows einzigartiges Volume