因为需求,不能对整个库里面的所有表做操作,也不用生成那么多对象,也不用所表里面所有字段进行操作。只需要对部分属性进行数据库映射,需要的操作,才进行展示,所以就想到了spring jpa 的框架,但是Jfinal 又是目前团队都在用的,对Jfinal 需要映射,我不是很习惯,因此就重新写了一个自己熟悉的框架。
MonthpackOrder monthpackOrder = new MonthpackOrder(); monthpackOrder.setOrderNo(orderNo); monthpackOrder.setFee(products.getFee()); monthpackOrder.setGameId(order.getYnGameId()); monthpackOrder.setInTime(new Date()); monthpackOrder.setManthpakBack(order.getBackUrl()); monthpackOrder.setPayResult(1); monthpackOrder.setProductId(order.getProductId()); monthpackOrder.setProductName(products.getProductName()); monthpackOrder.setUserId(order.getUserId()); monthpackOrder.setUserToken(order.getUserToken()); monthpackOrder = monthpackOrder.save(); log.info("订单系统id是:{}",monthpackOrder.getId());
以上是保存数据,查询数据,把保存的数据从数据库里面取出来。
以下是查询数据
MonthpackOrder order = new MonthpackOrder().queryToObject("select * from iptv_monthpackorder where OrderID = '"+orderNo+"';");
以下是查询List<T> 的数据
List<MonthpackOrder> orderList = new MonthpackOrder().queryToObjectList("select * from iptv_monthpackorder where payresult = '1' order by id ;");
ok,这个时候,就明了吧。语句我们可以自己写,完全可以实现你们复杂的数据查询。分页更加简单,你们自己写就好了。sql分页比你们自己写的分页要简单。
当然,如果你们想缓存分页,那个也简单,只需要一次查询出来,在内存分页就可以了。但是不影响查询。
可能有的人脑回路太长,无法理解更新,那我就贴出查询和更新的操作。
List<Products> productsList = new Products().queryToObjectList(" select * from iptv_products where status = 1 " ); for(int i = 0 ; i < productsList.size() ; i ++){ Products products = productsList.get(i); ClientData.productsList.put(products.getProductsId(),products); } //定时清楚用户 Date currentTime = new Date(); long cTime = currentTime.getTime(); Iterator<Map.Entry<String, JSONObject>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, JSONObject> entry = it.next(); JSONObject value=entry.getValue(); long lTime = value.getLong("time"); //将大于一分钟未发起订购的用户清掉 System.out.println(entry.getKey()+"="+(cTime-lTime)); if((cTime-lTime)>=(1000*60)){ // 使用迭代器的remove()方法删除元素 it.remove(); } }
那么重点来了,就是。 对象怎么设置。 当然也可以不用注解,但是命名规则就需要按照JPA的命名规则来, IptvUserName = t_iptv_user_name 数据库的表名称就是这个了,而属性字段就是 userName = user_name 。 这样进行对应的。所有命名规则都是属性名称不能大写。如果首字母大写例如 UserName = user_name。
package com.ynwl.clientdata.model; import com.ynwl.clientdata.api.interfaces.SqlColumn; import com.ynwl.clientdata.api.interfaces.Sqltable; import java.util.Date; /** * @创建人: 杨英 * @创建时间: 2018/3/19 15:45 * @描述: 用户生成订单的对象 */ @Sqltable( name = "iptv_monthpackorder") public class MonthpackOrder extends Model<MonthpackOrder>{ @SqlColumn(name="id") private int id; @SqlColumn(name="OrderID") private String orderNo; @SqlColumn(name="UserName") private String userId ; @SqlColumn(name="InTime") private Date inTime ; @SqlColumn(name="ProductID") private String productId ; @SqlColumn(name="ProductName") private String productName ; @SqlColumn(name="GameID") private String gameId ; @SqlColumn(name="Fee") private String fee ; @SqlColumn(name="PayResult") private int payResult ; @SqlColumn(name="userToken") private String userToken ; @SqlColumn(name="manthpakBackUrl") private String manthpakBack ; @SqlColumn(name="Notify") private int notify = 0; public int getNotify() { return notify; } public void setNotify(int notify) { this.notify = notify; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo = orderNo; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public Date getInTime() { return inTime; } public void setInTime(Date inTime) { this.inTime = inTime; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getGameId() { return gameId; } public void setGameId(String gameId) { this.gameId = gameId; } public String getFee() { return fee; } public void setFee(String fee) { this.fee = fee; } public int getPayResult() { return payResult; } public void setPayResult(int payResult) { this.payResult = payResult; } public String getUserToken() { return userToken; } public void setUserToken(String userToken) { this.userToken = userToken; } public String getManthpakBack() { return manthpakBack; } public void setManthpakBack(String manthpakBack) { this.manthpakBack = manthpakBack; } }
这样就可以了。查询和保存,修改的方法。不提供删除的方法,删除自己直接用Db.delete();就可以了,不用封装
package com.xchenm.jfinalshar.model; import com.alibaba.fastjson.JSON; import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.Record; import com.xchenm.jfinalshar.api.interfaces.SqlColumn; import com.xchenm.jfinalshar.api.interfaces.Sqltable; import org.apache.commons.beanutils.BeanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * @author yang * @创建人: 杨英 * @创建时间: 2018/3/20 17:16 * @描述: */ public class Model<T> { private final Logger log = LoggerFactory.getLogger(Model.class); private Map<String,Object> cuont; private SimpleDateFormat simdfhh = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private SimpleDateFormat simdfhh2 = new SimpleDateFormat("yyyy-MM-dd"); public T save() { //获取对象对应的表 String table = getTableName(); //获取属性对应的字段 this.cuont = getColumnName(); Record record = setRecord(new Record()); String cuontKey = "id"; String cuontVal = "0"; String cuontVal2 = "null"; if("".equals(cuont.get(cuontKey)) || cuontVal.equals(cuont.get(cuontKey)) || cuontVal2.equals(cuont.get(cuontKey)) || cuont.get(cuontKey) == null){ Db.save(table,record); }else{ record = setRecord(Db.findById(table, cuont.get(cuontKey))); Db.update(table,record); } return queryToObject(record); } /** * 如果对象有id 值,那么返回整个属性信息 * */ public T finById(){ //获取对象对应的表 String table = getTableName(); //获取属性对应的字段 this.cuont = getColumnName(); String cuontKey = "id"; return queryToObject("select * from "+table+" where "+cuontKey+" = "+cuont.get(cuontKey)); } private Record setRecord(Record record){ Iterator<Map.Entry<String, Object>> it = cuont.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Object> entry = it.next(); if(!"id".equals(entry.getKey())){ record.set(entry.getKey(),entry.getValue()); } } return record; } /** * 返回单个对象 * */ public T queryToObject(String sql){ List<T> outputList = queryToObjectList(sql); if(outputList.size() > 0){ return outputList.get(0); } return null; } /** * 返回对象集合 * **/ public List<T> queryToObjectList(String sql) { List<T> outputList = new ArrayList<T>(); List<Record> rs = Db.find(sql); try { // 判断结果是否为空 if (rs != null) { // 遍历结果集 for(int i = 0 ; i < rs.size() ; i ++){ outputList.add( queryToObject(rs.get(i))); } } else { return null; } } catch (Exception e) { e.printStackTrace(); } return outputList; } /** * 返回单个对象 * */ public T queryToObject(Record record){ T bean = null; try { // 判断结果是否为空 if (record != null) { // 得到属性 Field[] fields = this.getClass().getDeclaredFields(); //得到每一个对象 //泛型实现对象序列化,类似于new bean = (T) this.getClass().newInstance(); //得到对象的数组集合 数据库字段,数据库值 Map<String ,Object > map = record.getColumns(); for (Field field : fields) { //显示Key String colName = getColumnName(field); Object columnValue =getObject(field, map.get(colName),1); //通过注解的名称对应注解的属性 if (columnValue != null) { try { BeanUtils.setProperty(bean, field.getName(), columnValue); }catch (Exception e){ System.out.println(" name "+ colName+" columnValue " + columnValue); e.printStackTrace(); } } } } else { // 返回错误结果 } } catch (Exception e) { e.printStackTrace(); } return bean; } /** * 显示数据库表字段名 * 如果有注解,显示注解字段, * 如果没有,那么就用_这种默认显示操作。 * */ private String getColumnName(Field field) { try{ SqlColumn annotation = (SqlColumn) field.getAnnotation(SqlColumn.class); if(annotation!= null){ return annotation.name(); } }catch(Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return nameString(field.getName(),1); } /** * 显示数据库表名。 * 如果有注解,显示注解内容, * 如果没有注解,显示默认数据库命名规则。 IptvUserName = t_iptv_user_name * */ private String getTableName() { Class userCla; userCla = (Class) this.getClass(); Sqltable annotation = (Sqltable) userCla.getAnnotation(Sqltable.class); if(annotation!= null){ return annotation.name(); } String[] clazzName = userCla.getName().split("\\."); return nameString( clazzName[clazzName.length-1],0); } /** * 显示默认数据库命名规则。 IptvUserName = t_iptv_user_name * 显示默认数据库字段命名规则。 UserName = user_name * */ private String nameString(String filedName,int t){ StringBuffer filedNewName = new StringBuffer(); for(int i=0;i<filedName.length();i++){ if((byte)filedName.charAt(i)>64&&(byte)filedName.charAt(i)<91){ if(i == 0){ if(t == 0) { filedNewName.append("t_").append(String.valueOf(filedName.charAt(i)).toLowerCase()); }else{ filedNewName.append(String.valueOf(filedName.charAt(i)).toLowerCase()); } }else{ filedNewName.append("_").append(String.valueOf(filedName.charAt(i)).toLowerCase()); } }else{ filedNewName.append(filedName.charAt(i)); } } return filedNewName.toString(); } /** * 获得列名 * @return Map<数据库字段,对象值> */ @SuppressWarnings("unchecked") private Map<String,Object> getColumnName() { Map<String,Object> map = null; try{ Class clazz = (Class) this.getClass(); //根据Class对象获得属性 私有的也可以获得 Field[] fields = clazz.getDeclaredFields(); map = new HashMap<String,Object>(fields.length); for(int i=0;i<fields.length;i++){ String firstLetter = fields[i].getName().substring(0, 1).toUpperCase(); String getter = "get" + firstLetter + fields[i].getName().substring(1); try { Method method = this.getClass().getMethod(getter, new Class[]{}); Object value = getObject(fields[i], method.invoke(this, new Object[]{}),0) ; if(value != null){ map.put(getColumnName(fields[i]), String.valueOf(value)); } }catch (Exception e){ e.printStackTrace(); } } }catch(Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return map; } /** * 类型转化 * */ private Object getObject(Field field,Object columnValue,int o) throws ParseException { if(columnValue == null){return null;} String type = "class java.lang.Integer"; String type1 = "class java.util.Date"; String type3 = "class java.lang.String"; if(field.getGenericType().toString().equals(type)){ if(columnValue == null){ columnValue = 0 ; } }else if (field.getGenericType().toString().equals(type1)) { if(o == 0){ try { columnValue = simdfhh.format(columnValue); }catch (Exception e){ columnValue = simdfhh2.format(columnValue); } }else{ try { columnValue = simdfhh.parse( String.valueOf(columnValue) ); }catch (Exception e){ columnValue = simdfhh2.parse( String.valueOf(columnValue) ); } } }else if(field.getGenericType().toString().equals(type3)){ if(columnValue == null){ columnValue = ""; } }else{ if(columnValue == null){ columnValue = 0.00; } } return columnValue; } @Override public String toString(){ return JSON.toJSONString(this); } }
好吧,我还需要优化,这个部分的代码可能对性能之类的有影响,明显对象创建过多了,怎么进行优化,求大神指教
贴出两个注解
package com.ynwl.clientdata.api.interfaces; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * @创建人: 杨英 * @创建时间: 2018/3/16 15:14 * @描述: */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface SqlColumn { /** * (Optional) The name of the column. Defaults to * the property or field name. */ String name() default ""; }
package com.ynwl.clientdata.api.interfaces; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * @创建人: 杨英 * @创建时间: 2018/3/16 14:55 * @描述: */ @Target(TYPE) @Retention(RUNTIME) public @interface Sqltable { String name() default ""; }
项目:Jfinal jpa