SpringData Jpa

SpringData JPA

  • springdata 学习日志--day1
    • 1.Spring-data-jpa的基本介绍
    • 2.与Spring的整合
    • 3.用法与细节

springdata 学习日志–day1

1.Spring-data-jpa的基本介绍

  1. spring-data jpa表示与jpa的整合,hibernate实现标准由jpa提供(接口)。
  2. 在原生的hibernate中操作数据库的对象为Session,在JPA中叫EntityManager,在MyBatis中叫SqlSession;
  3. 在ORM框架中,都会提供基本的CRUD功能,如果用原生的框架,一般业务逻辑代码会自定义,自己编写sql语句,而spring-data jpa的强大之处就是几乎可以不需要写一条sql,实现对复杂逻辑的业务sql实现。

2.与Spring的整合

`














    
    
    
    
        
    
    
        
            
            
            
            
        
    
    
        
    
    
        
            
            
            
            
            
            
            
        
    




    



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    




    
        
        
        
        
        
        
        
        
    



    
    

`

3.用法与细节

  1. XXXRepositoryImpl不需要实现XXXRepository接口,因为后者继承了JpaRepository如果我们的UserRepositoryImpl实现了UserRepository接口,导致的后果就是我们势必需要重写里面的所有方法,这是Java语法的规定,如此一来,悲剧就产生了,UserRepositoryImpl里面我们有很多的@Override方法,这显然是不行的,结论就是,这里我们不用去写implements部分。
  2. for instance:
第一步-建表
第二步-实体类
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String password;
    private String birthday;
    // getter,setter
}
第三步-写接口
public interface UserRepository extends JpaRepository{}
至此User的基础CRUD就ok了。

测试》:

public class UserRepositoryTest {
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void baseTest() throws Exception {
        User user = new User();
        user.setName("Jay");
        user.setPassword("123456");
        user.setBirthday("2008-08-08");
        userRepository.save(user);
//        userRepository.delete(user);
//        userRepository.findOne(1);
    }
}

3.SpringData方法命名规范和原理

在UserRepository接口中定义:
	User findByNameAndPassword(String name, String password);
被翻译成的sql语句:
	select * from user where name = ? and password = ?;

原理是:spring-data-jpa会根据方法的名字来自动生成sql语句,我们只需要按照方法定义的规则即可,上面的方法findByNameAndPassword,spring-data-jpa规定:
方法都以findBy开头,sql的where部分就是NameAndPassword,在属性后面加关键字如 like就可以模糊查询,如User findByNameLike(String name);生成的sql就是select * from user where name like = ?

4.动态查询与分页等
 a.使用JPQL,类似Hibernate的HQL
  前面说到了在UserRepository接口的同一个包下面建立一个普通类UserRepositoryImpl来表示该类的实现类,同时前面也介绍了完全不需要这个类的存在,但是如果使用JPQL的方式就必须要有这个类。

public class StudentRepositoryImpl {
    
    @PersistenceContext
    private EntityManager em;
    @SuppressWarnings("unchecked")
    public Page search(User user) {
        String dataSql = "select t from User t where 1 = 1";
        String countSql = "select count(t) from User t where 1 = 1";
        
        if(null != user && !StringUtils.isEmpty(user.getName())) {
            dataSql += " and t.name = ?1";
            countSql += " and t.name = ?1";
        }
        
        Query dataQuery = em.createQuery(dataSql);
        Query countQuery = em.createQuery(countSql);
        
        if(null != user && !StringUtils.isEmpty(user.getName())) {
            dataQuery.setParameter(1, user.getName());
            countQuery.setParameter(1, user.getName());
        }long totalSize = (long) countQuery.getSingleResult();
        Page page = new Page();
        page.setTotalSize(totalSize);
        List data = dataQuery.getResultList();
        page.setData(data);
        return page;
    }
}

b.使用JPA的动态接口,以类型检查的方式,拼接sql

public interface JpaSpecificationExecutor 

for instance:>

@Service
public class StudentServiceImpl extends BaseServiceImpl implements StudentService {
    
    @Autowired
    private StudentRepository studentRepository;
    
    @Override
    public Student login(Student student) {
        return studentRepository.findByNameAndPassword(student.getName(), student.getPassword());
    }

    @Override
    public Page search(final Student student, PageInfo page) {
        return studentRepository.findAll(new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                
                Predicate stuNameLike = null;//where后面的参数对象
                if(null != student && !StringUtils.isEmpty(student.getName())) {
           // 这里也可以root.get("name").as(String.class)这种方式来强转泛型类型
                    stuNameLike = cb.like(root. get("name"), "%" + student.getName() + "%");
                }
                
                Predicate clazzNameLike = null;
                if(null != student && null != student.getClazz() && !StringUtils.isEmpty(student.getClazz().getName())) {
                    clazzNameLike = cb.like(root. get("clazz"). get("name"), "%" + student.getClazz().getName() + "%");
                }
                
                if(null != stuNameLike) query.where(stuNameLike);
                if(null != clazzNameLike) query.where(clazzNameLike);
                return null;
            }
        }, new PageRequest(page.getPage() - 1, page.getLimit(), new Sort(Direction.DESC, page.getSortName())));
    }
}

你可能感兴趣的:(全栈之路)