从CustomerController入手,其getCustomers方法调用了CustoemrService.findCustomersByTenantId方法
- CustomerService是由于CustoemrController继承了BaseController。BaseController注入了一个CustoemrService(接口)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public PageData<Customer> getCustomers(@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(customerService.findCustomersByTenantId(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
- 根据SpringBoot自动注入,需要在IOC容器中找到一个CustomerService的实现类。这个类是dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java 。然后这个类又注入了一个CustomerDao(接口),使用了customerDao.findCustomersByTenantId方法。
@Override
public PageData<Customer> findCustomersByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findCustomersByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink);
Validator.validateId(tenantId, "Incorrect tenantId " + tenantId);
Validator.validatePageLink(pageLink);
return customerDao.findCustomersByTenantId(tenantId.getId(), pageLink);
}
- 然后需要找到CustomerDao的实现类JpaCustomerDao.java。可以看到它又注入了一个CustomerRepository,调用了customerRepository.findByTenantId方法。
public class JpaCustomerDao extends JpaAbstractSearchTextDao<CustomerEntity, Customer> implements CustomerDao {
@Autowired
private CustomerRepository customerRepository;
@Override
public PageData<Customer> findCustomersByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(customerRepository.findByTenantId(
tenantId,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink)));
}
}
- 然后又发现CustomerRepository接口又继承了PagingAndSortingRepository<CustomerEntity, UUID>接口
import org.springframework.data.repository.PagingAndSortingRepository;
public interface CustomerRepository extends PagingAndSortingRepository<CustomerEntity, UUID> {
@Query("SELECT c FROM CustomerEntity c WHERE c.tenantId = :tenantId " +
"AND LOWER(c.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<CustomerEntity> findByTenantId(@Param("tenantId") UUID tenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
CustomerEntity findByTenantIdAndTitle(UUID tenantId, String title);
Long countByTenantId(UUID tenantId);
}
- 重点来了: PagingAndSortingRepository接口是JPA框架提供的一个接口,位于
org.springframework.data.repository.PagingAndSortingRepository
,继承了这个接口的接口,可以根据方法名自动生成sql语句从而进行查询。比如,User findUserById(int id)方法就会自动生成sql:SELECT * from User where id=#{id},并根据User的构造方法返回一个User对象 - 数据源配置:application/src/main/resources/thingsboard.yml 配置文件中441~457行
# SQL DAO Configuration
spring:
data:
jpa:
repositories:
enabled: "true"
jpa:
open-in-view: "false"
hibernate:
ddl-auto: "none"
database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}"
datasource:
driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}"
url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}"
username: "${SPRING_DATASOURCE_USERNAME:postgres}"
password: "${SPRING_DATASOURCE_PASSWORD:postgres}"
hikari:
maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:16}"