作者归档:Rick

sharp-database中的BaseDAOImpl实现一对一外键关联@OneToMany @ManyToOne

实体

http://xhope.top/wp-content/uploads/2022/05/image.png

IdCard.java

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Table("t_person_id_card")
public class IdCard extends BasePureEntity {

    private String idNum;

    private String address;

    /**
     * 一对一
     * oneToOne = true
     */
    @OneToMany(subTable = "t_person", joinValue = "id_card_id", cascadeSaveOrUpdate = true, oneToOne = true, reversePropertyName = "idCard")
    private Person person;
}

Person.java

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Table("t_person")
public class Person extends BasePureEntity {

    private String name;

    @ManyToOne(parentTable = "t_person_id_card", value = "id_card_id", cascadeSaveOrUpdate = true)
    private IdCard idCard;

}

运行 TableGenerator 生成SQL,参考sharp-database中的TableGenerator根据实体对象生成表

生成的SQL

create table t_person_id_card
(
    id bigint not null comment '主键'
        primary key,
    id_num varchar(32) null,
    address varchar(32) null,
    created_by bigint null,
    created_at datetime null,
    updated_by bigint null,
    updated_at datetime null,
    is_deleted bit null
);

create table t_person
(
    id bigint not null comment '主键'
        primary key,
    name varchar(32) null,
    id_card_id bigint null,
    created_by bigint null,
    created_at datetime null,
    updated_by bigint null,
    updated_at datetime null,
    is_deleted bit null
);

生成DAO

IdCardDAO

@Repository
public class IdCardDAO extends BaseDAOImpl<IdCard> {

}

PersonDAO

@Repository
public class PersonDAO extends BaseDAOImpl<Person> {

}

测试

@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class PersonTest {

    @Autowired
    private PersonDAO personDAO;

    @Autowired
    private IdCardDAO idCardDAO;

    @Test
    @Order(0)
    public void savePerson() {
        Person person = Person.builder()
                .name("Rick")
                .idCard(IdCard.builder().idNum("32128787988762").address("江苏").build())
                .build();
        personDAO.insert(person);
    }

    @Test
    @Order(0)
    public void saveCardId() {
        Person person = Person.builder()
                .name("Rick")
                .build();

        IdCard idCard = IdCard.builder().idNum("32128787988762").address("陕西")
                .person(person)
                .build();

        idCardDAO.insert(idCard);
    }

    @Order(1)
    @Test
    public void findPersonById() {
        Person person = personDAO.selectById(552098712424472576L).get();
        assertThat(person.getName()).isEqualTo("Rick");
        assertThat(person.getIdCard().getIdNum()).isEqualTo("32128787988762");
    }

    @Order(2)
    @Test
    public void findIdCardById() {
        final IdCard idCard = idCardDAO.selectById(552098712365752320L).get();
        assertThat(idCard.getPerson().getName()).isEqualTo("Rick");
        assertThat(idCard.getIdNum()).isEqualTo("32128787988762");
    }
}

sharp-database中继承BaseServiceImpl

@Service
@Validated
public class ProjectService extends BaseServiceImpl<ProjectDAO, Project> {

    public ProjectService(ProjectDAO projectDAO) {
        super(projectDAO);
    }
}

方法介绍

保存或更新

public E saveOrUpdate(E e)

保存

public E save(E e)

更新

public E update(E e)

根据id删除

public int deleteById(Long id)

根据id查询

public Optional<E> findById(Long id)

查询所有数据

public List<E> findAll()

sharp-common如果优雅地异常处理

定义异常枚举类,实现接口Assert

@Getter
@ToString
public enum ExceptionCodeEnum implements Assert {
DIMENSION_CODE_DUPLICATE(50100, "维度code、单位code不能重复,全局唯一"),
UNIT_CODE_DUPLICATE(50101, "单位code不能重复"),
LESS_BASE_UNIT_ERROR(50102, "缺少一个基准单位%s"),
MAX_TRY_LOGIN_ERROR(50103, "MAX_TRY_LOGIN_ERROR"), // messages.properties: MAX_TRY_LOGIN_ERROR=该账号{0}次登录失败后,被锁定{1}分钟

private int code;
private String msg;

ExceptionCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
}

