Spring Data开发手册|手摸手教你简化持久层开发工作

简介: Spring Data,是为数据访问提供熟悉且一致的基于Spring的编程模型,同时仍然保留底层数据存储的特殊特性。它是对于数据访问技术,关系数据库和非关系数据库,map-reduce框...

 image.gif

image.gif

Spring Data,是为数据访问提供熟悉且一致的基于Spring的编程模型,同时仍然保留底层数据存储的特殊特性。

它是对于数据访问技术,关系数据库和非关系数据库,map-reduce框架和基于云的数据服务变得容易。Spring Data是一个总括项目,其中包含很多特定于数据库相关的子项目

网络异常,图片无法展示
|
image.gif

首先,先带大家看一下本篇文章的大致介绍。

没目录怎么知道这篇到底有多少干货呢?

    • Spring Data是什么
    • Spring Data能干什么
    • Spring Data的第一个HelloWorld程序
    • 通过名字来确定方法
    • 通过注解的形式来实现查询
    • 写本地的SQL查询
    • 增删改的玩法
    • 使用框架中提供的增删改查的方法
    • 分页和排序
    • JpaRepository的使用

    是不是很清晰呢,现在开始进入正文,一个一个来:

    Spring Data是什么

    我们传统的开发中,我们的整个DAO层的代码上都是相对来说,都是比较复杂的,在这种情况下,Spring团队就考虑到一个问题,能不能开发一个框架,这个框架能够最大限度的减少DAO层的开发呢?

    Spring Data就是为了简化DAO层操作的一个框架

    传统的增删改查在我们的Spring Data中已经实现了,也就是说大部分的DAO层操作部分不用写了,仅仅只是需要编写复杂的业务的调用就可以啦

    网络异常,图片无法展示
    |
    image.gif

    写的这部分的代码,是需要写接口的声明就可以啦,不用写实现,这个实现是自动实现的

    Spring Data能干什么

    主要用途:

      • 传统的增删改查
      • 排序
      • 分页
      • 排序后分页

      即使你需要写DAO,也只是写声明就可以啦,不用写实现

      Spring Data的第一个HelloWorld程序(JPA、Hibernate、Spring、SpringMVC、Spring Data)

      导包

      网络异常,图片无法展示
      |
      image.gif

      编写配置文件

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop.xsd
              http://www.springframework.org/schema/data/jpa 
              http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd">
              <!--引入Properties文件-->
              <context:property-placeholder location="classpath:config/db.properties"/>
              <!--配置c3p0的连接池-->
              <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                  <property name="driverClass" value="${driverClass}"></property>
                  <property name="jdbcUrl" value="${url}"></property>
                  <property name="user" value="${user}"></property>
                  <property name="password" value="${password}"></property>
                  <property name="acquireIncrement" value="${acquireIncrement}"></property>
                  <property name="maxPoolSize" value="${maxPoolSize}"></property>
                  <property name="minPoolSize" value="${minPoolSize}"></property>
                  <property name="maxStatements" value="${maxStatements}"></property>
              </bean>
              <!--配置JPA实现产品的适配器-->
              <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
              </bean>
              <!--配置EntityManager对象-->
              <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                 <!--注入数据源-->
                 <property name="dataSource" ref="dataSource"></property>
                 <!--扫描entity包的--> 
                 <property name="packagesToScan" value="com.qy.helloworld"></property>
                 <!--注入JPA实现产品的适配器-->
                 <property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
                 <!--配置的是Hibernate的其他配置  除了连接数据库4大要素之外的其余配置-->
                 <property name="jpaProperties">
                    <props>
                     <!--是否自动创建表 -->
                     <prop key="hibernate.hbm2ddl.auto">update</prop>
                     <!--配置是否展示SQL-->
                     <prop key="hibernate.show_sql">true</prop>
                     <!--是否格式化SQL-->
                     <prop key="hibernate.format_sql">true</prop>
                     <!--连接数据库的方言-->
                     <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                  </props>
                 </property>
              </bean>
              <!--配置事务环境-->
              <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                 <!--注入dataSource-->
                 <property name="dataSource" ref="dataSource"></property>
                 <!--注入entityManagerFactory对象-->
                 <property name="entityManagerFactory" ref="entityManagerFactory"></property>
              </bean>
              <!--使用事务-->
              <tx:annotation-driven transaction-manager="jpaTransactionManager"/>
              <!--配置AOP的自动代理-->
              <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 
              <!--配置Spring的包扫描-->
              <context:component-scan base-package="com.qy.helloworld"></context:component-scan>
              <!--Spring data的包的扫描  这里的扫描扫描的是DAO层所在的位置-->
              <jpa:repositories base-package="com.qy.helloworld" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="jpaTransactionManager"></jpa:repositories>
      </beans>

      image.gif

      编写实体类和映射

      @Entity
      @Table(name="t_user")
      public class User {
       @Id
       @GeneratedValue(strategy=GenerationType.IDENTITY)
       private int userId;
       private String userName;
       private String password;
      }

      image.gif

      编写Repository类

      public interface UserRepository extends Repository<User,Integer>{
       /**
        * 这个的意思是通过id找用户
        * @Title: getByUserId   
        * @Description: TODO
        * @param: @param userId
        * @param: @return      
        * @return: User      
        * @throws
        */
       public User getByUserId(int userId);
      }

      image.gif

      测试

      ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserRepository userRepository=applicationContext.getBean(UserRepository.class);
       User users=userRepository.findByUserId(1);
      }

      image.gif

      通过名字来确定方法

      代码演示:

      举例如下

      public interface UserRepository extends Repository<User,Integer>{
       /**
        * 这个的意思是通过id找用户
        * @Title: getByUserId   
        * @Description: TODO
        * @param: @param userId
        * @param: @return      
        * @return: User      
        * @throws
        */
       public User getByUserId(int userId);
       /**
        * 记住查询的开头只能是  get 或者  find 开头   By:通过什么查询
        * @Title: findByUserId   
        * @Description: TODO
        * @param: @param userId
        * @param: @return      
        * @return: User      
        * @throws
        */
       public User findByUserId(int userId);
       /**
        * 通过用户名的模糊查询
        * @Title: findByUserNameLike   
        * @Description: TODO
        * @param: @param userName
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       public List<User> findByUserNameLike(String userName);
       /**
        * 通过用户名和密码的Like来进行查询
        * @Title: findByUserNameLikeAndPasswordLike   
        * @Description: TODO
        * @param: @param userName
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       public List<User> findByUserNameLikeAndPasswordLike(String userName,String password);
       /**
        * 用户名和密码like 然后id小于一个范围
        * @Title: findByUserNameLikeAndPasswordLikeAndUserIdLessThan   
        * @Description: TODO
        * @param: @param userName
        * @param: @param password
        * @param: @param userId
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       public List<User> findByUserNameLikeAndPasswordLikeAndUserIdLessThan(String userName,String password,int userId);
      }

      image.gif

      注意:一般情况下不会通过名字直接来写相应的方法,因为如果条件过多那么这个时候我们就存在名字特别长的问题

      通过注解的模式来实现查询

      代码演示:

      举例如下

      /**
           * 查询所有  没有条件直接查询
           * @Title: findUserAll   
           * @Description: TODO
           * @param: @return      
           * @return: List<User>      
           * @throws
           */
       @Query("from User")
       public List<User> findUserAll();
       /**
        * 通过id来查找数据     参数直接拼接到后面
        * @Title: findUserById   
        * @Description: TODO
        * @param: @param userId
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       @Query("from User u  where u.userId<3")
       public List<User> findUserById();
       /**
        * 通过id查询存在占位符的情况
        * @Title: findUserById1   
        * @Description: TODO
        * @param: @param userId
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       @Query("from User u  where u.userId<?")
       public List<User> findUserById1(int userId);
       /**
        * 多条件的查询  可以指定当前的参数映射的这个位置
        * @Title: getUserByNameAndId   
        * @Description: TODO
        * @param: @param userName
        * @param: @param userId
        * @param: @return      
        * @return: User      
        * @throws
        */
       @Query("from User u where u.userId=?2 and u.userName=?1")
       public User getUserByNameAndId(String userName,int userId);
       /**
        * 模糊查询的时候动态拼接上  %的问题
        * @Title: findUserByLike1   
        * @Description: TODO
        * @param: @param userName
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       @Query("from User u where u.userName like concat ('%',?,'%')")
       public List<User> findUserByLike1(String userName);

      image.gif

      写本地的SQL 查询

      代码演示:

      举例如下

      /**
        * 通过
        * @Title: findUserAll11   
        * @Description: TODO
        * @param: @return      
        * @return: List<User>      
        * @throws
        */
       @Query(nativeQuery=true,value="select * from t_user")
       public List<User> findUserAll11();

      image.gif

      增删改的玩法

      代码演示:

      添加业务逻辑 增加事务环境

      @Service
      @Transactional                  //提供一个事务的环境
      public class UserService {
       @Autowired
       private UserRepository userRepository=null;
       /**
        * 数据的更新
        * @Title: update   
        * @Description: TODO
        * @param: @param userName
        * @param: @param password
        * @param: @param userId      
        * @return: void      
        * @throws
        */
       public void update(String userName,String password,int userId){
        userRepository.update(userName, password, userId);
       }
       public void delete(int userId){
        userRepository.delete(userId);
       }
       public void insert(String userName,String password){
        userRepository.insert(userName, password);
       }
      }

      image.gif

      编写repository的对象

      public interface UserRepository extends Repository<User,Integer>{
       /**
        * 实现增删改的方法
        * @Title: add   
        * @Description: TODO
        * @param: @param userName
        * @param: @param password      
        * @return: void      
        * @throws
        */
       @Modifying    //这个注解的作用表示的是更新数据
       @Query("update User u set u.userName=?,u.password=? where u.userId=?")
       public void update(String userName,String password,int userId);
       /**
        * 更新数据
        * @Title: delete   
        * @Description: TODO
        * @param: @param userId      
        * @return: void      
        * @throws
        */
       @Modifying    //这个注解的作用表示的是更新数据
       @Query("delete User u where u.userId=?")
       public void delete(int userId);
       /**
        * 添加数据
        * @Title: insert   
        * @Description: TODO
        * @param: @param userName
        * @param: @param password      
        * @return: void      
        * @throws
        */
       @Modifying    //这个注解的作用表示的是更新数据
       @Query(nativeQuery=true,value="insert into t_user(userName,password) values(?,?)")
       public void insert(String userName,String password);
      }

      image.gif

      测试

      @Test
       public void testHelloWorld() throws Exception {
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserService userService=applicationContext.getBean(UserService.class);
        userService.insert("小羽","做程序的");
       }

      image.gif

      使用框架中提供的增删改查的方法

      代码演示:

      提供的是Repository

      public interface UserRepository extends CrudRepository<User,Integer>{
      }

      image.gif

      分页和排序

      代码演示:

      提供的Repository

      public interface UserRepository extends PagingAndSortingRepository<User,Integer>{
      }

      image.gif

      测试

      public class Test001 {
       @Test
       public void testPaging() throws Exception {
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserRepository userRepository=applicationContext.getBean(UserRepository.class);
       /**
        * 第一个参数:当前的页的页数是多少  页数是从0开始的   第二页:2-1
        * 第二个参数:表示的是每一页条目数
        */
        Page<User> pages=userRepository.findAll(new PageRequest(2-1,2));
        System.out.println("查询到的数据:"+pages.getContent());
        System.out.println("数据的条目数:"+pages.getSize());
        System.out.println("页数:"+pages.getNumber());
        System.out.println("数据条目的总数:"+pages.getTotalElements());
        System.out.println("一共的页数:"+pages.getTotalPages());
        System.out.println("排序的规则:"+pages.getSort());
       }
       /**
        * 排序
        * @Title: testSort   
        * @Description: TODO
        * @param: @throws Exception      
        * @return: void      
        * @throws
        */
       @Test
       public void testSort() throws Exception {
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserRepository userRepository=applicationContext.getBean(UserRepository.class);
        /**
         * 排序
         * 第一个参数:升序或者降序  Direction.ASC/DESC
         * 第二个参数: 排序的这个列
         */
        List<User> users=(List<User>) userRepository.findAll(new Sort(Direction.DESC,"userId"));
        System.out.println(users);
       }
       /**
        * 排序后分页
        * @Title: testSortAndPaging   
        * @Description: TODO
        * @param: @throws Exception      
        * @return: void      
        * @throws
        */
       @Test
       public void testSortAndPaging() throws Exception {
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserRepository userRepository=applicationContext.getBean(UserRepository.class);
        Page<User> pages=userRepository.findAll(new PageRequest(2-1,2,new Sort(Direction.DESC,"userId")));
        System.out.println(pages.getContent());
       }
      }

      image.gif

      JpaRepository的使用

      代码演示:

      提供的repository

      public interface UserRepository extends JpaRepository<User,Integer>{
      }

      image.gif

      测试

      public class Test001 {
       @Test
       public void testPaging() throws Exception {
        ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
        //获取DAO的对象
        UserRepository userRepository=applicationContext.getBean(UserRepository.class);
      //  long count=userRepository.count();
      //  User user=userRepository.findOne(15);
      //  user.setUserName("小羽");
        //保存或者更新数据
      //  userRepository.saveAndFlush(user);
        List<User> users=userRepository.findAll();
        //批处理
        userRepository.deleteInBatch(users);
        //System.out.println("统计:"+count);
       }
      }

      image.gif

      结语

      Spring Data是我们开发中离不开的经常用到的技术,其涉及的技术和知识面其实远不止上面列出的这些。

      后续浅羽会继续更新关于Spring Data的开发知识,只希望能对大家有所帮助,谢谢大家的支持!

      写作秉持初心,致力于让每一位互联网人共同进步。


      image.gif

      image.gif

      点点点,一键三连都在这儿!

      目录
      打赏
      0
      0
      0
      0
      33
      分享
      相关文章
      |
      2月前
      |
      使用Java和Spring Data构建数据访问层
      本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
      86 21
      SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
      智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
      SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
      Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
      63 6
      Spring AI Alibaba + 通义千问,开发AI应用如此简单!!!
      本文介绍了如何使用Spring AI Alibaba开发一个简单的AI对话应用。通过引入`spring-ai-alibaba-starter`依赖和配置API密钥,结合Spring Boot项目,只需几行代码即可实现与AI模型的交互。具体步骤包括创建Spring Boot项目、编写Controller处理对话请求以及前端页面展示对话内容。此外,文章还介绍了如何通过添加对话记忆功能,使AI能够理解上下文并进行连贯对话。最后,总结了Spring AI为Java开发者带来的便利,简化了AI应用的开发流程。
      2508 0
      阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手
      本次分享的主题是阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手,由阿里云两位工程师分享。
      140 0
      阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手
      建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
      智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
      122 7
      |
      3月前
      |
      Spring Boot 开发中常见的错误
      本文总结了 Java 开发中常见的几个问题及其改进方法,包括:1. 过度使用 `@Component` 注解;2. `@ResponseBody` 注解的错误用法;3. `@Autowired` 的不当使用;4. `application.properties` 管理不善;5. 异常处理不当。每部分详细解释了错误情况和建议的改进方案,并提供了相应的代码示例。
      80 11
      互联网应用主流框架整合之Spring Boot开发
      通过本文的介绍,我们详细探讨了Spring Boot开发的核心概念和实践方法,包括项目结构、数据访问层、服务层、控制层、配置管理、单元测试以及部署与运行。Spring Boot通过简化配置和强大的生态系统,使得互联网应用的开发更加高效和可靠。希望本文能够帮助开发者快速掌握Spring Boot,并在实际项目中灵活应用。
      97 5
      这款免费 IDEA 插件让你开发 Spring 程序更简单
      Feign-Helper 是一款支持 Spring 框架的 IDEA 免费插件,提供 URL 快速搜索、Spring Web Controller 路径一键复制及 Feign 与 Controller 接口互相导航等功能,极大提升了开发效率。
      如何使用 Spring Boot 和 Angular 开发全栈应用程序:全面指南
      如何使用 Spring Boot 和 Angular 开发全栈应用程序:全面指南
      99 1
      AI助理

      你好,我是AI助理

      可以解答问题、推荐解决方案等