一、JPA

1. JPA 介绍

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一 。 其实在5.0出现发布之前,市面上有诸如、Hibernate 、OpenJPA 、TopLink 等一些列 ORM框架,并且hibernate已经很受大众喜爱了,后来hibernate在3.2版本正式接入JPA 规范,表示自己即属于JPA的框架的具体实现。 一句话概括: JPA 是一种规范、 Hibernate 是这种规范的最好实现。

Dao最受欢迎的两个框架: MyBatis ----不是JPA体系 ----- 需要写sql语句 | Hibernate --- JPA 体系 -----可以不用写sql语句

2. ORM介绍

Object Relational Mapping : 对象关系映射 。 ORM的思想其实就是让 表 和 JavaBean 形成一种映射关系 , 并且让表里面的字段 和JavaBean 里面的成员形成映射关系。

3. JPA 入门

此处就以一个简单的保存案例来实现JPA 入门吧。

  • 添加JPA 依赖
// 在maven 搜索关键字  persistence 即可  hibernate的核心依赖,会包含它对JPA规范的升级,所以这个依赖可以不加
//compile group: 'javax.persistence', name: 'persistence-api', version: '1.0' //不要忘记了添加mysql数据库依赖
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.17' //下面要添加hibernate的依赖,因为JPA 只是一套规范而已,不是具体的实现,JPA的实现有很多,
//这里采用hibernate作为我们的实现,所以需要添加hibernate的依赖库
//compile group: 'org.hibernate', name: 'hibernate-core', version: '4.3.9.Final' //hibernate实体管理者,对接JPA规范的管理员 这是hibernate为了迎合JPA的规范做出来的。
compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '4.3.9.Final'
  • 定义实体类
@Entity(name="t_user")
public class User {
private static final String TAG = "User"; private int id;
private String name;
private int age ; @Id
@GeneratedValue
public int getId() {
return id;
} //剩下的get 和 set方法
...
}
  • 定义配置文件

必须要说明一点,配置文件的名字需要固定,必须叫:persistence.xml , 而且也必须放在 META-INF下面,不能直接放在resource下面。需要在resource下面,新建META-INF 文件夹,然后在放置 xml文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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_2_0.xsd"> <!--持久化单元,数据库 & 实体类 & 具体实现方式配置单元-->
<persistence-unit name="user"> <!--声明提供者,也就是说具体实现,因为JPA 只是规范,这里使用hibernate作为具体实现-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!--表示实体类有哪些-->
<class>com.itheima.bean.User</class> <!--数据库连接参数-->
<properties>
<!--使用jpa的配置-->
<!--<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/test"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> --> <!--也可以使用hibernate的配置为了以后无缝对接,还是建议使用上面的规范化的JPA 配置-->
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <!--表示自动建表-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties> </persistence-unit>
</persistence>
  • 测试代码
@Test
public void testJPA(){ //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("user"); //创建实体管理员
EntityManager manager = factory.createEntityManager(); //获取事务对象
EntityTransaction transaction = manager.getTransaction(); //开启事务
transaction.begin(); //构建实体对象
User user = new User();
user.setName("zhangsan");
user.setAge(18); //持久化,也就是保存到数据库
manager.persist(user); //提交事务
transaction.commit(); //关闭管理员
manager.close(); //关闭工厂,一般不关闭,后面也不用关心这个了。
factory.close();
}

4. 入门详解

a. 注解解释

@Entity : 表示该类是一个实体,也就是和表形成映射,可以添加属性来指定对应的表

​ 如:@Entity(name="t_user")

@Table : 指定表名,可以不写,可以在entity注解上直接表示标识表名。

​ 如 : @Table(name="t_user")

@Id : 用于表示主键,指定哪一个属性和主键对应 可以在变量上声明,也可以在get方法上声明,建议统一。

@GeneratedValue : 用于表示主键生成策略 主键生成策略,提供的有4种

  • 主键策略解释
