96SEO 2026-02-19 11:12 8
Data为这些持久性存储以及特定实现提供了通用的接口和模版。

其目的是统一简化对不同类型持久性存储…简介
Data为数据访问层提供了熟悉且一致的Spring编程模版对于每种持久性存储业务代码通常需要提供不同存储库提供对不同CURD持久化操作。
Spring
Data为这些持久性存储以及特定实现提供了通用的接口和模版。
其目的是统一简化对不同类型持久性存储的访问。
1、ORM映射元素数据:JPA支持xml和注解两种元数据的形式元数据描述对象和表之间的映射关系框架据此实体对象持久化到数据表中如Enity、Table、Id与Column注解等
2、JPA的API用来操作实体对象执行CRUD操作框架在后台替我们完成所有事情开发者从繁琐的JDBC和SQL代码中解脱出来
3、JPQL查询语句:通过面向对象而非面向数据库的查询语句数据避免程序的SQL语句紧密耦合如from
Data提供了对不同数据库对应的模版例如MongoTemplate、RedisTemplate、JDBCTemplate。
模版提供存储特定CRUD操作Spring
2、对象/数据存储映射可以通过xml文件或注解来映射数据之间的关系
}3、对Respository支持对持久层提供了基础的CRUD操作以及分页操作等
在项目目录下的resource创建一个hibernate.cfg.xml文件
DTD//ENhttp://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd
hibernate-configurationsession-factory!--配置数据库连接信息--property
nameconnection.urljdbc:mysql://localhost:3306/spring_data_jpa/propertyproperty
namehibernate.connection.usernameroot/propertyproperty
namehibernate.connection.password123456/propertyproperty
nameconnection.driver_classcom.mysql.jdbc.Driver/property!--选择数据库类型--property
namehibernate.dialectorg.hibernate.dialect.MySQL5Dialect/property!--打印sql语句--property
namehibernate.show_sqltrue/property!--格式化sql--property
namehibernate.format_sqltrue/property!--
namehbm2ddl.autoupdate/property!--
classorg.example.entity.Customer//session-factory
/hibernate-configuration其中映射的实体类如下
22:38:25*/IdGeneratedValue(strategy
GenerationType.IDENTITY)Column(name
initSessionFactory().openSession())
session.beginTransaction();Customer
Customer();customer.setCustName(张三);session.save(customer);tx.commit();}
{System.out.println(e);}}public
StandardServiceRegistryBuilder().configure(/hibernate.cfg.xml).build()).buildMetadata().buildSessionFactory();}
在项目跟并在其中创建persistence.xml文件其配置如下
xmlnshttp://java.sun.com/xml/ns/persistence
transaction-typeRESOURCE_LOCAL!--
--providerorg.hibernate.ejb.HibernatePersistence/provider!--
--classorg.example.entity.Customer/classpropertiesproperty
namejavax.persistence.jdbc.user
namejavax.persistence.jdbc.password
namejavax.persistence.jdbc.driver
valuecom.mysql.jdbc.Driver/property
valuejdbc:mysql://localhost:3306/spring_data_jpa/property
valueorg.hibernate.dialect.MySQL5InnoDBDialect//properties/persistence-unit
init().createEntityManager();EntityTransaction
entityManager.getTransaction();tx.begin();//
Customer();customer.setCustName(hello
jpa);entityManager.persist(customer);tx.commit();}public
Persistence.createEntityManagerFactory(springJpa);
JPQL代表Java持久化查询语言。
它被用来创建针对实体的查询存储在关系数据库中。
init().createEntityManager();EntityTransaction
entityManager.getTransaction();tx.begin();//
这里的Customer是映射的实体类名称其查询都是使用映射实体类的属性String
custId:id;entityManager.createQuery(jpql).setParameter(custName,
3L).executeUpdate();tx.commit();
entityManager.createNativeQuery(sql).setParameter(custName,
3L).executeUpdate();其中的cst_customer是表结构cust_name和cust_id是表的字段名
临时状态刚创建出来没有与entityManager发生关系没有被持久化不处于entityManager的对象中
持久状态与entityManager发生关系已经被持久化可以把持久化状态当做实实在在的数据库记录
游离状态游离状态就是提交到数据库后事务commit后实体的状态因为事务已经提交了此时实体属性你如何改变都不会同步到数据库中。
persist方法可以将实例转换为managed状态在调用flush()方法或事务提交后实例将被插入到数据库中
JPA是Spring提供的一套简化JPA开发的框架按照约定好的规则进行方法命名来实现dao层接口就可以在不写接口实现的前提下实现对数据库的访问和操作。
同时提供了很多除了CRUD在外的功能如分页、排序、复杂查询等功能
--dependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-bom/artifactIdversion2021.1.0/versiontypepom/type/dependencydependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-jpa/artifactIdversion2.7.7/version/dependencydependencygroupIdorg.hibernate/groupIdartifactIdhibernate-entitymanager/artifactIdversion5.6.15.Final/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.33/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.15/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.1.10.RELEASE/versionscopetest/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.16.10/versionscopeprovided/scope/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependency
/dependencies在resource文件夹下创建Spring.xml文件进行对JPA的配置
xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:jpahttp://www.springframework.org/schema/data/jpa
xmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/data/jpahttps://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd!--
base-packageorg.example.repositoriesentity-manager-factory-refentityManagerFactorytransaction-manager-reftransactionManager/!--
classorg.springframework.orm.jpa.LocalContainerEntityManagerFactoryBeanproperty
classorg.springframework.orm.jpa.vendor.HibernateJpaVendorAdapterproperty
valuetrue//bean/propertyproperty
valueorg.example.entity/property
classcom.alibaba.druid.pool.DruidDataSource
valuejdbc:mysql://localhost:3306/spring_data_jpa/property
valuecom.mysql.jdbc.Driver/property
classorg.springframework.orm.jpa.JpaTransactionManager
refentityManagerFactory//bean!--
transaction-managertransactionManager/
EnableJpaRepositories(basePackages
DruidDataSource();druidDataSource.setUsername(root);druidDataSource.setPassword(123456);druidDataSource.setDriverClassName(com.mysql.jdbc.Driver);druidDataSource.setUrl(jdbc:mysql://localhost:3306/spring_data_jpa);return
LocalContainerEntityManagerFactoryBean
HibernateJpaVendorAdapter();vendorAdapter.setGenerateDdl(true);LocalContainerEntityManagerFactoryBean
LocalContainerEntityManagerFactoryBean();factory.setJpaVendorAdapter(vendorAdapter);factory.setPackagesToScan(org.example.entity);factory.setDataSource(dataSource());return
transactionManager(EntityManagerFactory
JpaTransactionManager();txManager.setEntityManagerFactory(entityManagerFactory);return
使用配置类直接变更为ContextConfiguration(classes
RunWith(SpringJUnit4ClassRunner.class)
customerRepositories;Testpublic
customerRepositories.findById(1L);customer.ifPresent(System.out::println);}Testpublic
Customer();customer.setName(hello
test);customerRepositories.save(customer);}Testpublic
Customer();customer.setId(3L);customer.setName(hello
update);customerRepositories.save(customer);}Testpublic
Customer();customer.setId(3L);customerRepositories.delete(customer);}
Respositories的抽象目的是为了减少各种持久层存储实现数据访问层所需的样板代码。
其中CrudRepository提供了简单的增删改查的操作。
PagingAndSortingRepository在增删改查的基础上添加了分页排序的操作。
customerRepositories.findAll(PageRequest.of(0,
2));System.out.println(all.getContent());
通过对实体类的id属性进行降序排列IterableCustomer
customerRepositories.findAll(Sort.sort(Customer.class).by(Customer::getId).descending());System.out.println(sorted);
customerRepositories.findAll(Sort.sort(Customer.class).by(Customer::getId).descending().and(Sort.sort(Customer.class).by(Customer::getName)));JPQL和SQL
JPA提供了多种自定义操作比如使用JPQL或者原始的SQL、规定的方法名称、Query
Examply、通过Specifications、通过Querydsl方式
PagingAndSortingRepositoryCustomer,
PagingAndSortingRepositoryCustomer,
findCustomerByName(Param(customerName)
JPA中对增删改都需要加上事务,同时添加Modifying注解通知Spring
PagingAndSortingRepositoryCustomer,
{TransactionalModifyingQuery(UPDATE
}其中c.name和c.id都是实体类的属性名如果是新增一定只能是在Hibernate下才能支持而且必须是INSERT
PagingAndSortingRepositoryCustomer,
findCustomerByName(Param(custName)
}其中cst_customer是数据库表名,cust_name是数据库表字段当使用原生SQL时需要在Query注解的nativeQuery设置为true
关键字描述find...By、read..By、get...By、query...By、search..By、stream..By通用查询方法通常返回存储库类型、Collection或Streamable子类型或结果包装类例如PageGeoResults或任何其他特定与商店的结果包装类。
可以作findBy..、findMyDomainTypeBy...或与其他关键字结合使用exists..By存在投影。
通常返回boolean结果count..By计数投影返回数字结果delete...By、remove...By删除查询方法返回无结果void或者删除计数..Firstnumber...、...Topnumber..将查询结果限制为第一个number结果。
此关键字可以出现主题的find和其他关键字和之间的任何位置By...Distinct...使用不同查询仅返回唯一结果。
查阅特定与商店的问题是否支持该功能。
此关键字可以出现在主题find和其他关键字和之间任何位置By
关键词样本JPQL片段DistinctfindDistinctByLastnameAndFirstnameselect
?2AndfindByLastnameAndFirstname..
?2OrfindByLastnameOrFirstname..where
?2Is、EqualsfindByFirstname、findByFirstnameIs、findByFirstnameEquals..where
?1BetweenfindByStartDateBetween...where
?2LessThanfindByAgeLessThan...where
?1LessThanEqualfindByAgeLessThanEqual..where
?1GreaterThanfindByAgeGreaterThan..where
?1GreaterThanEqualfindByAgeGreaterThanEqual..where
?1AfterfindByStarterDateAfter..where
?1BeforefindByStartDateBefore..where
?1IsNull、NullfindByAge(Is)Null..where
nullIsNotNull、NotNullfindByAge(Is)NotNull..where
nullLikefindByFirstnameLike..where
自己指定%位置NotLikefindByFirstnameNotLike..where
?1自己指定%位置StartingWithfindByFirstnameStartingWith..where
?2参数绑定了append%EndingWithfindByFirstnameEndingWith..where
?1(参数绑定了prepended%)ContainingfindByFirstnameContaining..where
?1(参数绑定包裹在%)OrderByfindByAgeOrderByLastnameDesc..where
descNotfindByLastnameNot..where
?1NotInfindByAgeNotIn(CollectionAge
?1TruefindByActiveTrue()..where
trueFalsefindByActiveFalse()..where
falseIgoreCasefindByFirstnameIgoreCase..where
PagingAndSortingRepositoryCustomer,
PagingAndSortingRepositoryCustomer,
}需要使用Transient开启事务以及使用Modifying告诉Spring
PagingAndSortingRepositoryCustomer,
RunWith(SpringJUnit4ClassRunner.class)
customerMethodNameRepositories;Testpublic
customerMethodNameRepositories.findByNameLike(%test%);System.out.println(customers);}
只支持查询,不支持嵌套或者分组的属性约束如firstname?0或者firstname?1
start/contains/ends/regex匹配和其他属性类型精确匹配。
PagingAndSortingRepositoryCustomer,
Long,QueryByExampleExecutorCustomer
}接口需要继承QueryByExampleExecutor同时查询时需要通过Example.of()构建查询条件
查询条件通过Example.of()构建查询条件Customer
Customer();customer.setName(test);IterableCustomer
queryByExampleRepositories.findAll(Example.of(customer));System.out.println(all);
Customer();customer.setName(张三);customer.setAddress(shanghai);//
queryByExampleRepositories.findAll(Example.of(customer,
.matching().withIgnorePaths(address)));System.out.println(ignore);
Example的查询方式只支持字符串且无法对查询条件做出、和的限制所以需要使用Specifications的查询方式来实现但Specifications的查询方式不能使用分组、聚合函数。
Long,JpaSpecificationExecutorCustomer
}使用Specifications的查询方式需要继承JpaSpecificationExecutor接口如下案例查询address是BEIJIN且id在3,20,18的数据
specificationsRepositories.findAll((SpecificationCustomer)(root,
.and(criteriaBuilder.equal(root.get(id),
criteriaBuilder.in(root.get(address)).value(3L).value(20L).value(18L)));all.forEach(System.out::println);
Customer可以获取查询的列,criteriaBuilder设置各种查询条件如、或者in等操作、query设置各种组合条件如order
QueryDSL是基于ORM框架或者SQL平台上的一个通用查询框架借助QueryDSL可以在任何支持的ORM框架或者SQL平台上以通用的API方式构建查询。
dependencygroupIdcom.querydsl/groupIdartifactIdquerydsl-jpa/artifactIdversion4.4.0/version
buildpluginsplugingroupIdcom.mysema.maven/groupIdartifactIdapt-maven-plugin/artifactIdversion1.1.3/versiondependenciesdependencygroupIdcom.querydsl/groupIdartifactIdquerydsl-apt/artifactIdversion4.4.0/version/dependency/dependenciesexecutionsexecutionphasegenerate-sources/phasegoalsgoalprocess/goal/goalsconfigurationoutputDirectorytarget/generated-sources/queris/outputDirectoryprocessorcom.querydsl.apt.jpa.JPAAnnotationProcessor/processorlogOnlyOnErrortrue/logOnlyOnError/configuration/execution/executions/plugin/plugins
QuerydslPredicateExecutorCustomer,
}注意必须继承QuerydslPredicateExecutor和CrudRepository或CrudRepository的子类
RunWith(SpringJUnit4ClassRunner.class)
queryDSLRepositories;Testpublic
QCustomer.customer;IterableCustomer
queryDSLRepositories.findAll(customer.id.in(1L,
20L).and(customer.id.gt(5L)).and(customer.address.eq(BEIJIN)));all.forEach(System.out::println);}
RunWith(SpringJUnit4ClassRunner.class)
JPAQueryFactory(entityManager);QCustomer
QCustomer.customer;JPAQueryTuple
customer.name).from(customer).where(customer.id.eq(18L)).orderBy(customer.id.desc());ListTuple
{System.out.println(tuple.get(customer.id));System.out.println(tuple.get(customer.name));}}
GenerationType.IDENTITY)Column(name
CascadeType.PERSIST)JoinColumn(name
级联持久化保存操作持久保存拥有方实体时也会持久保存该实体的所有相关数据。
这个属性就是造成上面问题的关键。
当你保存一天条数据时所有的关联数据都会进行保存无论数据库里面有没有但有时候我们是需要这样的级联操作的。
级联删除操作删除当前实体时与它有映射关系的实体也会跟着被删除。
级联脱管/游离操作如果你要删除一个实体但是它有外键无法删除你就需要这个级联权限了。
它会撤销所有相关的外键关联。
有一个订单,订单里面关联了许多商品,这个订单可以被很多人操作,那么这个时候A对此订单和关联的商品进行了修改,与此同时,B也进行了相同的操作,但是B先一步比A保存了数据,那么当A保存数据的时候,就需要先刷新订单信息及关联的商品信息后,再将订单及商品保存。
级联更新合并操作当Student中的数据改变会相应地更新Course中的数据。
fetch参数的作用类似于设计模式中的单例模式默认为EAGER饿汉模式,可以设置为LAZY懒汉模式当设置为LAZY的时候只有在使用到对应的实体类的时候就会加载执行查询
repositories.findById(1L);System.out.println(byId.get());
}需要添加Transactional注解开启事务这是由于通过repositories接口来调用查询方法执行完后session会立即关闭一旦session关闭了就不能进行查询了所以在fetch
FetchType.LAZY的情况下执行完repositories.findById(1L)后会关闭session导致在执行byId.get()调用查询会报错。
而事务是在整个方法执行完后关闭session
GenerationType.IDENTITY)private
PagingAndSortingRepositoryCustomer,
RunWith(SpringJUnit4ClassRunner.class)
Account();account.setUsername(xushu);Customer
Customer();customer.setName(徐庶);customer.setAccount(account);repositories.save(customer);}
GenerationType.IDENTITY)private
GenerationType.IDENTITY)Column(name
CascadeType.ALL)JoinColumn(name
JPA默认使用的是懒加载所以需要使用Transactional开启事务来解决运行时出现no-session的错误
repositories.findById(7L);System.out.println(byId.get());
}或者在实体类中的Customer中添加OneToMany(cascade
FetchType.EAGER)注解解决出现no-session错误如下:
如果在Customer实体类中OneToMany的cascade
CascadeType.PERSIST这会只删除Customer表中的信息不会删除Message表中的信息
GenerationType.IDENTITY)private
CascadeType.PERSIST)JoinColumn(name
CascadeType.PERSIST)以及JoinColumn(name
GenerationType.IDENTITY)Column(name
CascadeType.PERSIST)JoinTable(name
GenerationType.IDENTITY)Column(name
Customer();customer.setName(zhangshang);ListRole
Role(商品管理员));}};customer.setRoles(roles);customerRepository.save(customer);
为了数据库中的数据方便溯源所以经常需要在数据库中添加创建人、修改人、修改时间、创建时间。
由于经常频繁的操作所以Spring
dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion5.3.28/version
注解指定时间类型Temporal(TemporalType.TIMESTAMP)CreatedDateprivate
修改时间Temporal(TemporalType.TIMESTAMP)LastModifiedDateprivate
Date();同时在实体类上添加EntityListeners(AuditingEntityListener.class)用于监听审计监听对应的实体类
后端获取到的用户类型一直可以是String可以是User对象等
org.springframework.data.domain.AuditorAwarejava.lang.String
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback