Springboot+JPA 搭建简易web框架
一. IDEA创建springboot项目
- 创建新项目,选择Spring Initialize
- 选择初始依赖,进行勾选
- 等待springboot依赖导入完毕
二. 添加maven仓库
pom.xml内容如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
<!-- hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入redis,redis主要用做缓存数据库,访问频繁的数据可以存储在这里-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--引入mongodb:文档型的nosql数据库-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-data-mongodb</artifactId>-->
<!--</dependency>-->
<!--RabbitMQ是AMQP高级消息队列协议一种实现,用于在分布式系统中实现对消息的存储和转发-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-amqp</artifactId>-->
<!--<version>2.1.3.RELEASE</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
三. 创建层级包结构
创建以下包结构:
- main
- java
- com.example.demo
- configs 配置类
- entities 实体类
- repository 仓库存储层
- controllers 控制层
- 主执行类
- com.example.demo
- resources
- application.properties 配置文件
- java
注意主执行类的位置:
- 不能直接放在java层下面
- 该类是整个spring容器中所有javaBean对象的入口
- 容器扫描住执行类的同级包及以下的类文件
四. 配置文件resources/application.properties
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORCL
spring.datasource.username=用户名
spring.datasource.password=密码
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
-
配置是否在控制台打印出sql语句:
spring.jpa.show-sql=true
-
配置是否利用程序自动创建数据库表结构:
spring.jpa.hibernate.ddl-auto=update
-
配置redis
# redis相关
spring.redis.host=localhost
spring.redis.port=6379
# Redis服务器连接密码(默认为空)启动redis服务端,使用redis-server.exe redis.windows.conf
spring.redis.password=redis密码
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=1000
五. 具体实现
i. 执行类
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
//import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @SpringBootApplication 注解:表明该类是整个spring容器中所有javaBean对象的入口
* SpringApplication.run() 方法启动spring容器,返回spring的ApplicationContext对象
* exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class} 未加载数据库
*/
//@SpringBootApplication
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class DemoApplication{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
/**
* redisTemplate()方法用于构建RedisTemplate并初始化用户数据存储的序列化方式
*/
@Bean
@SuppressWarnings({"rawtypes","unchecked"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
//redisTemplate.setKeySerializer(new StringRedisSerializer()) 定义了redis的key为String类型
//new JdkSerializationRedisSerializer()表示java的Object
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
ii. 各层代码
1. entities层代码示例:
package com.example.demo.entities;
import javax.persistence.*;
import java.io.Serializable;
/**
* @Id 标注用于声明一个实体类的属性映射为数据库的主键列
* @GeneratedValue 用于标注主键的生成策略,通过strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略
*/
@Entity
public class Person implements Serializable {
//strategy指定id生成策略,GenerationType.SEQUENCE根据序列,generator表示指定策略的方法,这里指oracle创建的序列
/**
* create sequence personId_seq
* increment by 1
* start with 1
* maxvalue 999999999;
*
* initialValue 序列初始值
* allocationSize 每次值增加的大小
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="idSeqGenerator")
@SequenceGenerator(name="idSeqGenerator", sequenceName = "person_id_seq",
initialValue = 1, allocationSize = 1)
private Long id;
private String name;
private Integer age;
private String address;
public Person() {
}
public Person(Long id, String name, Integer age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
//----------get/set 方法----------
2. repository层代码示例:
package com.example.demo.repository;
import com.example.demo.entities.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface JpaPersonRepository extends JpaRepository<Person, String> {
List<Person> findByAddress(String address);
Person findByNameAndAddress(String name, String address);
}
package com.example.demo.repository;
import com.example.demo.entities.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
/**
* @Autowired只按照byType 注入;@Resource默认按byName自动注入,也提供按照byType 注入;
* springboot中构建RedisTemplate的代码放在启动类中
*/
@Repository
public class RedisPeopleRepository {
//RedisTemplate能够实现序列化和连接过程的自动化管理
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Resource(name="redisTemplate")
ValueOperations<Object, Object> valOps;
public void save(Person person){
valOps.set(person.getName(), person);
}
public Person getPerson(String name){
return (Person) valOps.get(name);
}
}
3. controllers层代码示例:
package com.example.demo.controllers;
import com.example.demo.entities.Person;
import com.example.demo.repository.JpaPersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class JpaPersonController {
@Autowired
private JpaPersonRepository jpaPersonRepository;
@RequestMapping("/save")
public String save(String name, String address, Integer age){
jpaPersonRepository.save(new Person(null, name, age, address)) ;
return "success";
}
@RequestMapping("/address")
public List<Person> address(String address){
List<Person> people = jpaPersonRepository.findByAddress(address);
return people;
}
@RequestMapping("/nameAndAddress")
public Person nameAndAddress(String name, String address){
Person people = jpaPersonRepository.findByNameAndAddress(name, address);
return people;
}
@RequestMapping("/sort")
public List<Person> sort(){
List<Person> people = jpaPersonRepository.findAll(Sort.by(Sort.Direction.ASC,"age"));
return people;
}
public Page<Person> page(){
Page<Person> pagePeople = jpaPersonRepository.findAll(PageRequest.of(1,2));
return pagePeople;
}
}
package com.example.demo.controllers;
import com.example.demo.entities.Person;
import com.example.demo.repository.RedisPeopleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RedisPeopleController {
@Autowired
RedisPeopleRepository redisPeopleRepository;
@RequestMapping("/setPerson")
public void setPerson(){
Person person = new Person(2L,"zhangsan", 32, "tianyalan");
redisPeopleRepository.save(person);
}
@RequestMapping("/getPerson")
public Person getPerson(@Param("name") String name){
return redisPeopleRepository.getPerson(name);
}
}