微服务(四)--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 {}
阅读全文
0 0
- 微服务(四)--dao层一
- php框架开发四(DAO层)
- 微服务(四)
- 微服务(一)
- 微服务(一)--Common
- JavaEE中的MVC(一)Dao层彻底封装
- ssm框架搭建(一)-Dao层搭建-mybatis
- SSH框架——(二)四层结构:DAO,Service,Controller,View层
- mybatis基于Dao层开发(四)
- 微服务四篇文章
- 微服务指南走北(一):微服务是什么
- 微服务架构学习笔记(一)
- SpringBoot搭建微服务(一)HelloWorld!
- 我也来谈微服务(一)
- 微服务时代---Dubbo(一)
- 微服务设计笔记(一)
- 读书笔记《微服务一》
- 什么是微服务?(一)
- SSL_2295 暗黑破坏神(动规练习题)
- ios开发关于多线程编程的理解(一)
- html解析json数据为表格table显示
- <c:foreach>同时遍历两个list的方法
- (PTA详解)L1-004. 计算摄氏温度
- 微服务(四)--dao层一
- 【C#编程最佳实践 六】数据库操作相关实践
- PostMessage和PostThreadMessage区别
- 大话项目管理工具之Maven篇
- 数据结构与算法_选择排序
- document.getElementById和docuement.querySelector的区别
- 不可滑动的 Listview(NoScrollListView)
- pyspark之MLlib学习【加载和转换数据】(1)
- android Path.setFillType(Path.FillType ft) 设置填充方式