1、AUTO 自动选择一个最适合底层数据库的主键生成策略。如MySQL会自动对应auto increment。这个是默认选项,即如果只写@GeneratedValue,等价于@GeneratedValue(strategy=GenerationType.AUTO)。注意在mysql5 + hibernate 5的版本测试下,会产生另外一张表,用于记录主键值。 可以在核心配资文件中添加此属性来达到native效果
<property name="hibernate.id.new_generator_mappings">false</property> 2、IDENTITY 表自增长字段,Oracle不支持这种方式。 3、SEQUENCE 通过序列产生主键,MySQL不支持这种方式。 4、TABLE 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。不同的JPA实现商生成的表名是不同的,如 OpenJPA生成openjpa_sequence_table表,Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT。
  • 关于UUID策略

通常我们建表,主键都是int类型,但是其实在开发的时候,有些表也会建成String类型,也就是varchar类型 , 并且有时候我们要主键唯一,这时候需要使用到uuid策略了。JPA并没有提供UUID 策略, 好在hibernate提供了这种策略的支持。

//声明uuid这种策略类型。然后给定一个别名,叫做jpa-uuid  这个注解是hibernate提供的注解, jpa的注解没有
@GenericGenerator(name="jpa-uuid" ,strategy="uuid") //表示对应 t_student 这个表
@Entity(name="t_student")
public class Student { private String id;
private String name;
private int age;
private String phone;
private String address; //指定使用你的主键策略是 jpa-uuid这个名称对一个你的类型,其实就是指定了主键是uuid 。
//由hibernate来维护主键。
@Id
@GeneratedValue(generator="jpa-uuid")
public String getId() {
return id;
}
...
}

b. xml配置解释

  • xml必须放在META-INF下面,名字也必须固定是persistence.xml
  • xml其实就是用于表示怎么连接数据库,具体干活的是JPA实现是什么, 以及有哪些映射实体类。

  • 具体的属性名称,可以参考pdf文档。 第八章节

  • 关于hibernate的配置,请参考hibernate的pdf文档

c. 测试代码解释

代码没有什么好解释的了,必须要有实体管理员工厂,然后获取到管理员,后续就可以操作了。 可以稍稍解释下即可

5. CRUD

JPA 有一个要求就是写入操作,需要使用事务,否则数据不会到达数据库。

1. 增加

 @Test
public void testJPA(){ //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("user"); //创建实体管理员
EntityManager manager = factory.createEntityManager(); //获取事务对象
EntityTransaction transaction = manager.getTransaction(); //开启事务
transaction.begin(); //构建实体对象
User user = new User();
user.setName("zhangsan");
user.setAge(28); //持久化,也就是保存到数据库
manager.persist(user); //提交事务
transaction.commit(); //关闭管理员
manager.close(); //关闭工厂,一般不关闭,后面也不用关心这个了。
factory.close();
}

2. 删除

需要删除某条记录,需要先把它查询出来,然后才能删除。

@Test
public void testDelete(){ //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("user"); //创建实体管理员
EntityManager manager = factory.createEntityManager(); //获取事务对象
EntityTransaction transaction = manager.getTransaction(); //开启事务
transaction.begin(); //查询主键为1的用户
User u = manager.find(User.class,1); //删除用户
manager.remove(u); //提交事务
transaction.commit(); //关闭管理员
manager.close(); //关闭工厂,一般不关闭,后面也不用关心这个了。
factory.close();
}

3. 修改

修改也一样,需要先查询,然后修改后,在持久化。

 @Test
public void testUpdate(){ //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("user"); //创建实体管理员
EntityManager manager = factory.createEntityManager(); //获取事务对象
EntityTransaction transaction = manager.getTransaction(); //开启事务
transaction.begin(); //查询主键为1的用户
User u = manager.find(User.class,2);
u.setAge(102); //这句可以不写,因为查询出来的user对象已经是持久态,直接操作它也可以修改数据库
// manager.persist(u);
/* //删除用户
manager.remove(u);*/ //提交事务
transaction.commit(); //关闭管理员
manager.close(); //关闭工厂,一般不关闭,后面也不用关心这个了。
factory.close(); }

