原文链接:http://blog.youkuaiyun.com/qq_31001665
如有侵权,请联系博主删除博客,谢谢
更优雅的访问数据库JPA
JPA访问数据库的优点:
通常我们访问数据库归根结底无非就是增删改查,作为开发人员,我们会写大量的SQL,而这些SQL有大多是重复且枯燥的。无非就是库名,表名的不同。为了提高开发效率,我们通常会使用ORM框架,而其中最著名的就是Hibernate。
Hibernate以对象编程闻名,抛弃了面向过程的SQL语言,以类为对象作为查询的依据。并且以HQL语言作为辅助,大大简化了我们编写SQL的难度,将我们从无穷无尽的SQL编写中解放了出来。在SpringBoot中,我们使用JPA来访问数据库,JPA依赖于Hibernate,如果你熟悉Hibernate,那JPA你能够很快上手。如果你不了解Hibernate,那可能你的学习周期稍长。不过没关系,希望我的这篇文章能快速的带你使用JPA。
首先,我们需要引入JPA的依赖,请在pom.xml中添加JPA依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
之后我们在application.xml中添加下配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/blog
username: root
password: 123
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
show-sql: true
其中hbm2ddl.auto是对于数据库表结构的配置,一般有四种配置:
- create:每次加载hibernate都会建一次表,不推荐使用,会丢失表数据。
- create-drop:每次加载建立表,当SessionFactory关闭则自动删除。
- update:第一次会自动创建表,之后只更新数据。即使之后表结构改变,也不会删除之前的数据。也是我们最常用的一种属性。
- valiate:验证数据库中的表进行比较,不创建新表,只插入新值。
接下来我们可以创建我们的实体类了,这里我创建了一个地址类Address:
@Entity
@Table(name = "tp_address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long addressId;
@Column(name = "user_id",nullable = false)
private Long userId;
@Column(name = "add_info",nullable = false)
private String addressInfo;
/** 省略set get方法以及构造器 */
}
我们可以使用@Table来指定表的一些属性,这里我设定了表名。
使用@Id来指明主键,@GeneratedValue来设定自增长。
使用@Column可以设定列的属性,包括非空,名称,唯一,默认值等等。
接下来我们创建一个接口实现JpaRepository或者调用entitymanage的类方法,这一篇我先实现第一种方法来给大家演示,下一篇我们再说后一种方法。
public interface AddressRepository extends JpaRepository<Address,Long> {
List<Address> findByUserId(Long userId);
Address findByAddressIdAndUserId(Long addressId,Long userId);
@Query(value = "select t from Address t where t.addressInfo = :addressInfo")
Address findAddress(@Param("addressInfo") String addressInfo);
}
其中,JPA已经把我们常用的一些增(save),删(delete),改(update),查(find)已经做了一定的封装,我们直接拿来使用就可以了。
其次,我们一可以通过解析方法名创建查询,例如我代码中的第一第二个方法一样,这样就不需要我们添加任何SQL语句。
最后,我们还可以通过@Query来添加注解查询,要注意的是,这里语句并不是SQL语句,而是JPQL语句,如同HQL,代码中Address指的是Address这个类。
另外,参数重@param请一定使用org.springframework.data.jpa.repository.Query,千万别引入ibatis的注解哦。
完成这些,我们的数据库编写其实已经结束了,我们使用测试用例来验证下我们的代码是否可用(也可以写完controller,service后使用postman,我是太懒了,哈哈哈(^-^))。
@RunWith(SpringRunner.class)
@SpringBootTest
public class Round1ApplicationTests {
@Test
public void contextLoads() {
}
@Autowired
private AddressRepository addressRepository
@Test
public void jpaTest() throws Exception{
// 插入10条记录
addressRepository.save(new Address(Long.valueOf(3),"SH"))
addressRepository.save(new Address(Long.valueOf(4),"XA"))
addressRepository.save(new Address(Long.valueOf(5),"BJ"))
addressRepository.save(new Address(Long.valueOf(6),"GZ"))
addressRepository.save(new Address(Long.valueOf(7),"WX"))
addressRepository.save(new Address(Long.valueOf(14),"NC"))
addressRepository.save(new Address(Long.valueOf(15),"HLJ"))
addressRepository.save(new Address(Long.valueOf(15),"XJ"))
addressRepository.save(new Address(Long.valueOf(15),"DL"))
addressRepository.save(new Address(Long.valueOf(16),"M78"))
// 测试查询所有记录
Assert.assertEquals(10,addressRepository.findAll().size())
// 测试查询UserId为7,addressID为5的记录是不是WX
Assert.assertEquals("WX",addressRepository.findByAddressIdAndUserId(Long.valueOf(5),Long.valueOf(7)).getAddressInfo())
// 测试查询15号用户是否是三条记录
Assert.assertEquals(3,addressRepository.findByUserId(Long.valueOf(15)).size())
// 测试查询SH内容用户是不是3号用户
Assert.assertEquals(3,addressRepository.findAddress("SH").getUserId().longValue())
// 测试删除内容是M78的记录
addressRepository.delete(addressRepository.findAddress("M78"))
// 测试查询记录,看删除是否成功
Assert.assertEquals(9,addressRepository.findAll().size())
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
测试结果通过,并且数据库中建立了tp_address表。


我们可以看到我们之前配置的打印SQL也已经生效了。