AI智能
改变未来

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

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

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

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

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

  • Spring Data是什么

  • Spring Data能干什么

  • Spring Data的第一个HelloWorld程序

  • 通过名字来确定方法

  • 通过注解的形式来实现查询

  • 写本地的SQL查询

  • 增删改的玩法

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

  • 分页和排序

  • JpaRepository的使用

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

Spring Data是什么

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

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

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

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

Spring Data能干什么

主要用途:

  • 传统的增删改查

  • 排序

  • 分页

  • 排序后分页

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

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

导包

编写配置文件

 <?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>

编写实体类和映射

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

编写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);}

测试

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

通过名字来确定方法

代码演示:

举例如下

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);}

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

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

代码演示:

举例如下

 /**     * 查询所有  没有条件直接查询     * @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);

写本地的SQL 查询

代码演示:

举例如下

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

增删改的玩法

代码演示:

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

 @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); }}

编写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); }

测试

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

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

代码演示:

提供的是Repository

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

分页和排序

代码演示:

提供的Repository

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

测试

 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()); }}

JpaRepository的使用

代码演示:

提供的repository

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

测试

 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); }}

结语

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

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

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

往期好文

往期推荐

Spring Data开发手册|Java持久化API(JPA)需要了解到什么程度呢?

动态资源技术JSP|Java与Html的美好相遇

尚能饭否|技术越来越新,我对老朋友jQuery还是一如既往热爱

告别祈祷式编程|单元测试在项目里的正确落地姿势

组件必知必会|那些年我们使用过的轮子—Filter和Proxy

ES开发指南|如何快速上手ElasticSearch

玩转Redis|学会这10点让你分分钟拿下Redis,满足你的一切疑问

超级详细|Linux系统下从0到1的玩法大全

如果你觉得浅羽的文章对你有帮助的话,请在微信搜索并关注「 浅羽的IT小屋 」微信公众号,我会在这里分享一下计算机信息知识、理论技术、工具资源、软件介绍、后端开发、面试、工作感想以及一些生活随想等一系列文章。所见所领,皆是生活。慢慢来,努力一点,你我共同成长…

 

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

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Spring Data开发手册|手摸手教你简化持久层开发工作