Spring Data JPA 初体验
一,JPA相关的概念
JPA概述
全称是:JavaPersistence API。是SUN公司推出的一套基于ORM的规范。
Hibernate框架中提供了JPA的实现。
JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
2.JPA优势
标准化:
JPA是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
容器级特性的支持:
JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
简单方便:
JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。
查询能力:
JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是HibernateHQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
高级特性:
JPA中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
3.学习JPA要明确的
JPA是一套ORM规范,hibernate实现了JPA规范
hibernate中有自己的独立ORM操作数据库方式,也有JPA规范实现的操作数据库方式。
在数据库增删改查操作中,我们hibernate和JPA的操作都要会。
二, JPA入门
1.需求介绍
本章节我们实现基于JPA注解的对象关系映射,配置实体类和数据库表的对应关系. 并且使用JPA规范中的方法实现CRUD操作。
2.JPA环境搭建
2.1 拷贝jar包到工程中
2.2 编写实体类并使用注解配置
使用注解代替配置文件
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="uid")
private Integer uid; @Column(name="uname")
private String uname; @Column(name="uage")
private int uage; public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getUage() {
return uage;
}
public void setUage(int uage) {
this.uage = uage;
}
@Override
public String toString() {
return "User [uid=" + uid + ", uname=" + uname + ", uage=" + uage + "]";
} }
2.3创建配置文件
要求在src下面的META-INF文件夹下面创建一个名称为persistence.xml的文件。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<!--Name属性用于定义持久化单元的名字 (name必选,空值也合法); transaction-type 指定事务类型(可选) 取值: JTA:默认值
RESOURCE_LOCAL -->
<persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL">
<!-- 三引入映射 -->
<class>com.itheima.bean.User</class>
<properties>
<!-- 一,连接数据库的基本项 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="123456" />
<!-- 二,选配 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
2.4编写工具类
用于获取JPA的操作数据库对象EntityManager
public final class JPAUtil {
//JPA的实体管理器工厂:相当于Hibernate的SessionFactory
private static EntityManagerFactory em;
//使用静态代码块赋值
static {
//注意:该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
em = Persistence.createEntityManagerFactory("myPersistUnit");
}
/**
* 使用管理器工厂生产一个管理器对象
* @return
*/
public static EntityManager getEntityManager() {
return em.createEntityManager();
}
}
2.5编写单元测试
保存用户
@Test
public void fun01(){
User user = new User();
user.setUname("张三");
user.setUage(18); EntityManager manager = JPAUtil.getEntityManager();
EntityTransaction transaction = manager.getTransaction();
transaction.begin();
manager.persist(user);
transaction.commit();
manager.close();
}
3.常用注解说明
- @Entity
作用:指定当前类是实体类。写上此注解用于在创建SessionFactory/EntityManager时,加载映射配置。 - @Table
作用:指定实体类和表之间的对应关系。
属性:
name:指定数据库表的名称 - @Id
作用:指定当前字段是主键。 - @GeneratedValue
作用:指定主键的生成方式。JPA的主键生成方式详解见2.4小节的说明。
属性:
strategy :指定主键生成策略。JPA支持四种生成策略,具体介绍看4小节。 - @Column
作用:指定实体类属性和数据库表之间的对应关系
属性:
name:指定数据库表的列名称。
unique:是否唯一
nullable:是否可以为空
inserttable:是否可以插入
updateable:是否可以更新
columnDefinition: 定义建表时创建此列的DDL
secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。
4.主键生成策略
4.1JPA提供的类型
通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 其生成规则由 @GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法。JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO。具体说明如下:
IDENTITY:主键由数据库自动生成(主要是自动增长型)
用法:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long uid;SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 (用在oracle)
用法:@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")
@SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")
说明:
@SequenceGenerator源码中的定义
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator {
String name();
String sequenceName() default "";
int initialValue() default 0;
int allocationSize() default 50;
}
name:表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。
sequenceName:属性表示生成策略用到的数据库序列名称。
AUTO:主键由程序控制. 自动创建一张表
用法:@Id
@GeneratedValue(strategy = GenerationType.AUTO)TABLE:使用一个特定的数据库表格来保存主键(了解)
用法:@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator="payablemoney_gen")
@TableGenerator(name = "pk_gen",
table="tb_generator",
pkColumnName="gen_name",
valueColumnName="gen_value",
pkColumnValue="PAYABLEMOENY_PK",
allocationSize=1
) 这里应用表tb_generator,定义为 : CREATE TABLE tb_generator (
id NUMBER NOT NULL,
gen_name VARCHAR2(255) NOT NULL,
gen_value NUMBER NOT NULL,
PRIMARY KEY(id)
) 插入纪录,供生成主键使用:
INSERT INTO tb_generator(id, gen_name, gen_value)VALUES (1,PAYABLEMOENY_PK', 1);
在主键生成后,这条纪录的value值,按allocationSize递增。 @TableGenerator的定义:
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface TableGenerator {
String name();
String table() default "";
String catalog() default "";
String schema() default "";
String pkColumnName() default "";
String valueColumnName() default "";
String pkColumnValue() default "";
int initialValue() default 0;
int allocationSize() default 50;
UniqueConstraint[] uniqueConstraints() default {};
}
其中属性说明:
name:
表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。
table:
表示表生成策略所持久化的表名,例如,这里表使用的是数据库中的“tb_generator”。
catalog和schema:
具体指定表所在的目录名或是数据库名。
pkColumnName:
属性的值表示在持久化表中,该主键生成策略所对应键值的名称。例如在“tb_generator”中将“gen_name”作为主键的键值
valueColumnName:
属性的值表示在持久化表中,该主键当前所生成的值,它的值将会随着每次创建累加。例如,在“tb_generator”中将“gen_value”作为主键的值
pkColumnValue:
属性的值表示在持久化表中,该生成策略所对应的主键。例如在“tb_generator”表中,将“gen_name”的值为“CUSTOMER_PK”。
initialValue:
表示主键初识值,默认为0。
allocationSize:
表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
UniqueConstraint:
与@Table标记中的用法类似。
4.2自定义类型
JPA提供了四种类型,有的情况下是不能满足使用的. eg: 主键类型是字符串,需要uuid,这个时候就需要自定义类型.
5.JPA的CRUD操作
三,JPA一对多配置
1.注解详解
- OneToMany
作用:
建立一对多的关系映射
属性:
targetEntityClass:指定多的多方的类的字节码
mappedBy:指定从表实体类中引用主表对象的名称。
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
orphanRemoval:是否使用孤儿删除 - @ManyToOne
作用:
建立多对一的关系
属性:
targetEntityClass:指定一的一方实体类字节码
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
optional:关联是否可选。如果设置为false,则必须始终存在非空关系。 - @JoinColumn
作用:
用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
2.使用JPA配置一对多
一的一方实体(Category)
@Entity
@Table(name="category")
public class Category { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="cid")
private Integer cid; @Column(name="cname")
private String cname; //在一的一方,用一个集合表示和product的关系
@OneToMany(targetEntity=Product.class,mappedBy="category")
private Set<Product> products = new HashSet<Product>(); public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Set<Product> getProducts() {
return products;
}
public void setProducts(Set<Product> products) {
this.products = products;
}
}
多的一方实体(Product)
@Entity
@Table(name="product")
public class Product { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer pid; @Column(name="pname")
private String pname; @Column(name="price")
private double price;
//用一个对象表示,当前商品属于哪个类别
@ManyToOne(targetEntity=Category.class)
@JoinColumn(name="cid",referencedColumnName="cid")
private Category category; public Integer getPid() {
return pid;
} public void setPid(Integer pid) {
this.pid = pid;
} public String getPname() {
return pname;
} public void setPname(String pname) {
this.pname = pname;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} public Category getCategory() {
return category;
} public void setCategory(Category category) {
this.category = category;
} }
3.一对多关系的CRUD
四,JPA配置多对多
1,注解详解
- @ManyToMany
作用:
用于映射多对多关系
属性:
cascade:配置级联操作。
fetch:配置是否采用延迟加载。
targetEntity:配置目标的实体类。映射多对多的时候不用写。 - @JoinTable
作用:
针对中间表的配置
属性:
name:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段 - @JoinColumn
作用:
用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
2,使用JPA配置多对多
Student.java
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "sid")
private Integer sid; @Column(name = "sname")
private String sname; // 中间表s_c_table字段关联sid表的主键字段sid,// 中间表s_c_table的字段cid关联表的主键cid
@ManyToMany
@JoinTable(name = "s_c_table", // 中间表的名称
joinColumns = { @JoinColumn(name = "sid", referencedColumnName = "sid") },
inverseJoinColumns = {@JoinColumn(name = "cid", referencedColumnName = "cid") })
private Set<Course> courses = new HashSet<Course>(); public Integer getSid() {
return sid;
} public void setSid(Integer sid) {
this.sid = sid;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public Set<Course> getCourses() {
return courses;
} public void setCourses(Set<Course> courses) {
this.courses = courses;
} }
Course.java
@Entity
@Table(name="course")
public class Course { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="cid")
private Integer cid; @Column(name="cname")
private String cname; @ManyToMany(mappedBy="courses")
private Set<Student> students = new HashSet<Student>(); public Integer getCid() {
return cid;
} public void setCid(Integer cid) {
this.cid = cid;
} public String getCname() {
return cname;
} public void setCname(String cname) {
this.cname = cname;
} public Set<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
} }
五,Spring Data JPA
1.概述
1.1什么是SpringDataJPA
Spring提供的一个用于简化JPA开发的框架。可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。下面的示例代码即可完成数据保存的操作,而无需具体实现类
1.2SpringDataJPA的核心接口
- Repository:最顶层的接口,是一个空的接口,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
- CrudRepository :是Repository的子接口,提供CRUD的功能
- PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
- JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
- JpaSpecificationExecutor:用来做负责查询的接口,类似条件(QBC)查询
- Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
2.SpringDataJPA入门
2.1创建Java项目,导入jar包
- spring相关的jar包
- hibernate相关jar包
- springDaataJpa相关的jar: spring-data-commons.jar 、 spring-data-jpa.jar 、 hibernate-entitymanager-5.0.7.Final.jar
2.2创建持久化类
BaseDict
package com.itheima.crm.bean; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity
@Table(name="base_dict")
public class BaseDict { @Id
@GeneratedValue(generator="sysuuid")
@GenericGenerator(name = "sysuuid", strategy = "uuid")
@Column(name="dict_id")
private String dict_id; @Column(length=20)
private String dict_type_code;
@Column(length=40)
private String dict_type_name;
@Column(length=40)
private String dict_item_name;
@Column(length=40)
private String dict_item_code;
@Column
private int dict_sort;
@Column(length=40)
private String dict_enable;
@Column(length=40)
private String dict_memo; public String getDict_id() {
return dict_id;
}
public void setDict_id(String dict_id) {
this.dict_id = dict_id;
}
public String getDict_type_code() {
return dict_type_code;
}
public void setDict_type_code(String dict_type_code) {
this.dict_type_code = dict_type_code;
}
public String getDict_type_name() {
return dict_type_name;
}
public void setDict_type_name(String dict_type_name) {
this.dict_type_name = dict_type_name;
}
public String getDict_item_name() {
return dict_item_name;
}
public void setDict_item_name(String dict_item_name) {
this.dict_item_name = dict_item_name;
}
public String getDict_item_code() {
return dict_item_code;
}
public void setDict_item_code(String dict_item_code) {
this.dict_item_code = dict_item_code;
}
public int getDict_sort() {
return dict_sort;
}
public void setDict_sort(int dict_sort) {
this.dict_sort = dict_sort;
}
public String getDict_enable() {
return dict_enable;
}
public void setDict_enable(String dict_enable) {
this.dict_enable = dict_enable;
}
public String getDict_memo() {
return dict_memo;
}
public void setDict_memo(String dict_memo) {
this.dict_memo = dict_memo;
}
@Override
public String toString() {
return "BaseDict [dict_id=" + dict_id + ", dict_type_code=" + dict_type_code + ", dict_type_name="
+ dict_type_name + ", dict_item_name=" + dict_item_name + ", dict_item_code=" + dict_item_code
+ ", dict_sort=" + dict_sort + ", dict_enable=" + dict_enable + ", dict_memo=" + dict_memo + "]";
} }
2.3创建applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!--引入jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:component-scan base-package="com.itheima"/>
<!--配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--1.,配置数据源(代替四个基本项) -->
<property name="dataSource" ref="dataSource"></property>
<!--2,配置选配项 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
<!--3配置包扫描路径 -->
<property name="packagesToScan" value="com.itheima.crm.bean"></property>
<!-- 4.,配置JPA适配 -->
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
</bean>
<!--注册适配器 -->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
<!--配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!--配置注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--配置JPADao,生成代理对象 -->
<jpa:repositories base-package="com.itheima.crm.dao"></jpa:repositories>
<!--配置数据字典模块 -->
<bean id="baseDictService" class="com.itheima.crm.service.impl.BaseDictServiceImpl">
<property name="baseDictDao" ref="baseDictDao"></property>
</bean>
</beans>
2.4创建Dao
public interface BaseDictDao extends PagingAndSortingRepository<BaseDict, String>{
}
3.查询方法命名规则及JPQL语法生成
3.1概述
SpringDataJPA默认情况下, 提供了查询的相关的方法, 基本上能满足我们80%左右的需要. 但是还有一些是没有满足的,我们可以遵循它的命名规范来定义方法名. 如果没有满足命名规范的, 可以在方法上加@Query注解来写语句
3.2 JPA命令规范
关键字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)
eg
public interface StandardRepository extends JpaRepository<Standard, Long> { // JPA的命名规范
List<Standard> findByName(String name); // 自定义查询,没有遵循命名规范
@Query("from Standard where name = ?")
Standard findByNamexxxx(String name); // 遵循命名规范,执行多条件查询
Standard findByNameAndMaxLength(String name, Integer maxLength); // 自定义多条件查询
@Query("from Standard where name = ?2 and maxLength = ?1")
Standard findByNameAndMaxLengthxxx(Integer maxLength, String name); // 使用标准SQL查询
@Query(value = "select * from T_STANDARD where C_NAME = ? and C_MAX_LENGTH = ?",
nativeQuery = true)
Standard findByNameAndMaxLengthxx(String name, Integer maxLength); // 模糊查询
Standard findByNameLike(String name); @Modifying // 代表本操作是更新操作
@Transactional // 事务注解
@Query("delete from Standard where name = ?")
void deleteByName(String name); @Modifying // 代表本操作是更新操作
@Transactional // 事务注解
@Query("update Standard set maxLength = ? where name = ?")
void updateByName(Integer maxLength, String name);
}
Spring Data JPA 初体验的更多相关文章
- Spring Data JPA初使用 *****重要********
Spring Data JPA初使用 我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度. 在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样 ...
- Spring Data JPA初使用(转载)
我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度. 在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样优秀的Spring Data JPA. ...
- Spring Data JPA初使用
我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度. 在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样优秀的Spring Data JPA. ...
- Spring Data JPA应用之常规CRUD操作初体验
基于对于一个陌生的技术框架,先使用后研究其实现的原则(大部分本人如此,就如小朋友学习骑自行车不会先研究自行车是怎么动起来的而是先骑会了),对于Spring JPA先通过案例实践其怎么用吧. 用之前得明 ...
- 初入spring boot(七 )Spring Data JPA
Spring Data JPA通过提供基于JPA的Repository极大地减少JPA作为数据访问方案的代码量. 1.定义数据访问层 使用Spring Data JPA建立数据访问层十分简单,只需定义 ...
- Spring Boot对Spring Data JPA的支持
前两篇介绍了Spring Data JPA的基本使用,本篇介绍Spring Boot 对JPA的支持.如下: 1)导入坐标 2)注解配置 其他配置同Spring Data JPA应用之常规CRUD操作 ...
- Spring Data JPA应用 之查询分析
在Spring Data JPA应用之常规CRUD操作初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)尾附上了JpaRepository接口继承关系及方法,可以知道JpaRepos ...
- Springboot 系列(十)使用 Spring data jpa 访问数据库
前言 Springboot data jpa 和 Spring jdbc 同属于 Spring开源组织,在 Spring jdbc 之后又开发了持久层框架,很明显 Spring data jpa 相对 ...
- 使用Spring Data JPA进行数据分页与排序
一.导读 如果一次性加载成千上万的列表数据,在网页上显示将十分的耗时,用户体验不好.所以处理较大数据查询结果展现的时候,分页查询是必不可少的.分页查询必然伴随着一定的排序规则,否则分页数据的状态很难控 ...
随机推荐
- Linux学习笔记 --服务器优化
Linux服务器优化 序言: 服务器操作建议 1.严格按照目录规范操作服务器 2.远程服务器不允许关机 3.不要在服务器访问高峰运行高负载命令 4.远程配置防火墙时,不要把自己踢出服务器 一.禁用不必 ...
- opencv读写视频,对感兴趣区域进行裁剪
作为小码农,本人最近想对一段视频的某个区域进行处理,因此要将该段视频区域裁剪出来,搜搜网上,发现没有痕迹,是故自己琢磨一下,左右借鉴,编了如下代码,目标得以实现,希望对你有用. #include &q ...
- Linux下C语言的调试 - gdb
调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...
- TCP连接建立系列 — TCP选项解析
本文主要分析:在收到客户端的SYN包时,服务器端是如何解析它所携带的TCP选项,并结合本端情况决定是否予以支持. 内核版本:3.6 Author:zhangskd @ csdn blog 概述 收到客 ...
- Unity Socket TCP
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Net.Sock ...
- 【Android 应用开发】Activity生命周期 与 Activity 之间的通信
一. Activity生命周期 上图 1. Activity状态 激活状态 : Activity出于前台 , 栈顶位置; 暂停状态 : 失去了焦点 , 但是用户仍然可以看到 , 比如弹出一个对话框 , ...
- listview中的adapter学习小结
概述 Adapter是数据和UI之间的一个桥梁,在listview,gridview等控件中都会使用到,android给我们提拱了4个adapte供我们使用: BaseAdapter是一个抽象类,继承 ...
- DB Query Analyzer 5.02 is distributed, 53 articles concerned have been published
DB Query Analyzer is presented by Master Gen feng, Ma from Chinese Mainland. It has English version ...
- mysql-proxy中的admin-lua-script
[root@ecs-7b55 lua]# cat admin.lua --[[ $%BEGINLICENSE%$ Copyright (c) 2008, 2012, Oracle and/or its ...
- JQuery系统梳理
JQuery在前端网页开发中可以说是非常常用了,它所拥有的强大功能足以让我们完成各式各样的效果. 一.JQuery基础语法 1. 使用JQuery必须先导入jquery.x.x.x.js文件: 2. ...