Java反射机制、注解及JPA实现
1、java反射概述
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Java的反射机制允许编程人员在对类未知的情况下,获取类相关信息的方式变得更加多样灵活,调用类中相应方法,是Java增加其灵活性与动态性的一种机制。
2、java注解
注解本身没有任何的作用。简单说和注释没啥区别,而它有作用的原因是:注解解释类,也就是相关对代码进行解释的特定类。一般这些类使用反射是可以拿到的。Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
3 、反射结合注解、自实现JPA、实体映射
话不多说、直接上干货
注解TableEntry:用于解释实体的表名
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface TableEntry {
String tableName();
}
·PKField注解:用于解释主键及主键生成规则
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface PKField {
/* "ORCLE_SEQUENCE",
"MYSQL_AUTO_INCREASING",
"SELECTED_INCREASING",
"CURE_UUID"*/
PkGeneratorEnum pkGenerator() default PkGeneratorEnum.SEQUENCE;
String sequenceName() default "";
}
ColumnField注解:用于解释实体字段和数据库字段的对应
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface ColumnField {
String columnName();
}
Transient注解:用于描述无需查询出的实体属性
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Transient {
String value() default "";
}
实体映射接口
定义接口用于 获取实体
- 对应的表名
- 主键
- 主键生成规则
- sequence名
public interface EntryMapper {
abstract String getEntryTableName(Class<?> clazz);
abstract String[] getPKFieldName(Class<?> clazz);
abstract String getSequenceName(Class<?> clazz);
abstract PkGeneratorEnum getPkGenerator(Class<?> clazz);
}
实体映射接口实现类
通过反射获取注解对应作用域提供的信息
public class JpaEntryMapper implements EntryMapper{
public String getEntryTableName(Class<?> clazz){
Assert.notNull(clazz, "clazz不能为空");
TableEntry tableAnno=(TableEntry) clazz.getAnnotation(TableEntry.class);
Assert.notNull(tableAnno, "TableEntry注解未设置");
Assert.state(StringUtil.isNotEmpty(tableAnno.tableName()), "tableAnno.tableName未设置");
return StringUtil.toUpperCase(tableAnno.tableName());
}
public String[] getPKFieldName(Class<?> clazz){
Assert.notNull(clazz, "clazz不能为空");
Field[] fields= clazz.getDeclaredFields();
int pkArrLen=(fields.length>10?10:fields.length);
// String[] pkArr=new String[pkArrLen];
List<String> pk_list = new ArrayList<String>(pkArrLen);
for(int i=0; i < fields.length ; i++){
if("serialVersionUID".equalsIgnoreCase(fields[i].getName()))continue;
PKField pkField = fields[i].getAnnotation(PKField.class);
if(pkField != null){
ColumnField columnField = fields[i].getAnnotation(ColumnField.class);
if(columnField==null){
//未设置columnField注解默认属性值
pk_list.add(StringUtil.toLowerCase(fields[i].getName()));
}else{
pk_list.add(StringUtil.toLowerCase(columnField.columnName()));
}
}
}
Assert.notEmpty(pk_list, "PKField未设置或ColumnField未设置");
return pk_list.toArray(new String[0]);
}
public String getSequenceName(Class<?> clazz){
Assert.notNull(clazz, "clazz不能为空");
Field[] fields= clazz.getDeclaredFields();
for(Field field : fields){
if("serialVersionUID".equalsIgnoreCase(field.getName()))continue;
PKField pkField = field.getAnnotation(PKField.class);
if(pkField != null){
if(StringUtil.isNotEmpty(pkField.sequenceName())){
return StringUtil.toUpperCase(pkField.sequenceName());
}
}
}
Assert.state(false, "pkField.sequenceName未设置");
return null;
}
public PkGeneratorEnum getPkGenerator(Class<?> clazz){
Assert.notNull(clazz, "clazz不能为空");
Field[] fields= clazz.getDeclaredFields();
for(Field field : fields){
if("serialVersionUID".equalsIgnoreCase(field.getName()))continue;
PKField pkField = field.getAnnotation(PKField.class);
if(pkField != null){
// Assert.notNull(pkField.pkGenerator(), "pkField.pkGenerator未设置");
if(pkField.pkGenerator()!=null){
return pkField.pkGenerator();
}
}
}
Assert.state(false, "PKField未设置");
return null;
}
}
抽象sql中的where 条件 和 whereUnit单元
Where类
public class Where {
private List<WhereUnit> whereUnitList ;
private boolean isNamed = false ;
public Where(){
whereUnitList = new ArrayList<WhereUnit>() ;
}
public Where(boolean isNamed){
this();
this.isNamed=isNamed;
}
public Where(Object inputDto,boolean isNamed){
this(isNamed);
initEntry(inputDto);
}
public Where(Object inputDto){
this();
initEntry(inputDto);
}
public Where and(String colName ,String comparator ,Object colVal)
{
add(new WhereUnit("AND",colName,comparator,colVal));
return this;
}
public Where or(String colName ,String comparator ,Object colVal)
{
add(new WhereUnit("OR",colName,comparator,colVal));
return this;
}
public boolean add(WhereUnit unit)
{
return whereUnitList.add(unit);
}
public WhereUnit get(int index)
{
return whereUnitList.get(index);
}
public WhereUnit set(int index,WhereUnit unit)
{
if(index<0 || index >= size() ){
throw new IndexOutOfBoundsException("setUnit的index超出List的长度");
}
return whereUnitList.set(index, unit);
}
public Iterator<WhereUnit> iterator(){
return whereUnitList.iterator();
}
public WhereUnit remove(int index)
{
return whereUnitList.remove(index);
}
public boolean remove(WhereUnit unit)
{
return whereUnitList.remove(unit);
}
public int size()
{
return whereUnitList.size();
}
public int indexOf(WhereUnit unit)
{
return whereUnitList.indexOf(unit);
}
public StringBuffer toSqlString(){
StringBuffer where_Buffer=new StringBuffer(" WHERE 1=1 ");
Iterator<WhereUnit> iter=whereUnitList.iterator();
while(iter.hasNext()){
WhereUnit unit = iter.next();
Assert.notNull(unit,"WhereUnit不未空");
where_Buffer.append(unit.toSqlString(this.isNamed));
}
return where_Buffer;
}
public Object[] getParamterValArr(){
List<Object> paras= new ArrayList<Object>(size());
Iterator<WhereUnit> iter = whereUnitList.iterator();
while(iter.hasNext()){
WhereUnit unit =iter.next();
if("IN".equalsIgnoreCase(unit.getComparetor())){
continue;
}
paras.add(unit.getColVal());
}
return paras.toArray();
}
public Map<String,Object> getParamterMap(){
Map<String,Object> para_map= new HashMap<String,Object>(size());
Iterator<WhereUnit> iter = whereUnitList.iterator();
while(iter.hasNext()){
WhereUnit unit =iter.next();
if("IN".equalsIgnoreCase(unit.getComparetor())){
continue;
}
para_map.put( unit.getColName(),unit.getColVal());
}
return para_map;
}
private void initEntry(Object entry) {
// TODO
Assert.notNull(entry, "entry不为空");
Assert.notNull(whereUnitList, "whereUnitList不为空");
Class<?> entry_class = entry.getClass();
try{
Field[] fields = entry_class.getDeclaredFields();
for(Field field : fields){
String field_name = field.getName();
if(field_name.equalsIgnoreCase("serialVersionUID"))continue;
String read_method_name = "get"+StringUtil.toUpperFristChar(field_name);
Method read_method= entry_class.getDeclaredMethod(read_method_name);
Object field_val = read_method.invoke(entry);
if ( field_val != null ){
ColumnField columnFieldAnno = field.getAnnotation(ColumnField.class);
if(columnFieldAnno == null){
and(field_name,"=",field_val);
}else{
and(columnFieldAnno.columnName(),"=",field_val);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
WhereUnit类
public class WhereUnit {
private String colName;
private String comparetor;
private String linkSign;
private Object colVal;
public WhereUnit(){}
public WhereUnit(String linkSign, String colName , String comparetor,Object colVal){
this.linkSign=linkSign;
this.colName=colName;
this.comparetor=comparetor;
this.colVal=colVal;
}
public String getColName() {
return colName;
}
public void setColName(String colName) {
this.colName = colName;
}
public Object getColVal() {
return colVal;
}
public void setColVal(Object colVal) {
this.colVal = colVal;
}
public String getComparetor() {
return comparetor;
}
public void setComparetor(String comparetor) {
this.comparetor = comparetor;
}
public String getLinkSign() {
return linkSign;
}
public void setLinkSign(String linkSign) {
this.linkSign = linkSign;
}
public StringBuffer toSqlString(boolean isNamed){
StringBuffer unit_Buffer = new StringBuffer();
unit_Buffer.append(" ").append(linkSign).append(" ").append(colName).append(" ").append(comparetor);
if("IN".equalsIgnoreCase(comparetor)){
unit_Buffer.append(" (").append(colVal).append(") ");;
}else{
if(isNamed){
unit_Buffer.append(" :"+colName+" ");
}else{
unit_Buffer.append(" ? ");
}
}
return unit_Buffer;
}
}
JpaService接口定义常用的方法
public interface JpaService {
<T> T findById(Class<T> clazz, Long id);
<T> T findById(Class<T> clazz, Where pks_where);
<T> T findById(Class<T> clazz, Long id, Boolean cascade);
<T> T findById(Class<T> clazz, Where pks_where, Boolean cascade);
<T> List<T> findList(T inputDto);
<T> List<T> findList(Class<T> clazz, Where where, OrderBy orderby);
<T> List<T> findList(Class<T> clazz, Where where);
List<Map<String,Object>> findList(String tableName, Where where, OrderBy orderby);
List<Map<String,Object>> findList(String tableName, Where where);
<T> List<T> findAll(Class<T> clazz);
<T> List<T> findAll(Class<T> clazz, OrderBy orderby);
List<Map<String,Object>> findAll(String tableName);
List<Map<String,Object>> findAll(String tableName, OrderBy orderby);
<T> Pager<T> findPager(Class<T> clazz, Pager<T> pager, Where where);
<T> Pager<T> findPager(Class<T> clazz, Pager<T> pager);
<T> Pager<T> findPager(Class<T> clazz, Pager<T> pager, Where where,
OrderBy orderby);
Long selectTotal(String tableName, Where where);
Long selectTotal(Class<?> clazz, Where where);
<T> List<T> selectPageList(Class<T> clazz, Pager<T> pager, Where where,
OrderBy orderby);
int insert(Object entry);
int insert(Class<?> clazz,SqlSet sql_set);
int update(Object entry);
int update(Class<?> clazz, SqlSet sql_set);
long insertUseKey(Object t);
long insertUseKey(Class<?> clazz, SqlSet sql_set);
int delete(Class<?> clazz, Long id);
int delete(Class<?> clazz, Where pk_where);
Long getSeq(Class<?> clazz);
}
实现JpaService的接口,就能愉快的通过jpaService直接调用常用的方法啦
我是飞奔的企鹅:
一只有梦想,有故事的企鹅 ,欢迎诉说你的故事