主要是加入两个新注解
一个Entity注解,加在类的实体属性上
/**
* 实体对象属性的注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
//表名注解
String table();
//对应的非实体对象属性名
String field();
//实体类地址
String address();
//名称
String name();
}
另一个为类似于外键的注解,只不过是外键所对应的属性
/**
* 外键注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Key {
//对应Entity注解的表名
String farther();
}
构造实体类如下
@Table(name = "first_type")
public class FirstType implements Serializable{
/**
* 书本一级类型id
*/
@Id(name = "id")
@Column(name = "id")
private String id;
/**
* 书本一级类型名称
*/
@Column(name = "name")
private String name;
/**
*删除标记,0正常,1删除
*/
@Column(name = "del_flag")
private Integer deleteFlag;
@Entity(table = "sub_type",field = "id",address = "cn.keduox.entity.SubType",name = "subTypeList")
List<SubType> subTypeList=new ArrayList<>();
public Integer getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(Integer deleteFlag) {
this.deleteFlag = deleteFlag;
}
public FirstType(String id, String name, List<SubType> subTypeList) {
this.id = id;
this.name = name;
this.subTypeList = subTypeList;
}
public List<SubType> getSubTypeList() {
return subTypeList;
}
public void setSubTypeList(List<SubType> subTypeList) {
this.subTypeList = subTypeList;
}
public FirstType() {
}
public FirstType(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Table(name = "sub_type")
public class SubType implements Serializable{
/**
* id
*/
@Id(name = "id")
@Column(name = "id")
private String id;
/**
* 名称
*/
@Column(name = "name")
private String name;
/**
* 所属父类型id
*/
@Column(name = "first_type_id")
@Key(farther = "sub_type")
private String firstTypeId;
/**
* 所属父类型
*/
private FirstType firstType;
/**
* 包含的子类型
*/
@Entity(table = "second_type",field = "id",address = "cn.keduox.entity.SecondType",name = "secondTypeList")
List<SecondType> secondTypeList=new ArrayList<>();
public Integer getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(Integer deleteFlag) {
this.deleteFlag = deleteFlag;
}
/**
*删除标记,0正常,1删除
*/
@Column(name = "del_flag")
private Integer deleteFlag;
public SubType(String id, String name, String firstTypeId) {
this.id = id;
this.name = name;
this.firstTypeId = firstTypeId;
}
public SubType() {
}
public SubType(String id, String name, String firstTypeId, FirstType firstType, List<SecondType> secondTypeList) {
this.id = id;
this.name = name;
this.firstTypeId = firstTypeId;
this.firstType = firstType;
this.secondTypeList = secondTypeList;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFirstTypeId() {
return firstTypeId;
}
public void setFirstTypeId(String firstTypeId) {
this.firstTypeId = firstTypeId;
}
public FirstType getFirstType() {
return firstType;
}
public void setFirstType(FirstType firstType) {
this.firstType = firstType;
}
public List<SecondType> getSecondTypeList() {
return secondTypeList;
}
public void setSecondTypeList(List<SecondType> secondTypeList) {
this.secondTypeList = secondTypeList;
}
}
BaseDaoImpl的查询方法如下:
/**
* 查询方法:仅封装了where和默认的order by以及分页,支持模糊查询
*
* @param t 要查的表
* @param open 是否启用排序
* @param flag 排序要求
* @param e 分页对象
* @param vague 是否进行模糊查询
* @return
*/
@Override
public List<T> select(T t, boolean open, boolean flag, E e, boolean vague,String order) throws Exception {
//获取表名注解
Table table = EntityClass.getAnnotation(Table.class);
String tableName = table.name();
//取的域对象并做遍历处理
Field[] fields = EntityClass.getDeclaredFields();
//存放where语句后的查询条件的Map
Map<String, Object> whereMap = new HashMap<String, Object>();
List<Object> sonObjectList = new ArrayList<>();
//存放排序条件的集合
List<String> orderList = new ArrayList<String>();
for (Field field : fields) {
field.setAccessible(true);//一定要施暴
//获取属性值,判断是否为空,拼接where条件
if (field.isAnnotationPresent(Column.class)) {
/* Method method=clazz.getMethod("get"+getMethodName(field.getName()));Object value=method.invoke(object);PropertyDescriptor pd = new PropertyDescriptor(field.getName(),object.getClass());Object value=pd.getReadMethod().invoke(object);String verificationValue= (String) field.get(object);*/
Method method = EntityClass.getMethod("get" + getMethodName(field.getName()));
String verificationValue = String.valueOf(method.invoke(t));
if (!verificationValue.equals("null")) {
//不为空,是查询条件
Object value = field.get(t);
Class clazz = value.getClass();
Column column = field.getAnnotation(Column.class);
String key = column.name();
whereMap.put(key, value);
}
}
//拼接排序条件
if (field.isAnnotationPresent(OrderItem.class)) {
OrderItem orderItem = field.getAnnotation(OrderItem.class);
orderList.add(orderItem.name());
}
}
//拼接分页
Integer[] limitCondition = new Integer[2];
Field[] fields1 = EntityClass1.getDeclaredFields();
for (Field field : fields1) {
if (field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
String limitName = column.name();
Method method = EntityClass1.getMethod("get" + getMethodName(field.getName()));
Integer value = (Integer) method.invoke(e);
if (value != null) {
if (limitName.equals("currentPage")) {
limitCondition[0] = value;
}
if (limitName.equals("currentCount")) {
limitCondition[1] = value;
}
}
}
}
if (limitCondition[0] != null && limitCondition[1] != null) {
limitCondition[0] = limitCondition[1] * (limitCondition[0] - 1);
}
//集合准备完毕,开始拼接sql
StringBuilder sql = new StringBuilder("");
sql.append("select * from ").append(tableName);
//判断whereMap是否为空来进行条件查询
List<Object> valueList = new ArrayList<>();
if (whereMap.size() != 0) {
sql.append(" where ");
for (Map.Entry<String, Object> entry : whereMap.entrySet()) {
if (vague) {
if (entry.getValue() instanceof String) {
sql.append(entry.getKey() + " like ? and ");
valueList.add("%" + entry.getValue() + "%");
} else {
sql.append(entry.getKey() + "=? and ");
valueList.add(entry.getValue());
}
} else {
sql.append(entry.getKey() + "=? and ");
valueList.add(entry.getValue());
}
}
sql.delete(sql.length() - 5, sql.length());
}
//判断是否进行默认排序
if (open) {
sql.append(" order by ");
if (orderList.size() != 0) {
for (String str : orderList) {
sql.append(str).append(",");
}
sql.delete(sql.length() - 1, sql.length());
}
}
//是否进行自定义排序
if(!(order==null || order.equals(""))){
if (open){
boolean f=true;
for (String str : orderList) {
if (str.equals(order)){
f=false;
break;
}
}
if (f){
sql.append(",").append(order+" ");
}
}else {
sql.append(" order by ").append(order+" ");
}
}
if (open || !(order==null || order.equals(""))){
sql.append(" ").append(flag == true ? "asc" : "desc").append(" ");
}
//判断是否分页
if (limitCondition[0] != null && limitCondition[1] != null) {
sql.append("limit").append(" ").append(limitCondition[0]).append(",").append(limitCondition[1]);
}
//SQL拼接完毕,开始执行查询
PreparedStatement preState = null;
Connection connection = null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
//编译
preState = connection.prepareStatement(String.valueOf(sql));
preState = JDBCUtils.setObject(preState, valueList.toArray());
resultSet = preState.executeQuery();
//通过反射将resultSet封装为对象集
List<T> resultList = new ArrayList<>();
int m=resultSet.getRow();
while (resultSet.next()) {
T resultObject = EntityClass.newInstance();
for (Field field : fields) {
field.setAccessible(true);
if (field.isAnnotationPresent(Column.class)) {
String columnName = field.getAnnotation(Column.class).name();
Object fieldValue = resultSet.getObject(columnName);
field.set(resultObject, fieldValue);
}
}
for (Field field : fields) {
//处理实体类注解,采用迭代
if (field.isAnnotationPresent(Entity.class)) {
//获取注解对象,获取对应的属性值
Entity entity = field.getAnnotation(Entity.class);
String idName = entity.field();
Method method = EntityClass.getMethod("get" + getMethodName(idName));
String verificationValue = String.valueOf(method.invoke(t));
Class clazz = Class.forName(entity.address());
Object sonObject = clazz.newInstance();
Object value;
if (!verificationValue.equals("null")) {
//这是条件查询
value = method.invoke(t);
} else {
//非条件查询
value = method.invoke(resultObject);
}
Field[] sonFields = sonObject.getClass().getDeclaredFields();
//获取子实体类的id属性
for (Field field1 : sonFields) {
field1.setAccessible(true);//一定要施暴
//获取外键
if (field1.isAnnotationPresent(Key.class)) {
if (field1.getAnnotation(Key.class).farther().equals(entity.table())) {
field1.set(sonObject, value);
break;
}
}
}
sonObjectList = sonSelect(sonObject);
//封装
//判断当前域对象的类型用getSimpleName
Class c = field.getType();
String name = c.getSimpleName();
if ( sonObjectList != null && sonObjectList.size() != 0) {
if ("List".equals(name)) {
field.set(resultObject, sonObjectList);
} else {
field.set(resultObject, sonObjectList.get(0));
}
}
}
}
resultList.add(resultObject);
}
return resultList;
} catch (SQLException e1) {
e1.printStackTrace();
return null;
} finally {
//关闭资源
JDBCUtils.close(connection, preState, resultSet);
}
}
/**
* 迭代处理类
*/
public List<Object> sonSelect(Object object) throws Exception {
Class clazz = object.getClass();
Table table = (Table) clazz.getAnnotation(Table.class);
String tableName = table.name();
Field[] fieldList = clazz.getDeclaredFields();
Map<String, Object> whereMap = new HashMap<>();
List<Object> sonObjectList = new ArrayList<>();
for (Field field : fieldList) {
field.setAccessible(true);
//普通类型注解
if (field.isAnnotationPresent(Column.class)) {
Method method = clazz.getMethod("get" + getMethodName(field.getName()));
String verificationValue = String.valueOf(method.invoke(object));
if (!verificationValue.equals("null")) {
Object value = method.invoke(object);
String key = field.getAnnotation(Column.class).name();
whereMap.put(key, value);
}
}
}
//集合准备完毕,开始拼接sql
StringBuilder sql = new StringBuilder("");
sql.append("select * from ").append(tableName);
List<Object> valueList = new ArrayList<>();
if (whereMap.size() != 0) {
sql.append(" where ");
for (Map.Entry<String, Object> entry : whereMap.entrySet()) {
sql.append(entry.getKey() + "=? and ");
valueList.add(entry.getValue());
}
sql.delete(sql.length() - 5, sql.length());
}
//SQL拼接完毕,开始执行查询
PreparedStatement preState = null;
Connection connection = null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
//编译
preState = connection.prepareStatement(String.valueOf(sql));
preState = JDBCUtils.setObject(preState, valueList.toArray());
resultSet = preState.executeQuery();
//通过反射将resultSet封装为对象集
List<Object> resultList = new ArrayList<>();
while (resultSet.next()) {
Object resultObject = clazz.newInstance();
for (Field field : fieldList) {
field.setAccessible(true);
//普通注解
if (field.isAnnotationPresent(Column.class)) {
String columnName = field.getAnnotation(Column.class).name();
Object fieldValue = resultSet.getObject(columnName);
field.set(resultObject, fieldValue);
}
}
for (Field field : fieldList) {
//处理实体类注解,采用迭代
if (field.isAnnotationPresent(Entity.class)) {
Entity entity = field.getAnnotation(Entity.class);
String idName = entity.field();
Method method = clazz.getMethod("get" + getMethodName(idName));
String verificationValue = String.valueOf(method.invoke(object));
Class clazz1 = Class.forName(entity.address());
Object sonObject = clazz1.newInstance();
Object value;
if (!verificationValue.equals("null")) {
//条件查询
value = method.invoke(object);
} else {
value = method.invoke(resultObject);
}
Field[] sonFields = sonObject.getClass().getDeclaredFields();
for (Field field2 : sonFields) {
field2.setAccessible(true);//一定要施暴
if (field2.isAnnotationPresent(Key.class)) {
if (field2.getAnnotation(Key.class).farther().equals(entity.table())) {
field2.set(sonObject, value);
break;
}
}
}
sonObjectList = sonSelect(sonObject);
//封装
//判断注解是否是加在集合上的
//判断当前域对象的类型用getSimpleName
Class c = field.getType();
String name = c.getSimpleName();
if (sonObjectList != null && sonObjectList.size() !=0) {
if ("List".equals(name)) {
field.set(resultObject, sonObjectList);
} else {
field.set(resultObject, sonObjectList.get(0));
}
}
}
}
resultList.add(resultObject);
}
return resultList;
} catch (SQLException e1) {
e1.printStackTrace();
return null;
} finally {
//关闭资源
JDBCUtils.close(connection, preState, resultSet);
}
}
这样,在查询一级类的时候就能把二级类的信息也查询出来了,同时可以无限迭代查询。
代码下载地址:https://download.csdn.net/download/qq_34295546/10225638