浅谈SpringData Jpa与Hibernate区别
SpringDate Jpa:
-
Spring Data是Spring Framework的一部分。Spring Data存储库抽象的目标是显著减少为各种持久性存储实现数据访问层所需的代码量。
-
Spring Data JPA不是JPA提供者。它是一个库/框架,它在我们的JPA提供程序(如Hibernate)的顶部添加了一个额外的抽象层。
Hibernate:Hibernate是Java环境的对象关系映射解决方案。对象关系映射或ORM是将应用程序域模型对象映射到关系数据库表的编程技术。
区别:
JPA是一个规范,Hibernate是一个JPA提供者或实现。通过Spring Data Jpa,可以使用Hibernate、Eclipse Link或任何其他JPA提供程序。可以使用@Transactional注释以声明方式控制事务边界。
环境搭建
1.创建springboot项目,名字随意。首先找到resource下面的application.properties,开始配置,代码如下。(在图片中将会详细的进行解释)先展示一波整体的项目结构
#mysql
spring.datasource.url=jdbc:mysql://localhost:3307/hibernate?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
# Specify the DBMS
spring.jpa.database=MYSQL
# Show or not log for each sql query
spring.jpa.show-sql=true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto=update
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
2.关于pom.xml的相关jar包(在创建项目的时候可以手动添加,当然也可以在项目创建好了之后再胚补上对应的配置)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.修改XXXApplication(项目名+Application),如图所示
至此,基础的配置文件就已经基本完成啦
定义实体类
创建包Entity,在该包下面创建实体类的基类BaseEntity
@MappedSuperclass
//@MappedSuperclass标识的类表示其不能映射到数据库表,因为其不是一个完整的实体类,但它所拥有的属性能够映射到其子类所在的表中
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
@Column(name = "name")
protected String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建实体类User继承基类BaseEntity
@Entity//标识实体类
@Table(name="Hibernate_User")//对应数据库中的表名
public class User extends BaseEntity {
public User() {
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
定义数据操作接口
package com.ychd.cn.hibernate_study.dao.repository;
import com.ychd.cn.hibernate_study.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
/**
* 定义用户的数据操作接口
*
* @author ydy
* @create 2019-04-11 10:39
*/
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
/**
* 根据id查找用户
* @param id 用户id
* @return 用户信息
*/
User findById(Long id);
/**
* @param user
* @return
*/
User save(User user);
/**
* 根据姓名查找用户的信息
*
* @param name 用户名
* @return 用户信息
*/
@Query(value = "SELECT * FROM Hibernate_User WHERE name=?", nativeQuery = true)
User findName(String name);
/**
* 查找所有用户信息
* @return 用户信息的集合
*/
List<User> findAll();
/**
* 根据用户id删除用户信息
* @param id 用户id
* @return 受影响的行数
*/
@Transactional
@Modifying
@Query(value = "delete from hibernate_user where id=? ", nativeQuery = true)
Integer deleteById(Long id);
/**
* 根据用户id和用户名删除用户信息
* @param id 用户id
* @return 受影响的行数
*/
@Transactional
@Modifying
@Query(value = "delete from hibernate_user where id=? and username=?", nativeQuery = true)
Integer deleteByIdAndName(Long id, String username);
}
该接口继承JpaRepository<User, Integer>,从此就获得了许多神奇的力量,我们先来看一波源码
测试
创建对应的测试类UserRepositoryTestCase
- 测试save方法
package com.ychd.cn.hibernate_study;
import com.ychd.cn.hibernate_study.Entity.User;
import com.ychd.cn.hibernate_study.dao.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTestCase {
@Autowired
private UserRepository userRepository;
@Test
public void save(){
User user=new User();
user.setId(1L);
user.setName("张三1");
userRepository.save(user);
System.err.println("user = " + user);
}
@Test
public void findName(){
User user=userRepository.findName("张三4");
System.out.println("user = " + user);
}
@Test
public void findById(){
Long id=1l;
User u=userRepository.findById(id);
System.out.println("u = " + u);
}
@Test
public void findAll(){
List<User> list=userRepository.findAll();
System.out.println("list = " + list);
}
@Test
public void deleteById(){
Long id=2l;
Integer rows=userRepository.deleteById(id);
if(rows==1){
System.out.println("受影响行数rows = " + rows);
}else{
System.out.println("失败");
}
}
@Test
public void deleteByIdAndName(){
Integer rows=userRepository.deleteByIdAndName(6l,"张三4");
System.out.println("rows = " + rows);
}
}
我们发现数据库多了一张表,并且在控制台,我们发现
测试findById
可以发现,确实很神奇,我们在定义接口的时候并没有去写对应的SQL语句,但是却可以直接调用这些方法,这就是继承JpaRepository的神奇力量,当然如果我们要自己写的话,也是可以的
测试findName
测试deleteByIdAndName
在后面的话就开始写Service,定义异常,定义IUserService接口,再接着写ServiceImpl各种实现类,然后再ServiceTestCase,最后Controller以及界面等。这里就不详细介绍了,和之前springboot用法一样一样的,。