4. 查询

 @Test
public void testQuery(){ //创建实体管理工厂 , 参数的user 来自于配置文件的配置单元名字。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("user"); //创建实体管理员
EntityManager manager = factory.createEntityManager(); //不支持写*
Query query = manager.createQuery("select t from User t"); List<User> list = query.getResultList(); System.out.println("list=" + list); //关闭管理员
manager.close(); //关闭工厂,一般不关闭,后面也不用关心这个了。
factory.close();
}

6. 对象时态

这个状态主要是针对我们操作的持久化类对象。 有四种状态

  • 瞬时态

对象仅仅是创建出来(new对象),没有和EntityManager 产生关系

  • 持久态

和EntityManager建立关系,被持久化,保存到数据库或者刚从数据库查询出来。

  • 脱管态

已经持久化过了,现在要脱离管理。 提交事务,或者清除EntityManager都会走向这个状态。

  • 删除态

该状态只有在JPA 范畴里面才有,单独拿hibernate来说,没有这个状态。只有调用了EntityManager

的remove方法,才会走到这个状态。

7. 多表关系确立

最好使用例子引出关系确立的重要性。

a. 多对一

此处以分类 & 商品的关系来解释

  • 分类 Category
@Entity(name="category")
public class Category { private int id;
private String name; @Id
@GeneratedValue
public int getId() {
return id;
} //剩下的get & set方法
...
}
  • 商品 Product

商品在这个关系里面扮演的是外键的关系,是多方的角色,也就是一种商品分类,可以有很多件商品。所以从商品的位置出发,它和分类的关系是多对一的关系。

@Entity(name="product")
public class Product { private int id ;
private String name;
private double price; //表示该商品属于哪一种分类。
private Category category; @Id
@GeneratedValue
public int getId() {
return id;
} // @ManyToOne表示是多对一关系 optional =false 表示该外键不能为空
@ManyToOne(optional = false) //@JoinColumn name=cid 通俗的意思是: 拿什么列来作为外键,
//这里指定cid , 表示生成的是外键名称叫做cid
@JoinColumn(name="cid")
public Category getCategory() {
return category;
} ...
}

b. 一对多

一对多,比前面的多对一稍微麻烦一点,而且一对多必须双方都配上注解,否则生成的关系会比较乱。

  • 分类 Category

区别只是一方 category 里面多了一个注解 @OneToMany

@Entity(name="category")
public class Category { private int id;
private String name; private Set<Product> productSet = new HashSet<Product>(); @Id
@GeneratedValue
public int getId() {
return id;
} //mappedBy 表示和谁形成映射关系,也表示谁来维护这层关系。
@OneToMany(mappedBy = "category")
public Set<Product> getProductSet() {
return productSet;
} //剩下的get & set 方法
...
}
  • 商品 Product
@Entity(name="product")
public class Product { private int id ;
private String name;
private double price; //表示该商品属于哪一种分类。
private Category category; @Id
@GeneratedValue
public int getId() {
return id;
} @ManyToOne(optional = false)
@JoinColumn(name="cid")
public Category getCategory() {
return category;
} //剩下的get & set方法
...
}

8 . 查询

  1. 对象导航查询

所谓对象导航查询的意思是: 如果A表和B表存在主外键关系(一对多 | 多对一 ),那么在查询A表的时候, 也会顺便查询与该条记录关联的B表记录信息。如分类和商品的关系, 如果查询手机分类,那么会顺便把商品表中属于手机分类的商品给查询出来。


二、SpringData JPA

1. 介绍

在JavaEE 5.0发布的时候,sun公司就提出了jpa的规范,希望整合ORM技术,实现天下归一 。 虽然我们学过的orm技术只有hibernate、但是其实orm技术还有其他的一些方案,比如Apache的 openJPA。 Spring 作为业务逻辑层框架,起到承上启下的作用。所以它对JPA的这些技术实现做了一套封装。大家只要按照规范来配置即可,甚至你们的dao层实现都不用实现了,它在内部给你实现,如果我们想换到其他的jpa实现方案,那么只需要修改配置即可。 这就是我们要说的Spring Data JPA。

