Jfinal jpa

因为需求,不能对整个库里面的所有表做操作,也不用生成那么多对象,也不用所表里面所有字段进行操作。只需要对部分属性进行数据库映射,需要的操作,才进行展示,所以就想到了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 "";
}