微服务(四)--dao层一

来源:互联网 发布:java递归求n的阶乘 编辑:程序博客网 时间:2024/06/07 02:26

目录

在众多的orm框架中 ,mybatis 和 jpa 是我很喜欢的两个框架,我们试着将 mybatis和jpa 同时 引入到 工程中,mybatis负责复杂查询,jpa负责基本的crud 和排序分页之类的

底层建表规范

数据库是 mysql

create table T_DEMO_SAMPLE(   ID                   bigint(20) not null auto_increment comment 'ID',   SAMPLE_CODE          varchar(40) not null comment '示例编码',   SAMPLE_NAME          varchar(100) not null comment '示例名称',   UPDATE_USER          bigint(20) comment '更新者',   UPDATE_TIME          timestamp not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',   CREATE_USER          bigint(20) comment '创建者',   CREATE_TIME          timestamp not null default CURRENT_TIMESTAMP comment '创建时间',   LOGIC_DELETE         char(1) not null default '0' comment '逻辑删除:0-未删除 1-已删除',   primary key (ID));

所有表都必须 id 是默认主键,creat_user —直接是存储的 user的主键id , 逻辑删除 和 业务状态 ,业务删除 一般也是必须有,
所以 我针对这几个 属性有一个 basePo,并且 这个 basePo 被所有的Po所继承

基本 po

@MappedSuperclasspublic class UnexBasePo{    // ID    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Long id;     // 创建者    @Column(name = "CREATE_USER")    private Long createUser;     // 创建时间    private Date createTime;     // 更新者    @Column(name = "UPDATE_USER")    private Long updateUser;     // 更新时间    private Date updateTime;    // 逻辑删除: 0-未删除 1-已删除    private String logicDelete;

基本操作

针对这几个 基本的属性,我需要 进行基本的 crud 操作,
: 1。根据 entity对象中的非空字段值查询 单条记录
2。根据 entity对象中的非空字段值查询 全部记录

@NoRepositoryBeanpublic interface IUnexBaseRepository<Po extends UnexBasePo> extends PagingAndSortingRepository<Po, Long> { Po findByCondition(Po entity);  <T> List<T> queryByCondition(Po entity, Class<T> requiredType);}

实现类

public class UnexBaseDalImpl<Po extends UnexBasePo> extends SimpleJpaRepository<Po, Long> implements IUnexBaseRepository<Po> {    private final JpaEntityInformation<Po, ?> entityInformation;    private final EntityManager em;// 构造函数   public UnexBaseDalImpl(Class<Po> domainClass, EntityManager em) { this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);    }// 逻辑删除@Override    @Transactional    public void logicDelete(Long id) {        Assert.notNull(id, "The given id must not be null!");         Po po = findOne(id);        if (po == null) {            throw new UnexDalException(String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id));        } po.setLogicDelete(DalConstants.LOGIC_DELETE_TRUE);        po.setUpdateTime(DateUtil.now());        super.save(po);    }// 基本的查询 @Override    public Po findOne(Long id) {         return super.findOne(id);    }// 物理删除 @Override    @Transactional    public void delete(Long id) {        super.delete(id);    }// 查询@Override    @SuppressWarnings("unchecked")    public <T> T findByCondition(Po entity, Class<T> requiredType) {        Map<String, Object> params = new HashMap<String, Object>();         String querySql = UnexSqlUtil.sql_queryByCondition(entity, params);        if (logger.isDebugEnabled()) {            logger.debug("findByCondition SQL: [" + querySql + "]");            logger.debug("findByCondition PARAM:" + JSON.toJSONString(params));        }        Query query = em.createNativeQuery(querySql, requiredType);        query.setFirstResult(0);        query.setMaxResults(1);        this.setQueryParameters(query, params);        List<T> resultList = query.getResultList();        return CollectionUtils.isEmpty(resultList) ? null : resultList.get(0);    }// 为sql查询绑定查询参数 private void setQueryParameters(Query query, Map<String, Object> params) {        for (String key : params.keySet()) {            query.setParameter(key, params.get(key));        }    }

sql语句的拼写

你使用jpa ,难免会遇到自己写sql的情况,所以 自己写一个 生成sql语句的util 很有好处

 String querySql = UnexSqlUtil.sql_queryByCondition(entity, params);eg:   select *        from      po   where  1=1   and a=a and b=b //所以po 是需要动态的, and a=a 也是 动态的  ,于是 1=1 是一个 常量, and 也是   private static final String DEFAULT_CONDITION = " 1=1 ";     private static final String JOINT_AND = " AND ";    public static String sql_queryByCondition(Object entity, Map<String, Object> params) {        StringBuffer sb = new StringBuffer("SELECT * FROM ");          //  根据传入的对象,获取到其 数据库中的名字sb.append(getTableName(entity.getClass())).append(" WHERE " + DEFAULT_CONDITION);        Class<? extends Object> cls = entity.getClass();        while (null != cls) {            Field[] fields = cls.getDeclaredFields();            for (Field field : fields) {                appendCondition(sb, params, entity, field, JOINT_AND);            }            cls = cls.getSuperclass();        }        return sb.toString();    }// 根据 对象获取 其在数据库中的名字  ,实体类中 会有注解eg:@Entity(name = "T_NOTIFY_SCHE")public class NotifySchePo extends UnexBasePo {}    public static String getTableName(Class<? extends Object> clazz) {        Entity entity = clazz.getAnnotation(Entity.class);        if (entity != null) {            String name = entity.name().toUpperCase();            if (StringUtils.isNoneBlank(name)) {                return name;            }        }        Table table = clazz.getAnnotation(Table.class);        if (table != null) {            String name = table.name().toUpperCase();            if (StringUtils.isNoneBlank(name)) {                return name;            }        }        throw new UnexDalException("Entity define error!");    }// 为了 形成   and a=a and b=b 而且 tb_user  和TbUser 需要进行转化,于是 我需要将 遇到U时,将其变成 _u ,private static String getFieldName(String propertyName) {         StringBuffer sb = new StringBuffer();        for (byte b : propertyName.getBytes()) {            if (b >= 'a' && b <= 'z') {                // 小写字母转大写字母                sb.append((char) (b - 32));            } else if (b >= 'A' && b <= 'Z') {                // 大写字母前面加下划线                sb.append('_');                sb.append((char) b);            } else {                // 其他字符保留原样                sb.append((char) b);            }        }        return sb.toString();    }// 而且 我需要将 对象中的私有属性值 取出来,肯定需要用到 反射,于是 就需要用  getTbUser()  /*     * 把一个字符串的第一个字母大写     */    private static String getMethodName(String fildeName) {        byte[] items = fildeName.getBytes();        items[0] = (byte) ((char) items[0] - 'a' + 'A');        return new String(items);    }// 而且在 jpa 的底层sql中, String 和非 String 的传入方式是不一样的   private static void appendCondition(StringBuffer sb, Map<String, Object> params, Object entity, Field field, String joint) {        String propertyName = field.getName();       // 属性之上的 注解中的 列名        Column column = field.getAnnotation(Column.class);       // 表中之 列名          String fieldName = (null == column || StringUtil.isBlank(column.name())) ? getFieldName(propertyName) : column.name();        try {            Method readMethod = entity.getClass().getMethod("get" + getMethodName(propertyName));// 根据 反射中获得这个 方法            Object value = readMethod.invoke(entity);            if (value instanceof String) {                if (!StringUtil.isEmpty((String) (value))) {                    sb.append(joint).append(fieldName).append(" = :").append(propertyName);                    params.put(propertyName, value);                }            } else {                if (value != null) {                    sb.append(joint).append(fieldName).append(" = :").append(propertyName);                    params.put(propertyName, value);                }            }        } catch (Exception e) {            throw new UnexDalException("Entity define error!");        }    }
以上就是 jpa 的整合, 

具体的使用

@Servicepublic class PaymentRefundFlowUnionpayServiceImpl extends UnexBaseServiceImpl<PaymentRefundFlowUnionpayPo>                implements IPaymentRefundFlowUnionpayService {}
原创粉丝点击