JPA

Hibernate | Open Jap | Toplink ....

Spring Data JPA ---> 对Dao层的代码再一次升级封装 。 统一的JPA的实现,在封装。

2. 入门

1. 搭建环境 (建表)

  • 添加依赖
//mysql驱动
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.17' //springboot 依赖
compile("org.springframework.boot:spring-boot-starter-web:1.5.10.RELEASE") //spring data jpa 注意: 不要引入错了,要找的组是springboot的依赖。如下面这条注释的是错误的。
//因为我们使用了SpringBoot,所以采用的库,也要是springboot组下的。
//compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.11.3.RELEASE' compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.10.RELEASE'
  • 添加配置文件

同样还是那个 application.properties , 位于 resources 下面

#连接数据库
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver #hibernate配置
# 自动建表 update:表示有表则直接使用,无表就新建
spring.jpa.hibernate.ddl-auto=update # 表示在操作时,输出sql语句
spring.jpa.show-sql=true
  • 实体类
//name :用于表示构建出来的表名
@Entity(name="t_user")
public class User {
private static final String TAG = "User";
private int id;
private String name;
private int age ; @Id
@GeneratedValue
public int getId() {
return id;
} //剩余的get & set方法代码
...
}

2. 添加数据

上面仅仅是完成了表的创建工作,实际上还并没有看出来SpringData JPA 有什么厉害之处,现在就要往表里面添加数据了。

  • controller
@RestController
public class UserController { //这里要注入业务逻辑层引用
@Autowired
private UserService userService; @RequestMapping("/save")
public String save(){ User user = new User();
user.setName("奥巴马");
user.setAge(58); //调用业务逻辑层
userService.save(user);
return "save success~!";
}
}
  • service
public interface UserService {

    void save(User user);
} --------------------------------------------------------------- @Service
@Transactional
public class UserServiceImpl implements UserService { //这里要注入UserDao引用
@Autowired
private UserDao userDao; @Override
public void save(User user) {
userDao.save(user);
}
}
  • dao

注意: dao层只有一个接口而已,方法没有,其实是父类CrudRepository 已经定义了一些常用的方法,我们可以直接拿过来用即可。真正我们在业务逻辑层拿到的是 SimpleJPARepository 这个类的实例。它其实就是实现了CrudRepository接口方法。

public interface UserDao extends CrudRepository<User, Integer> {

}

三、 通用接口介绍

经过上面的入门例子,大家也看到了,spring data对于我们编程确实方便了许多。我们无需关心dao层的实现,只需要简单的照着规则去写代码即可,spring data jpa 最重要的就是我们的dao层继承的接口。接下来给大家着重说明它的几个接口。

1. Repository

这个接口是所有接口的父接口,也就是它就是老大了。所有我们后面用的接口都是从这位兄弟身上扩展来的。 下图是Repository 这个接口的继承体系,图中的UserDao 和 MyRepository 是我自己写的,大家不用理会。 不过要声明的是: 这个Repository 是一个空接口!!!,里面没有任何方法.

package org.springframework.data.repository;

import java.io.Serializable;
/**
* Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
* purpose is to hold type information as well as being able to discover interfaces that extend this one during
* classpath scanning for easy Spring bean creation.
* <p>
* Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
* same signature as those declared in {@link CrudRepository}.
*
* @see CrudRepository
* @param <T> the domain type the repository manages
* @param <ID> the type of the id of the entity the repository manages
* @author Oliver Gierke
*/
public interface Repository<T, ID extends Serializable> { }

这个repository虽然是个空接口,我们自己来继承它,虽然没有任何要实现的方法,但是我们可以自己写,自己声明方法,这也是允许D~~ ,话不多说,走起~~~

  • 自定义接口 MyRepository
public interface MyRepository extends Repository<User, Integer> {

