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)
导包
编写配置文件
- <?xmlversion="1.0"encoding="UTF-8"?>
- <beansxmlns="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-placeholderlocation="classpath:config/db.properties"/>
- <!–配置c3p0的连接池–>
- <beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <propertyname="driverClass"value="${driverClass}"></property>
- <propertyname="jdbcUrl"value="${url}"></property>
- <propertyname="user"value="${user}"></property>
- <propertyname="password"value="${password}"></property>
- <propertyname="acquireIncrement"value="${acquireIncrement}"></property>
- <propertyname="maxPoolSize"value="${maxPoolSize}"></property>
- <propertyname="minPoolSize"value="${minPoolSize}"></property>
- <propertyname="maxStatements"value="${maxStatements}"></property>
- </bean>
- <!–配置JPA实现产品的适配器–>
- <beanid="jpaVendorAdapter"class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
- </bean>
- <!–配置EntityManager对象–>
- <beanid="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
- <!–注入数据源–>
- <propertyname="dataSource"ref="dataSource"></property>
- <!–扫描entity包的–>
- <propertyname="packagesToScan"value="com.qy.helloworld"></property>
- <!–注入JPA实现产品的适配器–>
- <propertyname="jpaVendorAdapter"ref="jpaVendorAdapter"></property>
- <!–配置的是Hibernate的其他配置除了连接数据库4大要素之外的其余配置–>
- <propertyname="jpaProperties">
- <props>
- <!–是否自动创建表–>
- <propkey="hibernate.hbm2ddl.auto">update</prop>
- <!–配置是否展示SQL–>
- <propkey="hibernate.show_sql">true</prop>
- <!–是否格式化SQL–>
- <propkey="hibernate.format_sql">true</prop>
- <!–连接数据库的方言–>
- <propkey="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
- </props>
- </property>
- </bean>
- <!–配置事务环境–>
- <beanid="jpaTransactionManager"class="org.springframework.orm.jpa.JpaTransactionManager">
- <!–注入dataSource–>
- <propertyname="dataSource"ref="dataSource"></property>
- <!–注入entityManagerFactory对象–>
- <propertyname="entityManagerFactory"ref="entityManagerFactory"></property>
- </bean>
- <!–使用事务–>
- <tx:annotation-driventransaction-manager="jpaTransactionManager"/>
- <!–配置AOP的自动代理–>
- <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
- <!–配置Spring的包扫描–>
- <context:component-scanbase-package="com.qy.helloworld"></context:component-scan>
- <!–Springdata的包的扫描这里的扫描扫描的是DAO层所在的位置–>
- <jpa:repositoriesbase-package="com.qy.helloworld"entity-manager-factory-ref="entityManagerFactory"transaction-manager-ref="jpaTransactionManager"></jpa:repositories>
- </beans>
编写实体类和映射
- @Entity
- @Table(name="t_user")
- publicclassUser{
- @Id
- @GeneratedValue(strategy=GenerationType.IDENTITY)
- privateintuserId;
- privateStringuserName;
- privateStringpassword;
- }
编写Repository类
- publicinterfaceUserRepositoryextendsRepository<User,Integer>{
- /**
- *这个的意思是通过id找用户
- *@Title:getByUserId
- *@Description:TODO
- *@param:@paramuserId
- *@param:@return
- *@return:User
- *@throws
- */
- publicUsergetByUserId(intuserId);
- }
测试
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserRepositoryuserRepository=applicationContext.getBean(UserRepository.class);
- Userusers=userRepository.findByUserId(1);
- }
通过名字来确定方法
代码演示:
举例如下:
- publicinterfaceUserRepositoryextendsRepository<User,Integer>{
- /**
- *这个的意思是通过id找用户
- *@Title:getByUserId
- *@Description:TODO
- *@param:@paramuserId
- *@param:@return
- *@return:User
- *@throws
- */
- publicUsergetByUserId(intuserId);
- /**
- *记住查询的开头只能是get或者find开头By:通过什么查询
- *@Title:findByUserId
- *@Description:TODO
- *@param:@paramuserId
- *@param:@return
- *@return:User
- *@throws
- */
- publicUserfindByUserId(intuserId);
- /**
- *通过用户名的模糊查询
- *@Title:findByUserNameLike
- *@Description:TODO
- *@param:@paramuserName
- *@param:@return
- *@return:List<User>
- *@throws
- */
- publicList<User>findByUserNameLike(StringuserName);
- /**
- *通过用户名和密码的Like来进行查询
- *@Title:findByUserNameLikeAndPasswordLike
- *@Description:TODO
- *@param:@paramuserName
- *@param:@return
- *@return:List<User>
- *@throws
- */
- publicList<User>findByUserNameLikeAndPasswordLike(StringuserName,Stringpassword);
- /**
- *用户名和密码like然后id小于一个范围
- *@Title:findByUserNameLikeAndPasswordLikeAndUserIdLessThan
- *@Description:TODO
- *@param:@paramuserName
- *@param:@parampassword
- *@param:@paramuserId
- *@param:@return
- *@return:List<User>
- *@throws
- */
- publicList<User>findByUserNameLikeAndPasswordLikeAndUserIdLessThan(StringuserName,Stringpassword,intuserId);
- }
注意:一般情况下不会通过名字直接来写相应的方法,因为如果条件过多那么这个时候我们就存在名字特别长的问题
通过注解的模式来实现查询
代码演示:
举例如下:
- /**
- *查询所有没有条件直接查询
- *@Title:findUserAll
- *@Description:TODO
- *@param:@return
- *@return:List<User>
- *@throws
- */
- @Query("fromUser")
- publicList<User>findUserAll();
- /**
- *通过id来查找数据参数直接拼接到后面
- *@Title:findUserById
- *@Description:TODO
- *@param:@paramuserId
- *@param:@return
- *@return:List<User>
- *@throws
- */
- @Query("fromUseruwhereu.userId<3")
- publicList<User>findUserById();
- /**
- *通过id查询存在占位符的情况
- *@Title:findUserById1
- *@Description:TODO
- *@param:@paramuserId
- *@param:@return
- *@return:List<User>
- *@throws
- */
- @Query("fromUseruwhereu.userId<?")
- publicList<User>findUserById1(intuserId);
- /**
- *多条件的查询可以指定当前的参数映射的这个位置
- *@Title:getUserByNameAndId
- *@Description:TODO
- *@param:@paramuserName
- *@param:@paramuserId
- *@param:@return
- *@return:User
- *@throws
- */
- @Query("fromUseruwhereu.userId=?2andu.userName=?1")
- publicUsergetUserByNameAndId(StringuserName,intuserId);
- /**
- *模糊查询的时候动态拼接上%的问题
- *@Title:findUserByLike1
- *@Description:TODO
- *@param:@paramuserName
- *@param:@return
- *@return:List<User>
- *@throws
- */
- @Query("fromUseruwhereu.userNamelikeconcat('%',?,'%')")
- publicList<User>findUserByLike1(StringuserName);
写本地的SQL 查询
代码演示:
举例如下:
- /**
- *通过
- *@Title:findUserAll11
- *@Description:TODO
- *@param:@return
- *@return:List<User>
- *@throws
- */
- @Query(nativeQuery=true,value="select*fromt_user")
- publicList<User>findUserAll11();
增删改的玩法
代码演示:
添加业务逻辑 增加事务环境:
- @Service
- @Transactional//提供一个事务的环境
- publicclassUserService{
- @Autowired
- privateUserRepositoryuserRepository=null;
- /**
- *数据的更新
- *@Title:update
- *@Description:TODO
- *@param:@paramuserName
- *@param:@parampassword
- *@param:@paramuserId
- *@return:void
- *@throws
- */
- publicvoidupdate(StringuserName,Stringpassword,intuserId){
- userRepository.update(userName,password,userId);
- }
- publicvoiddelete(intuserId){
- userRepository.delete(userId);
- }
- publicvoidinsert(StringuserName,Stringpassword){
- userRepository.insert(userName,password);
- }
- }
编写repository的对象:
- publicinterfaceUserRepositoryextendsRepository<User,Integer>{
- /**
- *实现增删改的方法
- *@Title:add
- *@Description:TODO
- *@param:@paramuserName
- *@param:@parampassword
- *@return:void
- *@throws
- */
- @Modifying//这个注解的作用表示的是更新数据
- @Query("updateUserusetu.userName=?,u.password=?whereu.userId=?")
- publicvoidupdate(StringuserName,Stringpassword,intuserId);
- /**
- *更新数据
- *@Title:delete
- *@Description:TODO
- *@param:@paramuserId
- *@return:void
- *@throws
- */
- @Modifying//这个注解的作用表示的是更新数据
- @Query("deleteUseruwhereu.userId=?")
- publicvoiddelete(intuserId);
- /**
- *添加数据
- *@Title:insert
- *@Description:TODO
- *@param:@paramuserName
- *@param:@parampassword
- *@return:void
- *@throws
- */
- @Modifying//这个注解的作用表示的是更新数据
- @Query(nativeQuery=true,value="insertintot_user(userName,password)values(?,?)")
- publicvoidinsert(StringuserName,Stringpassword);
- }
测试:
- @Test
- publicvoidtestHelloWorld()throwsException{
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserServiceuserService=applicationContext.getBean(UserService.class);
- userService.insert("小羽","做程序的");
使用框架中提供的增删改查的方法
代码演示:
提供的是Repository:
- publicinterfaceUserRepositoryextendsCrudRepository<User,Integer>{
分页和排序
代码演示:
提供的Repository:
- publicinterfaceUserRepositoryextendsPagingAndSortingRepository<User,Integer>{
测试:
- publicclassTest001{
- @Test
- publicvoidtestPaging()throwsException{
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserRepositoryuserRepository=applicationContext.getBean(UserRepository.class);
- /**
- *第一个参数:当前的页的页数是多少页数是从0开始的第二页:2-1
- *第二个参数:表示的是每一页条目数
- */
- Page<User>pages=userRepository.findAll(newPageRequest(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:@throwsException
- *@return:void
- *@throws
- */
- @Test
- publicvoidtestSort()throwsException{
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserRepositoryuserRepository=applicationContext.getBean(UserRepository.class);
- /**
- *排序
- *第一个参数:升序或者降序Direction.ASC/DESC
- *第二个参数:排序的这个列
- */
- List<User>users=(List<User>)userRepository.findAll(newSort(Direction.DESC,"userId"));
- System.out.println(users);
- }
- /**
- *排序后分页
- *@Title:testSortAndPaging
- *@Description:TODO
- *@param:@throwsException
- *@return:void
- *@throws
- */
- @Test
- publicvoidtestSortAndPaging()throwsException{
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserRepositoryuserRepository=applicationContext.getBean(UserRepository.class);
- Page<User>pages=userRepository.findAll(newPageRequest(2-1,2,newSort(Direction.DESC,"userId")));
- System.out.println(pages.getContent());
- }
JpaRepository的使用
代码演示:
提供的repository:
- publicinterfaceUserRepositoryextendsJpaRepository<User,Integer>{
测试:
- publicclassTest001{
- @Test
- publicvoidtestPaging()throwsException{
- ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("config/bean-base.xml");
- //获取DAO的对象
- UserRepositoryuserRepository=applicationContext.getBean(UserRepository.class);
- //longcount=userRepository.count();
- //Useruser=userRepository.findOne(15);
- //user.setUserName("小羽");
- //保存或者更新数据
- //userRepository.saveAndFlush(user);
- List<User>users=userRepository.findAll();
- //批处理
- userRepository.deleteInBatch(users);
- //System.out.println("统计:"+count);
- }
- }
结语
Spring Data是我们开发中离不开的经常用到的技术,其涉及的技术和知识面其实远不止上面列出的这些。
后续浅羽会继续更新关于Spring Data的开发知识,只希望能对大家有所帮助,谢谢大家的支持!




