引入依赖
<!-- Spring JDBC 的依赖包,使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 将会自动获得HikariCP依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MYSQL包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
数据源配置
关于ddl-auto
的几个选项:
- create: 每次运行程序时,都会重新创建表,故而数据会丢失
- create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
- upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
- validate: 运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
spring.datasource.password=root
spring.datasource.username=root
#spring.datasource.type
# JPA\u914D\u7F6E
spring.jpa.hibernate.ddl-auto=update
# \u8F93\u51FA\u65E5\u5FD7
spring.jpa.show-sql=true
# \u6570\u636E\u5E93\u7C7B\u578B
spring.jpa.database=mysql
实体Model
@Entity(name = "t_user")
@Getter
@Setter
public class User2 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 自增策略
* TABLE: 使用一个特定的数据库表格来保存主键
* SEQUENCE: 根据底层数据库的序列来生成主键,条件是数据库支持序列。这个值要与generator一起使用,generator 指定生成主键使用的生成器(可能是orcale中自己编写的序列)。
* IDENTITY: 主键由数据库自动生成(主要是支持自动增长的数据库,如mysql)
* AUTO: 主键由程序控制,也是GenerationType的默认值。
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
/**
* 不需要映射
*/
@Transient
private String email;
public User2() { }
public User2(String username, String password) {
this.username = username;
this.password = password;
}
public User2(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
}
Repository
/**
* chapter5 JPA Repository
*
* 针对User2操作
*
* 创建UserRepository数据访问层接口,需要继承JpaRepository<T,K>,
* 第一个泛型参数是实体对象的名称,第二个是主键类型。
* 只需要这样简单的配置,该UserRepository就拥常用的CRUD功能,paRepository本身就包含了常用功能。
* 剩下的查询我们按照规范写接口即可,
* JPA支持@Query注解写HQL,也支持findAllByUsername这种根据字段名命名的方式
*/
@Repository
public interface UserRepository extends JpaRepository<User2, Long> {
/**
* 根据用户名查询用户信息
*
* @param username 用户名
* @return 查询结果
*/
List<User2> findAllByUsername(String username);
}
分页示例
//import org.springframework.data.domain.PageRequest;
//import org.springframework.data.domain.Sort;
@RequestMapping(value = "/cutpage")
public List<UserEntity> cutPage(int page)
{
UserEntity user = new UserEntity();
user.setSize(2);
user.setSord("desc");
user.setPage(page);
//获取排序对象
Sort.Direction sort_direction = Sort.Direction.ASC.toString().equalsIgnoreCase(user.getSord()) ? Sort.Direction.ASC : Sort.Direction.DESC;
//设置排序对象参数
Sort sort = new Sort(sort_direction, user.getSidx());
//创建分页对象
PageRequest pageRequest = new PageRequest(user.getPage() - 1,user.getSize(),sort);
//执行分页查询
return userJPA.findAll(pageRequest).getContent();
}
验证示例
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
@EnableAutoConfiguration
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Chapter5ApplicationTests.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Chapter5ApplicationTests {
private static final Logger log = LoggerFactory.getLogger(Chapter5ApplicationTests.class);
@Autowired
private UserRepository userRepository;
@Test
public void test1() throws Exception {
final User2 user = userRepository.save(new User2("u1", "p1"));
log.info("[添加成功] - [{}]", user);
final List<User2> u1 = userRepository.findAllByUsername("u1");
log.info("[条件查询] - [{}]", u1);
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("username")));
final Page<User2> users = userRepository.findAll(pageable);
log.info("[分页+排序+查询所有] - [{}]", users.getContent());
userRepository.findById(users.getContent().get(0).getId()).ifPresent(user1 -> log.info("[主键查询] - [{}]", user1));
final User2 edit = userRepository.save(new User2(user.getId(), "修改后的ui", "修改后的p1"));
log.info("[修改成功] - [{}]", edit);
userRepository.deleteById(user.getId());
log.info("[删除主键为 {} 成功] - [{}]", user.getId());
}
}
资料
QueryDSL
QueryDSL是一个Java语言编写的通用查询框架,专注于通过JavaAPI方式构建安全的SQL查询。QueryDSL可以应用到NoSQL数据库上,QueryDSL查询框架可以在任何支持的ORM框架或者SQL平台上以一种通用的API方式来构建SQL。目前QueryDSL支持的平台包扣JPA、JDO、SQL、Java Collections、RDF、Lucene、Hibernate Serch、MongoDB等。
引入依赖
<querydsl.version>4.1.4</querydsl.version>
<!--queryDSL-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
Maven插件
可以通过插件生成Model
<!--该插件可以生成querysdl需要的查询对象,执行mvn compile即可-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
使用QueryDSL
声明JPA服务:
public interface XXXXJPA
extends
JpaRepository<XXXX,Long>,
QueryDslPredicateExecutor<XXXX> {}
查询示例:
//querydsl查询实体
QXXXXEntity _xxxx = QXXXXXEntity.xxxxEntity;
//构建JPA查询对象
JPAQuery<GoodEntity> jpaQuery = new JPAQuery<>(entityManager);
//返回查询接口
return jpaQuery
//查询字段
.select(_xxxx)
//查询表
.from(_xxxx)
//查询条件
.where(_xxxx.type.id.eq(Long.valueOf("1")))
//返回结果
.fetch();
多条件查询发,封装条件请求:
对象Model
public class Inquirer {
//查询条件集合
private List<BooleanExpression> expressions;
public Inquirer() {
this.expressions = new ArrayList<>();
}
/**
* 添加查询条件到Query内的查询集合内
* @param expression 查询条件继承BooleanExpression抽象对象的具体实体对象,querydsl已经封装
* @return
*/
public Inquirer putExpression(BooleanExpression expression)
{
//添加到条件集合
expressions.add(expression);
return this;
}
/**
* 构建出查询findAll函数使用的Predicate接口查询对象<br>
* 调用buidleQuery()可直接作为findAll参数查询条件使用
* @return
*/
public Predicate buidleQuery()
{
//第一个查询条件对象
BooleanExpression be = null;
//遍历所有查询条件,以第一个开始and
for (int i = 0 ; i < expressions.size() ; i++)
{
if(i == 0)
be = expressions.get(i);
else
be = be.and(expressions.get(i));
}
return be;
}
/**
* 将Iterable集合转换成ArrayList集合
* @param iterable 源集合
* @param <T> 类型
* @return arrayList结果
*/
public <T> List<T> iteratorToList(Iterable<T> iterable)
{
List<T> returnList = new ArrayList<T>();
Iterator<T> iterator = iterable.iterator();
while(iterator.hasNext())
{
returnList.add(iterator.next());
}
return returnList;
}
}
查询示例:
//querydsl查询实体
QXXXXEntity _xxxx = QXXXXEntity.xxxxEntity;
//自定义查询对象
Inquirer inquirer = new Inquirer();
//添加查询条件
inquirer.putExpression(_xxxx.type.id.eq(Long.valueOf("1")));
//返回查询结果
return inquirer.iteratorToList(xxxxJPA.findAll(inquirer.buidleQuery()));