微服务(四)--dao层一

目录

在众多的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

@MappedSuperclass
public 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对象中的非空字段值查询 全部记录

@NoRepositoryBean
public 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 的整合, 

具体的使用

@Service
public class PaymentRefundFlowUnionpayServiceImpl extends UnexBaseServiceImpl<PaymentRefundFlowUnionpayPo>
                implements IPaymentRefundFlowUnionpayService {

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值