Java后端爱上SpringBoot 第二节:Spring-Data-Jpa应用
何为Spring-Data-Jpa?
首先要明确的是JPA是一个规范,并不是一个框架,Spring-data-jpa就是一群Spring的抠脚大汉写的一个符合JPA规范的一个封装了不易上手的Hibernate的易上手DAO框架。
为什么要用Spring-Data-Jpa?
- 能大大的简化我们DAO层的开发(这个现如今的DAO层框架都能做到,但是Spring-Data-Jpa做的更多)
- 可以解放写SQL的工作量
- 不用做数据库初始化建表语句的管理
- Jdk生成要实行ORM(现在还没有做到),在DAO层从一大堆SQL转变成关系-对象的模式
- 有成熟的生态圈
还有别的一些好处,就在此不在说了,有兴趣的道友可以自己搜一下。
使用JPA的一些思想上的转变
-
要把传统的在SQL上实现一大堆的业务逻辑分解成多的简单的业务逻辑
贫道的栗子:在日常开发中,特别是三五年前的项目,有些程序员就是要用一个很大很大的SQL(超过100行的SQL)来做一个复杂的业务逻辑,他写的代码让后人无法可写。 -
允许添加冗余的字段,以减少关联查询带来的效率问题
-
在插入数据时尽量多做,在查询数据时尽量少做
一些链接
- 【原创】纯干货,Spring-data-jpa详解,全方位介绍。
- spring data jpa 查询自定义字段,转换为自定义实体
- Spring Data JPA 介绍和使用
- Spring-Data-Jpa官网文档
SpringBoot整合Spring-Data-Jpa
上一节其实都说了,在这里再啰嗦一遍吧。
- Maven添加依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
- 添加数据库配置和JPA配置
spring:
###数据库配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/spring?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&allowPublicKeyRetrieval=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
username: hyn
password: hyn1234
###JPA配置
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
show-sql: true
generate-ddl: true
database: mysql
Spring-Data-Jpa应用
自动建表功能
创建一个实体SysUser
package com.hyn.spring.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
*
* @Title: SysUser.java
* @Package com.hyn.spring.domain
* @Description: TODO
* @author hyn
* @date 2018年12月9日 下午1:38:53
* @version V1.0
*/
@Entity
@Table(name = "sys_user")
@EntityListeners(AuditingEntityListener.class)
public class SysUser implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid") // 这个是hibernate的注解/生成32位UUID
@GeneratedValue(generator = "idGenerator")
/**
* 用户ID
*/
@Column(columnDefinition="varchar(36) not null comment '用户ID' ")
String id;
/**
*
* 用户状态
*/
@Column(columnDefinition = "enum('true','false') default 'true' not null comment '用户状态' ")
String status;
/**
* 邮箱
*/
@Column(columnDefinition = "varchar(20) not null default '' comment '用户邮箱'" )
private String email;
/**
* 登录用户名
*/
@Column(columnDefinition = "varchar(20) not null unique default '' comment '登录用户名'" )
private String loginName;
/**
* 用户名名称
*/
@Column(columnDefinition = "varchar(10) not null default '' comment '用户名称'" )
private String userName;
/**
* 密码策略
*/
@Column(columnDefinition = "varchar(100) not null default '888888' comment '登录密码'" )
private String password;
/**
* 电话
*/
@Column(columnDefinition = "varchar(11) not null unique default '' comment '手机号码'" )
private String phone;
/**
* 更新时间
*/
@Temporal(TemporalType.TIMESTAMP)
@Column(columnDefinition = "timestamp default current_timestamp on update current_timestamp comment '更新时间'")
@UpdateTimestamp
private Date moditime;
//省略get set
启动项目会生成自动建表语句,如果你没有看到自动建表,请检查你的配置:
spring.jpa.properties.hibernate.hbm2ddl.auto有几种状态,我这里去贴一下别人的:
- validate 加载hibernate时,验证创建数据库表结构
- create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
- create-drop 加载hibernate时创建,退出是删除表结构
- update 加载hibernate自动更新数据库结构
- none 不自动建表,也不检查表结构
自动注入时间
细心的道友会发现为什么实体上会加一个 @EntityListeners(AuditingEntityListener.class) 这个注解,在这里解释一下,这个注解是用来自动更新时间用的,比如每个表都应该有一个moditime字段用来记录这条数据最后更新的时间,如果让自己手动去维护这个字段就很麻烦,JPA提供了一个 @UpdateTimestamp注解来自动更新moditime,@EntityListeners 是用来开启这个实体上自动更新时间的。不过除了需要加上这个注解以为,还去要在启动类上加上 @EnableJpaAuditing注解,来开启SpringBoot的Jpa的自动注解功能。
@SpringBootApplication
@EnableJpaAuditing
@EnableSwagger2
public class SpringFirstApplication {
public static void main(String[] args) {
SpringApplication.run(SpringFirstApplication.class, args);
}
}
单表操作
新增数据
创建DAO层
package com.hyn.spring.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.hyn.spring.entity.SysUser;
public interface ISysUserRepository extends JpaRepository<SysUser, String>,JpaSpecificationExecutor<SysUser>{
}
单个新增
@Override
public String save(SysUserVO sysUserVO) {
SysUser sysUser = new SysUser();
sysUser.setEmail(sysUserVO.getEmail());
sysUser.setLoginName(sysUserVO.getLoginName());
sysUser.setPassword(sysUserVO.getPassword());
sysUser.setPhone(sysUserVO.getPhone());
sysUser.setStatus(sysUserVO.getStatus());
sysUser.setUserName(sysUserVO.getUserName());
iSysUserRepository.save(sysUser);
return "success";
}
批量新增
@Override
@Transactional(rollbackOn=Exception.class)
public String batchSave(List<SysUserVO> sysUserVOs) {
List<SysUser> sysUsers = new ArrayList<>(sysUserVOs.size());
for (SysUserVO sysUserVO : sysUserVOs) {
SysUser sysUser = new SysUser();
sysUser.setEmail(sysUserVO.getEmail());
sysUser.setLoginName(sysUserVO.getLoginName());
sysUser.setPassword(sysUserVO.getPassword());
sysUser.setPhone(sysUserVO.getPhone());
sysUser.setStatus(sysUserVO.getStatus());
sysUser.setUserName(sysUserVO.getUserName());
sysUsers.add(sysUser);
}
iSysUserRepository.saveAll(sysUsers);
return "success";
}
注意进行事务控制,spring-data-jpa默认是开启事务控制的,并且进行手动回滚 @Transactional(rollbackOn=Exception.class)
,这个是个好习惯。
注意这里有坑:Spring-data-jpa自带的批量插入接口,不适合大数据的插入,不是批量提交,是一条一条的INSERT来执行的,因为JPA每次都要检查此条数据在数据库中是否存在,如果存在是进行更新的。效率特别差,提交千条数据以上请使用别的方法。
批量保存 Jpa saveAll() 和 JdbcTemplate batchUpdate()效率对比
删除数据
删除数据只是一行代码,但是不管在那个地方写删除数据是特别谨慎的事情,应该多进行验证和确认。
@Override
public String delete(String id) {
iSysUserRepository.deleteById(id);
return "success";
}
注意点:删除数据的时候如果有关联关系,注意删除关联关系,才能删除此条数据。
修改数据
修改数据需要验证数据是否存在,在进行修改,修改数据的时候需要提交实体的所有属性,否则会将实体的属性更新为空!
@Override
public String update(SysUserVO sysUserVO) {
Optional<SysUser> optional = iSysUserRepository.findById(sysUserVO.getId());
if (optional.isPresent()) {
SysUser sysUser = optional.get();
sysUser.setEmail(sysUserVO.getEmail());
sysUser.setLoginName(sysUserVO.getLoginName());
sysUser.setPassword(sysUserVO.getPassword());
sysUser.setPhone(sysUserVO.getPhone());
sysUser.setStatus(sysUserVO.getStatus());
sysUser.setUserName(sysUserVO.getUserName());
sysUser.setId(sysUserVO.getId());
iSysUserRepository.save(sysUser);
return "success";
} else {
return "所更新的数据不存在!";
}
}
查询数据
普通查询
在ISysUserRepository加入以下方法:
/**
* 根据用户登录名和密码查询
* @param loString
* @param password
*/
Optional<SysUser> findByLoginNameAndPassword(String loginname,String password);
注意:使用Java 8自带的Optional来指示缺省值,以避免空指针。
Distinct查询
/**
* 根据用户名 Distinct 查询用户
* @param userName
* @return
*/
Optional<List<SysUser>> findEmailDistinctByUserName(String userName);
IgnoreCase查询
/**
* 根据用户名 IgnoreCase 查询用户 忽略username大小写
* @param userName
* @return
*/
Optional<List<SysUser>> findByUserNameIgnoreCase(String userName);
生成SQL:
SELECT
sysuser0_.id AS id1_0_,
sysuser0_.email AS email2_0_,
sysuser0_.login_name AS login_na3_0_,
sysuser0_.moditime AS moditime4_0_,
sysuser0_.PASSWORD AS password5_0_,
sysuser0_.phone AS phone6_0_,
sysuser0_.STATUS AS status7_0_,
sysuser0_.user_name AS user_nam8_0_
FROM
sys_user sysuser0_
WHERE
upper( sysuser0_.user_name ) = upper( ? )
ORDER BY查询
/**
* 根据用户名 OrderBy moditime 查询用户
* @param userName
* @return
*/
Optional<List<SysUser>> findByUserNameOrderByModitimeAsc(String userName);
生成SQL:
SELECT
sysuser0_.id AS id1_0_,
sysuser0_.email AS email2_0_,
sysuser0_.login_name AS login_na3_0_,
sysuser0_.moditime AS moditime4_0_,
sysuser0_.PASSWORD AS password5_0_,
sysuser0_.phone AS phone6_0_,
sysuser0_.STATUS AS status7_0_,
sysuser0_.user_name AS user_nam8_0_
FROM
sys_user sysuser0_
WHERE
sysuser0_.user_name =?
ORDER BY
sysuser0_.moditime ASC
OR查询
/**
* 根据用户名 or登录用户 查询用户
* @param userName
* @param userName
* @return
*/
Optional<List<SysUser>> findByUserNameOrLoginName(String userName,String loginName);
生成SQL:
SELECT
sysuser0_.id AS id1_0_,
sysuser0_.email AS email2_0_,
sysuser0_.login_name AS login_na3_0_,
sysuser0_.moditime AS moditime4_0_,
sysuser0_.PASSWORD AS password5_0_,
sysuser0_.phone AS phone6_0_,
sysuser0_.STATUS AS status7_0_,
sysuser0_.user_name AS user_nam8_0_
FROM
sys_user sysuser0_
WHERE
sysuser0_.user_name =?
OR sysuser0_.login_name =?
还有Between,LessThan,GreaterThan,和Like表达式就个个举例了,频道有时间会补充的。
特殊参数查询
/**
* 分页查询
* @param userName
* @param pageable
* @return
*/
Page<SysUser> findByUserName(String userName,Pageable pageable);
生成SQL:
SELECT
sysuser0_.id AS id1_0_,
sysuser0_.email AS email2_0_,
sysuser0_.login_name AS login_na3_0_,
sysuser0_.moditime AS moditime4_0_,
sysuser0_.PASSWORD AS password5_0_,
sysuser0_.phone AS phone6_0_,
sysuser0_.STATUS AS status7_0_,
sysuser0_.user_name AS user_nam8_0_
FROM
sys_user sysuser0_
WHERE
sysuser0_.user_name =?
ORDER BY
sysuser0_.moditime DESC
LIMIT ?
运用@Query
/**
* @Query 测试
* @param userName
* @return
*/
@Query(value = "select * from sys_user where user_name = ?1", nativeQuery = true)
Optional<List<SysUser>> findByUserName(String userName);
生成SQL:
select * from sys_user where email_address = ?1
写成 select * 标识一下。
@Query 命名参数
/**
* @Query 测试
* @param userName
* @return
*/
@Query(value = "select * from sys_user where email like :email", nativeQuery = true)
Optional<List<SysUser>> findByEmail(@Param("email") String email);
生成SQL:
select * from sys_user where email like ?
贴一下官方的代码:
关键词 | 样品 | JPQL代码段 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
多表操作
在日常开发中,一定会有多表的关联关系,不外乎一对一,一对多(多对一),多对对,这几种关联关系,以下依次介绍这几种关联关系的使用方式,来建立一个用户-工位,用户-部门,用户-角色:
一对一关系
以上只建立了用户的实体,而一个用户只能拥有一个工位,因此用户和工位是一对一关系
创建一个工位实体:
package com.hyn.spring.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Entity
@Table(name = "sys_station")
@EntityListeners(AuditingEntityListener.class)
public class SysStation implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid") // 这个是hibernate的注解/生成32位UUID
@GeneratedValue(generator = "idGenerator")
/**
* 工位ID
*/
@Column(columnDefinition="varchar(36) not null comment '工位ID' ")
String id;
/**
* 个人电脑编号
*/
@Column(columnDefinition = "varchar(10) not null unique default '' comment '个人电脑编号'" )
private String pcCode;
/**
* pcIP 个人电脑IP
*/
@Column(columnDefinition = "varchar(10) not null unique default '' comment '个人电脑IP'" )
private String pcIP;
//省略get set
}
为用户实体和工位实体添加关联关系,这个关联关系是单向的也可以是双向的,我们这里建立一个双向的。
在用户实体中加入:
@OneToOne(mappedBy="sysUser")
SysStation sysStation;
在工位实体中加入:
@OneToOne
@JoinColumn(name="user_id")
SysUser sysUser;
@OneToOne表示实体与实体的关联关系
@JoinColumn 定义了与关联实体关联的column字段名
关于关联双向和单向的问题,道友可以参考这篇文章,写的很详细:hibernate的OneToOne映射
在新增工位方法中,添加关联用户的代码
@Override
public String save(SysStationVO sysStationVO) {
SysStation sysStation=new SysStation();
sysStation.setPcCode(sysStationVO.getPcCode());
sysStation.setPcIP(sysStationVO.getPcIP());
//关联用户
SysUser sysUser=new SysUser();
sysUser.setId(sysStationVO.getUserId());
sysStation.setSysUser(sysUser);
iSysStationRepository.save(sysStation);
return "success";
}
新增工位时就可以关联用户了
一对多(多对一)关系
多个用户可以对应一个部门,一个部门有多个用户,因此用户-部门是一对多关系。
建立部门实体:
package com.hyn.spring.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
*
* @Title::SysOrganization.java
* @Package :com.summit.homs.dto.sys
* @Description: TODO
* @author: hyn
* @date: 2018年8月28日 下午9:10:40
* @version : 1.0
*/
@Entity
@Table(name = "sys_organization")
@EntityListeners(AuditingEntityListener.class)
@ApiModel(value="组织机构")
public class SysOrganization implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid") // 这个是hibernate的注解/生成32位UUID
@GeneratedValue(generator = "idGenerator")
/**
* 机构ID
*/
@Column(length = 36, columnDefinition = "varchar(36) COMMENT '机构ID'")
String id;
/**
* 机构代码(行政区划码)
*/
@Column(columnDefinition = "VARCHAR(6) not null default '' COMMENT '机构代码(行政区划码)'")
private String code;
/**
* 机构名称
*/
@Column(columnDefinition = "VARCHAR(20) unique not null default '' COMMENT '机构名称'")
private String name;
/**
* 机构类型
*/
@Column(columnDefinition = "VARCHAR(10) not null COMMENT '机构类型'")
private String type;
/**
* 机构等级
*/
@Column(columnDefinition = "VARCHAR(10) not null default '' COMMENT '机构等级'")
private String level;
/**
* 上级节点ID
*/
@Column(columnDefinition = "VARCHAR(36) not null default '' COMMENT '机构等级'")
private String pid;
/**
* 电话
*/
@Column(columnDefinition = "VARCHAR(11) not null default '' COMMENT '手机号码'")
private String phone;
/**
* 地址
*/
@Column(columnDefinition = "VARCHAR(100) not null default '' COMMENT '地址'")
private String addr;
/**
* 负责人
*/
@Column(columnDefinition = "VARCHAR(10) not null default '' COMMENT '负责人'")
private String principal;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间", name = "moditime", example = "2018-08-27 00:00:00")
@Temporal(TemporalType.TIMESTAMP)
@Column(columnDefinition = "timestamp not null default current_timestamp comment '更新时间'")
@UpdateTimestamp
private Date moditime;
@OneToMany(mappedBy="sysOrganization")
List<SysUser> sysUsers;
}
用户中加入关联关系:
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="org_id")
SysOrganization sysOrganization;
建立关联代码:
@Override
public String save(SysOrganizationVO sysUserVO) {
SysOrganization sysOrganization = new SysOrganization();
sysOrganization.setAddr(sysUserVO.getAddr());
sysOrganization.setCode(sysUserVO.getCode());
sysOrganization.setLevel(sysUserVO.getLevel());
sysOrganization.setName(sysUserVO.getName());
sysOrganization.setPhone(sysUserVO.getPhone());
sysOrganization.setPid(sysUserVO.getPid());
sysOrganization.setPrincipal(sysUserVO.getPrincipal());
sysOrganization.setType(sysUserVO.getType());
SysOrganization resultOrganization= iSysOrganizationRepository.save(sysOrganization);
//用户关联部门结构
List<String> userIds = sysUserVO.getUserIds();
if (userIds != null && userIds.size() > 0) {
for (String userId : userIds) {
Optional<SysUser> optional= iSysUserRepository.findById(userId);
if(optional.isPresent())
{
SysUser sysUser=optional.get();
sysUser.setSysOrganization(resultOrganization);
iSysUserRepository.saveAndFlush(sysUser);
}
}
}
return "success";
}
多对多关系
一个用户可以对应多个角色,多个角色也可以被一个用户拥有,因此是多对多关系,建立角色的实体。
package com.hyn.spring.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
*
* @Title: SysRole.java
* @Package com.hyn.spring.entity
* @Description: TODO
* @author hyn
* @date 2018年12月13日 下午5:38:06
* @version V1.0
*/
@Entity
@Table(name = "sys_role")
@EntityListeners(AuditingEntityListener.class)
@ApiModel(value="系统角色")
public class SysRole implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid") // 这个是hibernate的注解/生成32位UUID
@GeneratedValue(generator = "idGenerator")
/**
* 角色ID
*/
@Column(columnDefinition="varchar(36) not null COMMENT '角色ID' ")
private String id;
/**
* 角色名称
*/
@Column(columnDefinition="varchar(20) not null unique COMMENT '角色名称' default ''")
private String name;
/**
* 角色描述
*/
@Column(columnDefinition="varchar(50) not null COMMENT '角色描述' default ''")
private String comments;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间", name = "moditime", example = "新增,修改,无此字段")
@Temporal(TemporalType.TIMESTAMP)
@Column(columnDefinition = "TIMESTAMP not null default CURRENT_TIMESTAMP COMMENT '更新时间'")
@UpdateTimestamp
private Date moditime;
//省略get set
}
添加用户-角色的关联关系,在用户中添加:
/**
* 用户-角色列表 (多对多)
* @return
*/
@ManyToMany(mappedBy="sysUsers")
private List<SysRole> sysRoles;
在角色中添加:
@ManyToMany(fetch = FetchType.EAGER,cascade=CascadeType.DETACH)
@JoinTable(name = "sys_user_role_r",joinColumns = @JoinColumn(name="user_id",referencedColumnName = "id"),inverseJoinColumns = @JoinColumn(name = "role_id",referencedColumnName = "id"))
List<SysUser> sysUsers;
建立关联关系,在保存角色中关联对应用户:
@Override
public String save(SysRoleVO sysRoleVO) {
SysRole sysRole = new SysRole();
sysRole.setComments(sysRoleVO.getComments());
sysRole.setName(sysRoleVO.getName());
List<String> userIds = sysRoleVO.getUserIds();
if (userIds != null && userIds.size() > 0) {
List<SysUser> users = new ArrayList<>(userIds.size());
for (String userId : userIds) {
SysUser user = new SysUser();
user.setId(userId);
users.add(user);
}
sysRole.setSysUsers(users);
}
iSysRoleRepository.save(sysRole);
return "success";
}
测试:
自定义动态条件拼接
根据用户名查询用户:
/**
* 构造断言
*
* @param userName
* @return
*/
private Specification<SysUser> getWhereClause(String userName) {
return new Specification<SysUser>() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public Predicate toPredicate(Root<SysUser> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Predicate predicate = criteriaBuilder.conjunction();
if (StringUtils.isEmpty(userName)) {
predicate.getExpressions()
.add(criteriaBuilder.like(root.<String>get("userName"), "%" + userName + "%"));
}
return predicate;
}
};
}
注意:CriteriaBuilder 类中可以拼接很多查询条件,道友们可以自行研究,贫道再此就不一一解释了,有问题的可以留言。
自定义动态SQL查询
@PersistenceContext
private EntityManager entityManager;
...
@Override
public List<SysUserVO> listSysUser(String userName) {
StringBuffer sqlBuffer = new StringBuffer();
sqlBuffer.append("select id from sys_user where user_name = ?1");
String sql = sqlBuffer.toString();
Query query = entityManager.createNativeQuery(sql);
query.setParameter(1, userName);
List<String> sysUsers= query.getResultList();
System.out.println(sysUsers);
return null;
}
这个和Hibernate的Query 差不多,有兴趣的道友可以自行学习。