	/**
* 根据用户id查询用户
* @param uid
* @return
*/
User findByUid(int uid); }
  • service层代码
public interface UserService {

	User findByUid(int uid);
} ------------------------------
@Service
@Transactional //现在仍然是查询这个注解可以不写,为了免得大家记太多,我就索性都打开了。
public class UserServiceImpl implements UserService {
@Autowired
private MyRepository repository; @Override
public User findByUid(int uid) {
return repository.findByUid(uid);
} }
  • 测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJpa { @Autowired
private UserService userService; @Test
public void testFindByUid(){
System.out.println(userService.findByUid(1)); }
}
  • 结果:

  • 疑问:

写到这,有的同学绝对会有疑问, 这都可以,那这也行的话,我写一个叫做 fUid() 或者叫做 zhaoUserByUid() 这样的方法名,行不行呢? 答案是: NO!

因为我们声明的是接口,具体的实现类还是由人家的spring做出来的。spring胃口比较挑剔,而且为了满足大众化的口味,就做出了一些命名上的要求,大家要慢慢习惯这种要求,这也正是它的另一个框架Spring Boot的口号习惯优于配置 。 下图摘自 Spring Data JPA 文档对方法关键字的描述。

如:我们想按照用户的name 查询, 那么可以写成 findByName 以此类推

如果觉得这些关键字记不住,那么spring可以允许我们程序员自己定义自己的方法名。

2. 自定义方法名

这个小节主要讲述的是,我们可以自己定义自己的方法名,你爱叫啥叫啥,随意。

  • Dao接口
public interface MyRepository extends Repository<User, Integer> {

	@Query("from User  where uid = ?1") //?1 表示取第一个参数uid 来替代这个?。
User selectUser(int uid); }
  • Service
public interface UserService {

	User selectUser(int uid);
}
  • 测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJpa { @Autowired
private UserService userService; @Test
public void testSelectUser(){
System.out.println(userService.selectUser(1)); }
}

虽然我们可以自己定义方法名,但是这种做法稍微有点麻烦,所以建议少用这种写法。 只有在以后执行多表查询的时候,我们才需要这么做。

3. CrudRepository

这个接口是扩展了repository, 在这个接口里面默认给大家声明好了一些增删改查的方法,此处给大家演练一个查询所有用户的操作

  • Dao
public interface UserDao extends CrudRepository<User, Integer> {
//查询所有的用户
}
  • Service
@Service
//@Transactional
public class UserServiceImpl implements UserService { @Autowired
private UserDao userDao; @Override
public List<User> findAll() {
return (List<User>) userDao.findAll();
} }
  • 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJpa { @Autowired
private UserService userService; @Test
public void testFindAll(){
List<User> list= userService.findAll();
System.out.println("list="+list);
}
}

4.PagingAndSortingRepository

这个接口是是CrudRepository的扩展接口,除了兼备增删改查之外,它还扩展了分页查询&排序的效果。

以下是这个接口的代码声明

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { /**
* Returns all entities sorted by the given options.
*
* @param sort
* @return all entities sorted by the given options
*/
Iterable<T> findAll(Sort sort); /**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
*
* @param pageable
* @return a page of entities
*/
Page<T> findAll(Pageable pageable);
}
  • Dao
public interface UserDao extends PagingAndSortingRepository<User, Integer> {
//查询所有的用户
}
  • Service
public interface UserService {

	/**
* 返回值是page 这个类型是springdatajpa定义好的。其实就和
* 我们自己平常写的PageBean 一样。
* @param pageable
* @return
*/
Page<User> findByPage(Pageable pageable);
} --------------------------------------------------------- @Service
//@Transactional
public class UserServiceImpl implements UserService { @Autowired
private UserDao userDao; @Override
public Page<User> findByPage(Pageable pageable) {
return userDao.findAll(pageable);
} }
  • 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJpa { @Autowired
private UserService userService; @Test
public void testFindByPage(){
//这里ctrl + T 看实现类,然后找PageRequest ,别说你不会哈~~
// page : page表示请求的页码数, 从0开始,0就代表第一页大家。
//size : 表示每页拿多少条记录
Pageable pageable = new PageRequest(1, 2);
Page<User> page = userService.findByPage(pageable); //当前是第几页 这个页码从0开始的,大家可以加上1表示从1开始。
System.out.println(page.getNumber());
System.out.println(page.getTotalPages()); //总页数
System.out.println(page.getSize()); //每页个数
System.out.println(page.getTotalElements()); //总记录数
System.out.println(page.getContent()); //总页数
}
}

