一、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. P1217 [USACO1.5]回文质数 Prime Palindromes

    题目描述 因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数. 写一个程序来找出范围[a,b](5 <= a < b <= 100,000 ...

  2. JS isArray、typeof、instanceof

    Array.isArray() 用来检验是不是数组 var a = [1,2,3] console.log(typeof a); // object console.log(Array.isArray ...

  3. 使用c++控制sqlite3

    首先,到官网下载相关的压缩包 https://www.sqlite.org/download.html 但是要自己再重新编译一个, 博主自己收集了一下,密码:hixo https://pan.baid ...

  4. 小程序里面使用wxParse解析富文本导致页面空白等

    在部分安卓手机上会出现白屏的情况且有些ios手机上图文混排上,图片显示不出问题 解决:把插件里面的console.dir去掉即可(原因在于安卓手机无法解析console.dir) 有些图片解析出来下面 ...

  5. POJ 3171 区间最小花费覆盖 (DP+线段树

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4245   Accepted: 1429 D ...

  6. [Bzoj3611]大工程(虚树+DP)

    Description 题目链接 Solution 在虚树上跑DP即可 关于虚树的建立,是维护一个最右链的过程 关键代码如下: sort(A+1,A+k+1,cmp);//按dfs序排序 s[top= ...

  7. 笔记-python-lib-contextlib

    笔记-python-lib-contextlib 1.      contextlib with 语句很好用,但不想每次都写__enter_-和__exit__方法: py标准库也为此提供了工具模块c ...

  8. 1864: [Zjoi2006]三色二叉树

    1864: [Zjoi2006]三色二叉树 链接 分析: 做得最智障的一题了... 首先中间输出两个数之间没空格(换行居然也过了...), 写了dp[i][0/1/2],后来知道其实dp[i][0/1 ...

  9. 关于android 5.0报错:dlopen failed: couldn't map ... Permission denied

    问题描述: 我的应用当中集成了一个安全相关的sdk,而这个sdk中使用的so是加过壳的. 它加载native so的方式是:Java System.loadLibrary --> native ...

  10. Toolbar中menu菜单文字颜色的修改

    Toolbar菜单中menu当中我们大多数都使用图片来按钮,可是有些时候我们也会直接使用文字,文字的颜色如何修改呢. 其实很简单,我们只要修改styles.xml文件中,添加一句 <item n ...