使用异常

  • 数据库中不存在某个对象,抛出异常“库房不存在“
Assert.notExists("库房");
  • 参数不能为空,抛出异常“库房id不能为空“
Assert.notNull(id, "库房id");
  • 业务异常
ExceptionCodeEnum.DIMENSION_CODE_DUPLICATE.exception();
  • 参数格式化错误信息
throw new BizException(ExceptionCodeEnum.LESS_BASE_UNIT_ERROR.result(), new Object[] {"米"});

异常信息为“缺少一个基准单位米”

  • 参数国际化错误信息
throw new BizException(ExceptionCodeEnum.MAX_TRY_LOGIN_ERROR.result(), new Object[] {"0001", "10"});

异常信息为“该账号001次登录失败后,被锁定10分钟”

sharp-database中的BaseDAOImpl实现多表级联@ManyToMany(三)

级联查询,在中间表中建立关系。不会级联更新!!!

创建实体对象

Usre.java

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Table("t_user")
public class User extends BasePureEntity {

    private String name;

    @ManyToMany(thirdPartyTable = "t_user_role", referenceColumnName = "role_id", columnDefinition = "user_id", referenceTable = "t_role")
    private List<Role> roleList;

}

Role.java

/**
 * @author Rick
 * @createdAt 2022-03-03 19:26:00
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Table("t_role")
public class Role extends BasePureEntity {

    private String name;

}

生成3张表 t_user t_role t_user_role。中间表t_user_role 只有三个字段 user_id role_id is_deleted 级联删除的时候需要该字段。

添加测试

    @Test
    public void testInsert() {
        User user = User.builder()
                .name("Rick")
                .roleList(Arrays.asList(Role.builder().id(530861443353075712L).build()))
                .build();

        int count = personDAO.insert(user);
        assertThat(count).isEqualTo(1);

        Optional<User> personOptional = personDAO.selectById(user.getId());
        User person2 = personOptional.get();
        assertThat(person2.getRoleList().get(0).getName()).isEqualTo("admin");
    }

    @Test
    public void testUpdate() {
        User user = User.builder()
                .id(530865367078330368L)
                .name("Tom")
                .roleList(Arrays.asList(Role.builder().id(530861443353075712L).build()
//                        , Role.builder().id(530861443353075713L).build()
                        , Role.builder().id(530861443353075714L).build())
                )
                .build();

        personDAO.update(user);
    }

    @Test
    public void testSelect() {
        Optional<User> personOptional = personDAO.selectById(530864959987572736L);
        User user = personOptional.get();
        assertThat(user.getRoleList().get(0).getName()).isEqualTo("admin");
    }

    @Test
    public void testDelete() {
        personDAO.deleteById(530865367078330368L);
    }

sharp-database中的TableGenerator根据实体对象生成表

1. 创建实体对象

Task.java

@SuperBuilder
@Getter
@Setter
@Table(value = "t_task", comment = "任务表")
@NoArgsConstructor
public class Task extends BasePureEntity {

    @Column(nullable = true, comment = "任务名称")
    private String taskName;

    @Column(comment = "完成时间")
    private LocalDateTime completeTime;

    private Integer costHours;

    private Boolean complete;

    private Long assignUserId;

    @Column(comment = "用户状态")
    private UserStatusEnum userStatus;

}

2. 执行代码

@SpringBootTest
public class TableGeneratorTest {

    @Autowired
    private TableGenerator tableGenerator;

    @Test
    public void createTable() {
        tableGenerator.createTable(Task.class);
    }

}

生成sql,并执行

create table t_task
(
    id bigint not null comment '主键'
        primary key,
    task_name varchar(32) not null comment '任务名称',
    complete_time datetime null comment '完成时间',
    cost_hours int null,
    complete bit null,
    assign_user_id bigint null,
    user_status varchar(16) null comment '用户状态',
    created_by bigint null,
    created_at datetime null,
    updated_by bigint null,
    updated_at datetime null,
    is_deleted bit null
)
comment '任务表';