重点:

多表关系建立
@ManyToOne @OneToMany SpringDataJPA 完成CRUD
CrudRepository

springboot11 JPA的更多相关文章

  1. 快速搭建springmvc+spring data jpa工程

    一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...

  2. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  3. 玩转spring boot——结合JPA事务

    接着上篇 一.准备工作 修改pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  4. springmvc+jpa实现分页的两种方式

    1.工具类 public final class QueryTool { public static PageRequest buildPageRequest(int pageNumber, int ...

  5. spring boot(五):spring data jpa的使用

    在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...

  6. 转:使用 Spring Data JPA 简化 JPA 开发

    从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...

  7. 一步步学习 Spring Data 系列之JPA(一)

    引入: Spring Data是SpringSource基金会下的一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得数据库的访问变得方便快捷,并支持map-reduce框架和云计算数据服 ...

  8. 一步步学习 Spring Data 系列之JPA(二)

    继上一篇文章对Spring Data JPA更深( )一步剖析. 上一篇只是简单的介绍了Spring Data JPA的简单使用,而往往在项目中这一点功能并不能满足我们的需求.这是当然的,在业务中查询 ...

  9. jpa+springmvc+springdata(一)

    学习尚硅谷笔记: 首先配置application.xml: <?xml version="1.0" encoding="UTF-8"?> <b ...

随机推荐

  1. frcnn_train_data_param的distort_param实现

    frcnn_train_data_param frcnn_train_data_param { source: "./data/train_list.txt" root_folde ...

  2. 旧文备份: 怎样实现SDO服务

    SDO是CANopen协议中最复杂的一部分,带有应答机制,有多种传输方式,并且完整的SDO功能节点需提供1个SDO server和多个SDO client,因此SDO的实现异常困难,协议多种传输方式的 ...

  3. Hive[6] HiveQL 查询

    6.1   SELECT ... FROM 语句    hive> SELECT name,salary FROM employees;    --普通查询 hive>SELECT e.n ...

  4. 在线代码编辑器 Codemirror 的轻量级 React 组件

    代码编辑器 CodeMirror 的轻量级 React 组件 demo @uiw-react.github.io/react-codemirror/ 特性:

  5. 【Python 2 到 3 系列】 关于除法的余数

    v2.2 以前,除("/")运算符的返回有两种可能情况,分别是整型和浮点型.操作数的不同,是影响计算结果数据类型的关键. 以 a / b 为例,a.b均为整型,则结果返回整型:a. ...

  6. 关于json输出为null?

    原因: 该字符中含了ASCII码ETB控制符,即\x17导致json解析失败   解决方案: $params = preg_replace('/[\x00-\x1F]/', '', $params); ...

  7. Form表单提交,js验证

    Form表单提交,js验证 1,  Onclick() 2, Onsubmit() Button标签 input (属性 submit  button )标签 Input type=button    ...

  8. openwrt(二) 配置openwrt及编译

    导航 1. 配置openwrt 2. 编译openwrt 3. 错误记录 1. 配置openwrt 在openwrt的根目录下,执行make menuconfig. 这个界面我也只是了解了这两个选项而 ...

  9. SPOJ1026 概率DP

    Favorite Dice BuggyD loves to carry his favorite die around. Perhaps you wonder why it's his favorit ...

  10. 大话CNN经典模型:VGGNet

       2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发出了新的深度卷积神经网络:VGGNet,并取得了ILSVRC20 ...