springData学习笔记(一)搭建基础springData
springData学习
springData Jpa 是应用于dao层的一个框架,简化数据库开发的,作用和mybatis框架一样,但是在使用方式和底层机制是有所不同的。最明显的特点,开发dao的时候,很多场景我们连sql语句都不需要开发。sql语句有spring生成。
application.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
">
<!-- 对spring和springdataJPA进行配置-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 1、创建数据库连接池-->
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 2、配置一个jpa中很重要的对象,entityManagerFactory
entityManager类似于mybatis中的sqlSession
entityManagerFactory类似于sqlSessionFactory
-->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"></property>
<!-- 扫描实体类-->
<property name="packagesToScan" value="com.lagou.edu.pojo"></property>
<!--指定jpa的具体实现,也就是hibernate-->
<property name="persistenceProvider" >
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
<!--指定jpa的方言-->
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
<!--配置hibernate细节-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--定义hibernate细节-->
<!--配置数据表是否自动创建
因为我们会建立pojo和表之间的关系,程序启动时,如果数据表还没有创建,是否要程序创建
-->
<property name="generateDdl" value="false"></property>
<!--指定数据库类型
hibernate是一个dao层框架,是可以支持多种数据库类型,这里指定使用什么数据库
-->
<property name="database" value="MYSQL"></property>
<!--配置数据库方言
hibernate可以帮助我们拼接sql语句,但是不同的数据库sql语法不同,所以需要我们注入具体的数据库方言
-->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
<!--是否显示sql
执行操作数据库是,是否打印sql
-->
<property name="showSql" value="true"></property>
</bean>
</property>
</bean>
<!-- 3、引用上面创建的entityManagerFactory
jpa:repositories 配置jpa dao层细节
-->
<jpa:repositories base-package="com.lagou.edu.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"></jpa:repositories>
<!-- 4、配置事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 5、声明式事务
tx:annotation-driver
-->
<!-- 6、配置包扫描-->
<context:component-scan base-package="com.lagou.edu"></context:component-scan>
</beans>
resumeDao
public interface ResumeDao extends JpaRepository<Resume,Long>, JpaSpecificationExecutor<Resume> {
@Query("from Resume where id=?1 and name=?2")
List<Resume> findByJPql(Long id,String name);
/**
* 使用原生sql语句,要设置nativeQuery = true,默认为false
* @param name
* @param address
* @return
*/
@Query(value = "select * from tb_resume where name like ?1 and address like ?2",nativeQuery = true)
List<Resume> findBySql(String name,String address);
/**
* 按照方法命名规则
* 按照name模糊查询
*/
List<Resume> findByNameLike(String name);
}
resumeTest
@Autowired
ResumeDao resumeDao;
@Test
public void test(){
List<Resume> all = resumeDao.findAll();
for (Resume so : all) {
System.out.println(so);
}
Optional<Resume> byId = resumeDao.findById(1l);
Resume resume = byId.get();
System.out.println(resume);
}
@Test
public void test1(){
Resume resume=new Resume();
resume.setId(1l);
Example<Resume> of = Example.of(resume);
Optional<Resume> one = resumeDao.findOne(of);
System.out.println(one.get());
}
@Test
public void test2(){
//新增和更新都使用save,没有主键为新增,有主键为修改
Resume resume=new Resume();
resume.setId(5l);
resume.setAddress("西安222");
resume.setPhone("1333333333");
resume.setName("赵六");
Resume save = resumeDao.save(resume);
System.out.println(save);
}
@Test
public void testDel(){
resumeDao.deleteById(4l);
}
/**
* 查询,
* 方式1、调用继承的接口中的方法
* 方式2、引入JPQL(JPA查询语言)进行查询
* 方式3、引入原生sql语句
* 方式4、可以在接口中自定义方法,而且不必写sql语句和JPQL语句(方法命名规则)
* 方式5、动态查询,把参数封装成一个对象,传递给dao层,这个对象就叫Specification
*/
@Test
public void test3(){
List<Resume> byJPql = resumeDao.findByJPql(1l,"张三");
System.out.println(byJPql);
}
@Test
public void test4(){
List<Resume> byJPql = resumeDao.findBySql("张三","北京");
System.out.println(byJPql);
}
@Test
public void test5(){
List<Resume> byNameLike = resumeDao.findByNameLike("张%");
for (Resume resume : byNameLike) {
System.out.println(resume);
}
}
@Test
public void test6(){
/**
* toPredicate动态组装条件
* 借助root,criteriaBuilder完成条件封装
* root帮助获取属性
* criteriaBuilder构建查询条件
* 需求根据name,查询resume,name=“张三”,address like "北%"
*/
Specification<Resume> specification=new Specification<Resume>() {
@Override
public Predicate toPredicate(Root<Resume> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> name = root.get("name");
Path<Object> address = root.get("address");
Predicate predicate1 = criteriaBuilder.equal(name, "张三");
Predicate predicate2 = criteriaBuilder.like(address.as(String.class), "北%");
Predicate and = criteriaBuilder.and(predicate1, predicate2);
return and;
}
};
Optional<Resume> one = resumeDao.findOne(specification);
System.out.println(one.get());
}
@Test
public void test7(){
Sort sort=new Sort(Sort.Direction.DESC,"id");
List<Resume> all = resumeDao.findAll(sort);
for (Resume resume : all) {
System.out.println(resume);
}
}
@Test
public void test8(){
Pageable pageable=new PageRequest(0,2);
Page<Resume> all = resumeDao.findAll(pageable);
for (Resume resume : all) {
System.out.println(resume);
}
}
Resume
@Entity
@Table(name = "tb_resume")
public class Resume {
@Id
/**
* 经常使用的两种生成策略:
* 1、GenerationType.IDENTITY(依赖数据库自增)
* 2、GenerationType.SEQUENCE(序列,主要指oracle)
*/
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "phone")
private String phone;
@Column(name = "address")
private String address;
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;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Resume{" +
"id=" + id +
", name='" + name + '\'' +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
'}';
}
}