本教程分为三类配置
1.spring xml配置文件方式
2.spring 注解配置方式
3.springboot 配置方式
1.xml配置方式
引入maven依赖
org.springframework.data
spring-data-jpa
2.7.0
org.hibernate
hibernate-entitymanager
5.4.33.Final
mysql
mysql-connector-java
5.1.49
com.alibaba
druid
1.2.8
org.springframework
spring-test
5.3.19
junit
junit
4.13.2
test
2.在resources文件夹下创建application.xml文件
3.创建实体类
package com.yujie.model;
import javax.persistence.*;
@Entity
@Table(name = "t_customer")
public class Customer{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String cusName;
set..
get..
}
4.创建dao
package com.yujie.dao;
import com.yujie.model.Customer;
import org.springframework.data.repository.PagingAndSortingRepository;
//PagingAndSortingRepository<实体类,主键类型>
public interface CustomerDao extends PagingAndSortingRepository {
}
5.进行测试
package com.yujie;
import com.yujie.dao.CustomerDao;
import com.yujie.model.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Optional;
@ContextConfiguration("classpath:application.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaXMLTest {
@Autowired
CustomerDao customerDao;
@Test
public void save(){
Customer customer = new Customer();
customer.setCusName("王大宝2");
customerDao.save(customer);
}
@Test
public void delete(){
//删除方式一
Customer customer = new Customer();
customer.setId(10);
customerDao.delete(customer);
//删除方式二
//customerDao.deleteById(10);
}
@Test
public void update(){
Optional byId = customerDao.findById(1);
Customer customer = byId.get();
customer.setCusName("老六");
customerDao.save(customer);
}
@Test
public void find(){
//先查询
Optional byId = customerDao.findById(1);
//orElse如果查询不到不会报错
System.out.println(byId.orElse(null));
}
//分页查询
@Test
public void limitFind(){
Page page = customerDao.findAll(PageRequest.of(2, 2));
//总条数
long totalElements = page.getTotalElements();
//总页数
int totalPages = page.getTotalPages();
//返回的实体对象
List content = page.getContent();
System.out.println(content);
//当前页数
int number = page.getNumber();
}
//查询查询
@Test
public void sort(){
//倒叙排序
Sort.TypedSort sort = Sort.sort(Customer.class);
Sort descending = sort.by(Customer::getId).descending();
Iterable all = customerDao.findAll(descending);
for (Customer customer : all) {
System.out.println(customer);
}
}
}
2.方式二spring 注解进行配置
1.创建配置类
package com.yujie.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableJpaRepositories(basePackages = "com.yujie.dao")
@EnableTransactionManagement
public class SpringDataJPAConfig {
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername("root");
dataSource.setPassword("123123");
dataSource.setUrl("jdbc:mysql:///jpa");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.yujie.model");
factory.setDataSource(dataSource());
return factory;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
2.进行测试,注意测试类和上面的不一样
@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaAnnotaionTest {
@Autowired
CustomerDao customerDao;
@Test
public void save(){
Customer customer = new Customer();
customer.setCusName("王大宝2");
customerDao.save(customer);
}
}
3.springboot 配置方式
导入jpa启动依赖
org.springframework.boot
spring-boot-starter-parent
2.7.0
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
5.1.49
在resources目录下创建application.properties
#自动生成数据库表(关键)
spring.jpa.hibernate.ddl-auto=update
#mysql数据库连接配置(非常重要)
spring.datasource.url = jdbc:mysql:///jpa
#数据库用户名
spring.datasource.username = root
#数据库密码
spring.datasource.password = 123123
#mysql数据库驱动程序(重要)
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
#jpa配置:在控制台显示Hibernate的sql(可选)
spring.jpa.show-sql = true
#其他配置:关闭Thymeleaf 的缓存
spring.thymeleaf.cache = false
# 取消小驼峰到下划线映射(加上这个)
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
创建测试类进行测试
package com;
import com.yujie.SpringbootJpaApplication;
import com.yujie.dao.CustomerDao;
import com.yujie.model.Customer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
//classes指定启动类的位置
@SpringBootTest(classes = SpringbootJpaApplication.class)
class SpringbootJpaApplicationTests {
@Autowired
private CustomerDao customerDao;
@Test
void contextLoads() {
Iterable all = customerDao.findAll();
for (Customer customer : all) {
System.out.println(customer);
}
}
}
打印
Customer{id=1, cusName='宝宝', age=23, addr='北海'}
Customer{id=11, cusName='小王八', age=18, addr='北海大道'}
Customer{id=12, cusName='王大宝', age=19, addr='上海'}
...
复杂查询可以自定义方法,书写JPQL
1.在接口上定义方法
package com.yujie.dao;
import com.yujie.model.Customer;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import javax.transaction.Transactional;
import java.util.List;
public interface CustomerDao extends PagingAndSortingRepository,JpaSpecificationExecutor{
//通过占位符+索引位置 注意:?索引和:属性 在一个方法上,要么统一使用?索引,要么统一使用:属性,混合使用会报错
@Query("FROM Customer WHERE id=?1 OR cusName=?2")
public List findCustomerByIdOrName(Integer id666, String cusName);
//通过@Param注解
@Query("FROM Customer WHERE id=:id")
public Customer findCustomerById(@Param("id") Integer id666);
//修改和删除要加上Modifying以及Transactional注解 JPQL不支持插入,可以使用原始SQL
@Transactional
@Modifying
@Query("UPDATE Customer SET cusName=?1 WHERE id=?2")
public Integer updateCustomer( String cusName,Integer id);
//通过原始SQL查询
@Query(value = "SELECT * FROM t_customer WHERE id=:id",nativeQuery = true)
public Customer findCustomerByIdSQL(@Param("id") Integer id666);
//通过原始SQL更新
@Transactional
@Modifying
@Query(value = "UPDATE t_customer SET cusName=?1 WHERE id=?2 ",nativeQuery = true)
public Integer updateCustomerSQL(String name,Integer id666);
}
2.测试自定义的方法
@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaTest {
@Autowired
CustomerDao customerDao;
@Test
public void findCustomerByIdOrName(){
List customers= customerDao.findCustomerByIdOrName(null,"老六");
System.out.println(customers);
}
@Test
public void findCustomerById(){
Customer customer = customerDao.findCustomerById(1);
System.out.println(customer);
}
@Test
public void updateCustomer(){
Integer count = customerDao.updateCustomer("老六啊", 1);
System.out.println(count);
}
@Test
public void findCustomerByIdSQL(){
Customer customer = customerDao.findCustomerByIdSQL( 1);
System.out.println(customer);
}
@Test
public void updateCustomerSQL(){
Integer customer = customerDao.updateCustomerSQL( "小王八",1);
System.out.println(customer);
}
@Test
public void saveCustomer(){
Integer count = customerDao.saveCustomer("小贱人");
System.out.println(count);
}
}
动态SQL查询
@Test
public void specification(){
//查询出姓小的人并且年龄大于18岁并且地名有北字开头的城市或者年龄大于99的客户然后根据id倒叙输出
Specification specification = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
Path cusName = root.get("cusName");
Path age = root.get("age");
Path addr = root.get("addr");
//客户名字等于王大宝
Predicate cusNameEq = cb.equal(cusName, "小王八");
//客户年龄大于等于18岁
Predicate ageGt = cb.greaterThanOrEqualTo(age, 18);
//99大寿
Predicate ageGt2 = cb.greaterThanOrEqualTo(age, 99);
//模糊查询地址
Predicate like = cb.like(addr,"北%");
//把上面两个子条件拼接成总条件
Predicate var1 = cb.and(cusNameEq, ageGt,like);
Predicate finalResult = cb.or(var1,ageGt2);
return finalResult;
}
};
//倒序
Sort.TypedSort sort = Sort.sort(Customer.class);
Sort descending = sort.by(Customer::getId).descending();
Page all = customerDao.findAll(specification, PageRequest.of(0, 3, descending));
for (Customer customer : all) {
System.out.println(customer);
}
}
打印
Hibernate: select customer0_.id as id1_0_, customer0_.addr as addr2_0_, customer0_.age as age3_0_, customer0_.cusName as cusname4_0_ from t_customer customer0_ where customer0_.cusName=? and customer0_.age>=18 and (customer0_.addr like ?) or customer0_.age>=99 order by customer0_.id desc limit ?
Hibernate: select count(customer0_.id) as col_0_0_ from t_customer customer0_ where customer0_.cusName=? and customer0_.age>=18 and (customer0_.addr like ?) or customer0_.age>=99
Customer{id=21, cusName='小贱人', age=99, addr='上海'}
Customer{id=20, cusName='小王八', age=20, addr='北京'}
Customer{id=11, cusName='小王八', age=18, addr='北海大道'}