# spring-boot-demo-orm-jpa
> 此 demo 主要演示了 Spring Boot 如何使用 JPA 操作数据库,包含简单使用以及级联使用。
## 主要代码
### pom.xml
```xml
* JPA配置类 *
* * @package: com.xkcoding.orm.jpa.config * @description: JPA配置类 * @author: yangkai.shen * @date: Created in 2018/11/7 11:05 * @copyright: Copyright (c) 2018 * @version: V1.0 * @modified: yangkai.shen */ @Configuration @EnableTransactionManagement @EnableJpaAuditing @EnableJpaRepositories(basePackages = "com.xkcoding.orm.jpa.repository", transactionManagerRef = "jpaTransactionManager") public class JpaConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return DataSourceBuilder.create().build(); } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter japVendor = new HibernateJpaVendorAdapter(); japVendor.setGenerateDdl(false); LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setDataSource(dataSource()); entityManagerFactory.setJpaVendorAdapter(japVendor); entityManagerFactory.setPackagesToScan("com.xkcoding.orm.jpa.entity"); return entityManagerFactory; } @Bean public PlatformTransactionManager jpaTransactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory); return transactionManager; } } ``` ### User.java ```java /** ** 用户实体类 *
* * @package: com.xkcoding.orm.jpa.entity * @description: 用户实体类 * @author: yangkai.shen * @date: Created in 2018/11/7 14:06 * @copyright: Copyright (c) * @version: V1.0 * @modified: 76peter */ @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor @Data @Builder @Entity @Table(name = "orm_user") @ToString(callSuper = true) public class User extends AbstractAuditModel { /** * 用户名 */ private String name; /** * 加密后的密码 */ private String password; /** * 加密使用的盐 */ private String salt; /** * 邮箱 */ private String email; /** * 手机号码 */ @Column(name = "phone_number") private String phoneNumber; /** * 状态,-1:逻辑删除,0:禁用,1:启用 */ private Integer status; /** * 上次登录时间 */ @Column(name = "last_login_time") private Date lastLoginTime; /** * 关联部门表 * 1、关系维护端,负责多对多关系的绑定和解除 * 2、@JoinTable注解的name属性指定关联表的名字,joinColumns指定外键的名字,关联到关系维护端(User) * 3、inverseJoinColumns指定外键的名字,要关联的关系被维护端(Department) * 4、其实可以不使用@JoinTable注解,默认生成的关联表名称为主表表名+下划线+从表表名, * 即表名为user_department * 关联到主表的外键名:主表名+下划线+主表中的主键列名,即user_id,这里使用referencedColumnName指定 * 关联到从表的外键名:主表中用于关联的属性名+下划线+从表的主键列名,department_id * 主表就是关系维护端对应的表,从表就是关系被维护端对应的表 */ @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinTable(name = "orm_user_dept", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "dept_id", referencedColumnName = "id")) private Collection* 部门实体类 *
* * @package: com.xkcoding.orm.jpa.entity * @description: 部门实体类 * @author: 76peter * @date: Created in 2019/10/1 18:07 * @copyright: Copyright (c) 2019 * @version: V1.0 * @modified: 76peter */ @EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor @Builder @Entity @Table(name = "orm_department") @ToString(callSuper = true) public class Department extends AbstractAuditModel { /** * 部门名 */ @Column(name = "name", columnDefinition = "varchar(255) not null") private String name; /** * 上级部门id */ @ManyToOne(cascade = {CascadeType.REFRESH}, optional = true) @JoinColumn(name = "superior", referencedColumnName = "id") private Department superior; /** * 所属层级 */ @Column(name = "levels", columnDefinition = "int not null default 0") private Integer levels; /** * 排序 */ @Column(name = "order_no", columnDefinition = "int not null default 0") private Integer orderNo; /** * 子部门集合 */ @OneToMany(cascade = {CascadeType.REFRESH, CascadeType.REMOVE}, fetch = FetchType.EAGER, mappedBy = "superior") private Collection* 实体通用父类 *
* * @package: com.xkcoding.orm.jpa.entity.base * @description: 实体通用父类 * @author: yangkai.shen * @date: Created in 2018/11/7 14:01 * @copyright: Copyright (c) 2018 * @version: V1.0 * @modified: yangkai.shen */ @MappedSuperclass @EntityListeners(AuditingEntityListener.class) @Data public abstract class AbstractAuditModel implements Serializable { /** * 主键 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** * 创建时间 */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "create_time", nullable = false, updatable = false) @CreatedDate private Date createTime; /** * 上次更新时间 */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "last_update_time", nullable = false) @LastModifiedDate private Date lastUpdateTime; } ``` ### UserDao.java ```java /** ** User Dao *
* * @package: com.xkcoding.orm.jpa.repository * @description: User Dao * @author: yangkai.shen * @date: Created in 2018/11/7 14:07 * @copyright: Copyright (c) 2018 * @version: V1.0 * @modified: yangkai.shen */ @Repository public interface UserDao extends JpaRepository* User Dao *
* * @package: com.xkcoding.orm.jpa.repository * @description: Department Dao * @author: 76peter * @date: Created in 2019/10/1 18:07 * @copyright: Copyright (c) 2019 * @version: V1.0 * @modified: 76peter */ @Repository public interface DepartmentDao extends JpaRepository* jpa 测试类 *
* * @package: com.xkcoding.orm.jpa.repository * @description: jpa 测试类 * @author: yangkai.shen * @date: Created in 2018/11/7 14:09 * @copyright: Copyright (c) 2018 * @version: V1.0 * @modified: yangkai.shen */ @Slf4j public class UserDaoTest extends SpringBootDemoOrmJpaApplicationTests { @Autowired private UserDao userDao; /** * 测试保存 */ @Test public void testSave() { String salt = IdUtil.fastSimpleUUID(); User testSave3 = User.builder().name("testSave3").password(SecureUtil.md5("123456" + salt)).salt(salt).email("testSave3@xkcoding.com").phoneNumber("17300000003").status(1).lastLoginTime(new DateTime()).build(); userDao.save(testSave3); Assert.assertNotNull(testSave3.getId()); Optional* jpa 测试类 *
* * @package: com.xkcoding.orm.jpa.repository * @description: jpa 测试类 * @author: 76peter * @date: Created in 2018/11/7 14:09 * @copyright: Copyright (c) 2018 * @version: V1.0 * @modified: 76peter */ @Slf4j public class DepartmentDaoTest extends SpringBootDemoOrmJpaApplicationTests { @Autowired private DepartmentDao departmentDao; @Autowired private UserDao userDao; /** * 测试保存 ,根节点 */ @Test @Transactional public void testSave() { Collection