疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

spring data 概述


 

 
由于自己一个项目要用多到Sql与NoSql两种截然不同的数据结构,但在编程上我希望统一接口API,让不同类型的数据库能在相同的编程接口模式下运作。于是找了一个spring的官网,发现一个spring data的项目。Spring Data 统一所有访问数据库的接口,为开发者提供一个更加简便的开发方式  Spring Data 官网
 
  下面是几个核心的项目介绍
 
Spring Data Commons - 每个Spring Data 项目的核心基础 (因此每一个Spring Data项目都使用统一的接口)
Spring Data Gemfire - 以Spring 的方式 提供GemFire 的简单配置和访问
Spring Data JPA - 简化所有JPA标准数据库访问和操作(例如Hibernate MyBatis等等)
Spring Data KeyValue - 简化所有以Map结构数据库及SPIs服务的构建Spring Data 模块  
Spring Data LDAP - 提供 Spring LDAP.的基础支持
Spring Data MongoDB -  为文档数据库 构建以Spring 基础的支持和数据访问组件
Spring Data REST - 可以把Spring 数据仓库 输出为超媒体的形式的RESTFUL 资源
Spring Data Redis - 提供简便的方式访问Redis
Spring Data for Apache Cassandra - Apache Cassandra 的 Spring Data 模块
Spring Data for Apache Solr - Apache Solr 的 Spring Data 模块
 
 
   在Spring Data 以前我们要实现在对一个数据库的通常是这样的
 
我们首先来写一个接口来说明我们要对数据库操作什么,然后使用泛型(T)来传入要保存实体类型,以hibernate为例  
 
复制代码
public interface CommonDao{ 
        //保存实体
        public <T> Serializable save(T entity);
    
        //保存或更新实体   
        public <T> void saveOrUpdate(T entity);            
 
        //获取一个实体对象   
        public <T> get(Class<T> entityName, Serializable id);
 
     
  
}
复制代码
 
 
但我们还要写一个具体实现类,因为你只是告诉了用户可以干什么,但没有告诉后端该怎进行 增删改查
 
复制代码
public CommonDaoImpl implments CommonDao{
       //Hibernate Session
        @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;
 
    public Session getSession() {
        // 事务必须是开启的(Required),否则获取不到
        return sessionFactory.getCurrentSession();
    }
 
    
   public Serializable save(T entity){
             try{
               Serializable id = getSession().save(entity);
              getSession().flush();
         return id 
             }catch(Exception e){
         ........            
   }
       
      }
 
  public <T> saveOrUpdate(T entity){
    //保存或更新事务代码
  }
 
  public <T> get(T entity,Serializable id){
    //获取单个实体代码
 
  }
   
}    
复制代码
 
 
 编写一个数据服务接口,便于隐藏具体实现
 
复制代码
public interface CommonService{
 
      // 保存实体
      public <T> Serializable save(T entity);  
 
      // 保存或更新  
      public <T> void saveOrUpdate(T entity) ;
 
      // 其他数据新增改查方法
}
复制代码
 
 
编写一个公共数据服务实现类
 
复制代码
@Service
public class CommonServiceImpl{
     
     //数据访问接口
     @Autowired
     public CommonDao  commonDao;
     
     //保存实体实现
     public <T> Serializable save(T entity){
           //使用数据
           commonDao.save(entity);
     }     
    
      //保存或更新
      public <T> void saveOrUpdate(T entity){
           //保存或更新实体
           commonDao.saveOrUpdate(entity);  
      }
 
       //其他服务方法
}
复制代码
 
 
 
 
 
 
 编写一个指定模型接口
 
复制代码
 
public interface UserService extends CommonService
      //继承父类所有增删改查接口
      //新增接口
      public User getMyUser(String id); 
 
      public List<User> getUserByUsername(String username);
    //.....其他用户方法
 
        
}
复制代码
 
 
对方法进行@Service //用注释进行组件注入 实现Sprign对接口的管理 
 
复制代码
public class UserServiceImpl extends CommonServiceImpl  implments CommonService{
      
               
     /**
     * 重写父类保存实体方法
     **/ 
     public <T> Serializable save(T entity) {
 
     //对User进行前置业务处理
     ........
     this.save(User(entity));//保存user
    
    //返回保存信息 
    } 
     
