自定义sql查询并封装为指定实体 - 类似Hibernate

原理:通过java反射,得到实体属性对应的字段名称及类型,并用原生的jdbc执行查询并封装。

直接看源码:


1.实体:Zztest

package demo.linj.test;

import java.text.NumberFormat;

public class Zztest {
	
	private String id;
	private String serviceTypeid;
	private Double totlaprice;
	
	@JdbcMapping("ID")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@JdbcMapping("SERVICE_TPYEID")
	public String getServiceTypeid() {
		return serviceTypeid;
	}
	public void setServiceTypeid(String serviceTypeid) {
		this.serviceTypeid = serviceTypeid;
	}
	@JdbcMapping("TOTALPRICE")
	public Double getTotlaprice() {
		return totlaprice;
	}
	public void setTotlaprice(Double totlaprice) {
		this.totlaprice = totlaprice;
	}
	
	@Override
	public String toString() {
		return "['id':'"+id+"', 'serviceTypeid':'"+serviceTypeid+"','totalprice':'"+NumberFormat.getCurrencyInstance().format(totlaprice)+"']";
	}
}
2.注解类:JdbcMapping

package demo.linj.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JdbcMapping {
	String value() default "";
}
3.访问链接工具(DAO):LocalJdbcUtils
package demo.linj.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class LocalJdbcUtils {
	private String driver;
	private String url;
	private String username;
	private String password;
	
	public LocalJdbcUtils(String driver, String url, String username, String password) {
		this.driver = driver;
		this.url = url;
		this.username = username;
		this.password = password;
	}

	/**获取数据库连接*/
	private Connection getConnection() {
		Connection conn = null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, username, password);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	/**得到实体每一个属性*/
	private HashMap<Field,Object[]> setEntityMap(Class<?> claz) throws Exception {
		HashMap<Field,Object[]> fieldCloumType = new HashMap<Field, Object[]>();
		Field[] fields = claz.getDeclaredFields();
		for (Field field : fields) {
			String fieldName = field.getName();
			String getMethod = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
			try {
				Method method = claz.getMethod(getMethod, new Class<?>[]{});
				if(method == null) {//如果该属性没有对应的get方法,则不处理
					System.out.println("there is no method of 'get' for field '"+fieldName+"'");
					continue;
				}
				JdbcMapping jm = method.getAnnotation(JdbcMapping.class);
				if(jm == null) {
					throw new Exception("The method of 'get' for field named "+claz.getName()+"."+fieldName+" has no use @JdbcMapping annotation");
				}
				fieldCloumType.put(field, new Object[]{jm.value(),method.getReturnType()});//{String,Class<?>}
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
		}
		return fieldCloumType;
	}

	/**使用原生态的jdbc查询*/
	public <E> List<E> findBySql(String sql, Class<? extends E> clz) throws Exception {
		List<E> list = new ArrayList<E>();
		HashMap<Field,Object[]> fieldCloumType = setEntityMap(clz);
		Connection conn = getConnection();
		try {
			PreparedStatement pstmt = conn.prepareStatement(sql);
			ResultSet sets = pstmt.executeQuery();
			while(sets.next()) {
				E z = clz.newInstance();
				for (Field field : fieldCloumType.keySet()) {
					field.setAccessible(true);
					Object[] cloumType = fieldCloumType.get(field);
					if(((Class<?>)cloumType[1]).isAssignableFrom(String.class)) {
						field.set(z, sets.getString((String)cloumType[0]));
					}
					if(((Class<?>)cloumType[1]).isAssignableFrom(Double.class)) {
						field.set(z, sets.getDouble((String)cloumType[0]));
					}
				}
				list.add(z);
			}
			sets.close();
			pstmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
}
=========================

4.测试类:

package demo.linj.test;

import java.util.List;

public class TestJdbcMappingEntity {
	
	public static void main(String[] args) throws Exception {
		LocalJdbcUtils u = new LocalJdbcUtils("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password");
		
		List<Zztest> list = u.findBySql("select * from zztest", Zztest.class);
		for (Zztest zztest : list) {
			System.out.println(zztest);
		}
	}
}


5.输出结果:

['id':'2', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥0.00']
['id':'1', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥10.00']
['id':'3', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥20.00']
['id':'4', 'serviceTypeid':'f82f28bcad934a5d','totalprice':'¥15.00']

=================================

总结:本例只是一个简单的使用原生jdbc的模仿,没有使用AOP等工具类。但原理类似。重点在于JDBC的使用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值