Spring Data Jpa 基本使用
前言:
Spring Data JPA 是 spring data 项目下的一个模块。提供了一套基于 JPA标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA 来实现的。
一、创建Spring Data Jpa项目
1、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2、配置数据源信息
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=tianya
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
server.port=8010
logging.level.org.springframework=error
#spring.jpa.generate-ddl=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.jdbc.batch_size=50
logging.level.org.hibernate.type.descriptor.sql=trace
3、编写Dao层
public interface UsersDao extends JpaRepository<Users, Integer> {}
4、User
@Entity
@Table(name="t_users")
public class Users implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=GenerationType.IDENTITY 自增长
@Column(name="userid")
private Integer userid;
@Column(name="username")
private String username;
@Column(name="userage")
private Integer userage;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getUserage() {
return userage;
}
public void setUserage(Integer userage) {
this.userage = userage;
}
@Override
public String toString() {
return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]";
}
}
5、编写测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsersDaoImplTest {
@Autowired
private UsersDao usersDao;
/**
* 添加用户
*/
@Test
@Transactional// 在测试类对于事务提交方式默认的是回滚。
@Rollback(false)//取消自动回滚
public void testInsertUsers(){
Users users = new Users();
users.setUserage(24);
users.setUsername("张三");
this.usersDao.save(users);
}
}
二、Spring Data Jpa 接口继承结构
三、Spring Data Jpa 运行原理
@PersistenceContext(name="entityManagerFactory")
private EntityManager em;
@Test
public void test1(){
//org.springframework.data.jpa.repository.support.SimpleJpaRepositor y@fba8bf
//System.out.println(this.usersDao);
//class com.sun.proxy.$Proxy29 代理对象 是基于 JDK 的动态代理方式创建的
//System.out.println(this.usersDao.getClass());
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
//getRepository(UsersDao.class);可以帮助我们为接口生成实现类。而 这个实现类是 SimpleJpaRepository 的对象
//要求:该接口必须要是继承 Repository 接口
UsersDao ud = factory.getRepository(UsersDao.class);
System.out.println(ud);
System.out.println(ud.getClass());
}
四、Repository 接口
Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口 Repository 提供了两种查询方式的支持
1)基于方法名称命名规则查询
2)基于@Query 注解查询
1、方法命名规则查询
规则:
findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)
关键字 | 方法命名 | sql where 字句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equal | findById, | findByIdEquals |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEqual | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEqual | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,Not Null | findByNameNotNull | where name is not |
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(?) |
创建接口
/**
* Repository接口讲解
* @author Administrator
*
*/
public interface UsersDao extends Repository<Users, Integer> {
//方法名称命名规则
List<Users> findByUsernameIs(String string);
List<Users> findByUsernameLike(String string);
List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);
}
测试类
/**
* Repository接口测试
* @author Administrator
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {
@Autowired
private UsersDao usersDao;
/**
* 需求:使用用户名作为查询条件
*/
@Test
public void test1(){
/**
* 判断相等的条件,有三种表示方式
* 1,什么都不写,默认的就是做相等判断
* 2,Is
* 3,Equal
*/
List<Users> list = this.usersDao.findByUsernameIs("王五");
for (Users users : list) {
System.out.println(users);
}
}
/**
* 需求:根据用户姓名做Like处理
* Like:条件关键字
*/
@Test
public void test2(){
List<Users> list = this.usersDao.findByUsernameLike("王%");
for (Users users : list) {
System.out.println(users);
}
}
/**
* 需求:查询名称为王五,并且他的年龄大于等于22岁
*/
@Test
public void test3(){
List<Users> list = this.usersDao.findByUsernameAndUserageGreaterThanEqual("王五", 22);
for (Users users : list) {
System.out.println(users);
}
}
}
2、基于@Query注解查询
JPQL:
通过 Hibernate 的 HQL 演变过来的。他和 HQL 语法及其相似。
创建接口
/**
* Repository接口讲解
* @author Administrator
*
*/
public interface UsersDao extends Repository<Users, Integer> {
//使用@Query注解查询
@Query(value="from Users where username = ?")
List<Users> queryUserByNameUseJPQL(String name);
@Query("from Users where username like ?")
List<Users> queryUserByLikeNameUseJPQL(String name);
@Query("from Users where username = ? and userage >= ?")
List<Users> queryUserByNameAndAge(String name,Integer age);
}
测试类
/**
* Repository接口测试
* @author Administrator
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {
@Autowired
private UsersDao usersDao;
/**
* 测试@Query查询 JPQL
*/
@Test
public void test4(){
List<Users> list = this.usersDao.queryUserByNameUseJPQL("王五");
for (Users users : list) {
System.out.println(users);
}
}
/**
* 测试@Query查询 JPQL
*/
@Test
public void test5(){
List<Users> list = this.usersDao.queryUserByLikeNameUseJPQL("王%");
for (Users users : list) {
System.out.println(users);
}
}
/**
* 测试@Query查询 JPQL
*/
@Test
public void test6(){
List<Users> list = this.usersDao.queryUserByNameAndAge("王五", 22);
for (Users users : list) {
System.out.println(users);
}
}
}
3、通过 SQL 语句查询
/**
* Repository接口讲解
* @author Administrator
*
*/
public interface UsersDao extends Repository<Users, Integer> {
//使用@Query注解查询SQL
//nativeQuery:默认的是false.表示不开启sql查询。是否对value中的语句做转义。
@Query(value="select * from t_users where username = ?",nativeQuery=true)
List<Users> queryUserByNameUseSQL(String name);
@Query(value="select * from t_users where username like ?",nativeQuery=true)
List<Users> queryUserByLikeNameUseSQL(String name);
@Query(value="select * from t_users where username = ? and userage >= ?",nativeQuery=true)
List<Users> queryUserByNameAndAgeUseSQL(String name,Integer age);
}
4、通过@Query 注解完成数据更新
/**
* Repository接口讲解
* @author Administrator
*
*/
public interface UsersDao extends Repository<Users, Integer> {
@Query("update Users set userage = ? where userid = ?")
@Modifying //@Modifying当前语句是一个更新语句
void updateUserAgeById(Integer age,Integer id);
}
五、JpaRepository 接口
JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。
1、创建接口
/**
* JpaRepository接口
* @author Administrator
*
*/
public interface UsersDao extends JpaRepository<Users, Integer>{
}
2、测试类
/**
* JpaRepository接口测试
* @author Administrator
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RepositoryTest {
@Autowired
private UsersDao usersDao;
/**
* 查询全部数据
*/
@Test
public void test1(){
List<Users> list = this.usersDao.findAll();
for (Users users : list) {
System.out.println(users);
}
}
}
无论风雨,和自己一决胜负吧