    /**
    * 获取单个User对象
    **/
    public User getUser(String id){
       this.get(User.class,id);
    }
 
    /**
     *自定义用户搜索
     **/
    public User getUserByUsername(String username){
 
        //定制实现 
         //hql 实现
         //String hql = "from User u where u.password = ?  "
        // List<User> users = this.queryByHql(password); 
        //判断users存不存在
        //if(users!=null&&users.size>0)
          return users.get(0);
         
          return null;
          
   }
 
 
 
      
 
 
 
}
复制代码
 
 
这时我们才算实是完成一个完整的数据服务,我们会回顾一下这个编码步骤
 
1、编写数据访问层通用接口
 
2、编写数据访问层通用实现
 
3、编写通用服务接口
 
4、编写通用服务实现(包括定制查询,定制hql 或者 封装criteria)
 
5、转化为pojo
 
 
 
以上就是传统j2ee crud的编码过程。
 
接下来我们要介绍我们今天的主角,Spring-data
 
看完上面的一堆代码是不是觉得好烦,为什么呢?因为老子又要写接口,又要写实现,写接口告诉客户干什么,然后又写了一个实现告诉java虚拟机要对计算机干什么。这里需要增加了java 的工程性(使用接口把实现和行为本身分开),减轻了使用者的使用成本,也增加了软件的可维护性扩展性。对于庞大而又复杂的系统来说,这是一个稳健的做发。但是这毫无疑问地增加了开发成本。1、接口和实现本身的代码量增加。2、需求和设计不明确,导至接口扩展,其实实现也必须扩展。所谓接口就是 java工程的命门。接口的制定者往往是最有经验的工程师。因为这些东西实在太影响效率了。于是spring-data诞生了。spring-data 的意思是,你只需要在接口里告诉spring你要查询什么,你要一个什么样的查询,它便帮你实现了。你不用自己再去写查询语句。不用再拼接复杂的查询,如果你根据你的姓氏去查询这个人,你只需要写,那一切就像变魔术一样。获取到一个对象列表
 
interface PersonRepository extends Repository<Person, Long> {
  List<Person> findByLastname(String lastname);
}
  你不用再去写你dao实现,再见了hql,再见了sql,再见了criteria ,一切来得这么简洁。到此spring data 为我们做了什么?来我们来回顾一下数据库与java之前间交互的发展历程
 
 
 
  从图中可以看我们数据库操作要解决的问题的一个大概历程,spring-data实现了重要的一步,把各orm的框架的实现都隐藏掉,把查询规则和查询接口统一起来,就是行为即实现,由接口去定义数据库的查询实现,而你更不需要关注你使用的是哪个orm框架,因为查询模型(使用统一接口)和返回模型都是统一的,而orm,查询封装这些spring-data通通帮你处理了。
 
以下为spring-data的接口规则
 
    Logical keyword
 
  Keyword expressions
AND
 
And
 
OR
 
Or
 
AFTER
 
After, IsAfter
 
BEFORE
 
Before, IsBefore
 
CONTAINING
 
Containing, IsContaining, Contains
 
BETWEEN
 
Between, IsBetween
 
ENDING_WITH
 
EndingWith, IsEndingWith, EndsWith
 
EXISTS
 
Exists
 
FALSE
 
False, IsFalse
 
GREATER_THAN
 
GreaterThan, IsGreaterThan
 
GREATER_THAN_EQUALS
 
GreaterThanEqual, IsGreaterThanEqual
 
IN
 
In, IsIn
 
IS
 
Is, Equals, (or no keyword)
 
IS_NOT_NULL
 
NotNull, IsNotNull
 
IS_NULL
 
Null, IsNull
 
LESS_THAN
 
LessThan, IsLessThan
 
LESS_THAN_EQUAL
 
LessThanEqual, IsLessThanEqual
 
LIKE
 
Like, IsLike
 
NEAR
 
Near, IsNear
 
NOT
 
Not, IsNot
 
NOT_IN
 
NotIn, IsNotIn
 
NOT_LIKE
 
NotLike, IsNotLike
 
REGEX
 
Regex, MatchesRegex, Matches
 
STARTING_WITH
 
StartingWith, IsStartingWith, StartsWith
 
TRUE
 
True, IsTrue
 
WITHIN
 
Within, IsWithin