使用 Spring Data JPA 操作大量数据

批量删除区别

delete() 和 deleteInBatch()
deleteAll() 和 deleteAllInBatch()

普通删除方法会根据唯一标识字段,生成多条 SQL 语句,而有 InBatch 的方法只会生成一条 SQL 语句

写入大量数据

@Transactional
public void save100WEntities() {
    for (int i = 0; i < 1000; i++) {
        respsitory.save(1000Entities);

         entityManager.flush();
        entityManager.clear();
    }
}

读取大量数据

需要满足3个条件:

  1. ResultSetType 是 ResultSet.TYPE_FORWARD_ONLY
  2. ResultSetConcurrency 是 ResultSet.CONCUR_READ_ONLY
  3. FetchSize 是 Integer.MIN_VALUE
Statement statement = connection.createStatement(
        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
statement.setFetchSize(Integer.MIN_VALUE);

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
    @QueryHints(value = @QueryHint(name = FETCH_SIZE, value = "" + Integer.MIN_VALUE))
    Stream<User> findByIdIsNotNull();
}

@Transactional
public void run() {
    try (Stream<User> stream = userRepository.findByIdIsNotNull()) {
        stream.forEach(user -> {
            System.out.println(user);
            entityManager.detach(user);
        });
    }
}
2018/2/26 posted in  Spring Boot

Spring-AMQP 的使用记录

Spring-AMQP 特性

  • Listener container 使用 POJO 异步处理消息
  • 提供一个高度抽象的 template(RabbitTemplate)发送和接收消息
  • 使用 RabbitAdmin 来自动声明队列、Exchange 和 Binding

队列、Exchange 和 Binding 的设置

  • Spring way
    使用 spring-boot-starter-amqp 会自动配置 ConnectionFactoryRabbitTemplateAmqpAdmin 三个 Bean。

    @Configuration
    public class RabbitConfiguration {
    @Bean
    public DirectExchange exchange() {
    return new DirectExchange("infrastructure.direct");
    }
    @Bean
    public Queue queue(){
    return new Queue("queueName");
    }
    @Bean
    public Binding binding(){
    return BindingBuilder.bind(queue()).to(exchange()).with("routeKey");
    }
    }
  • Just java

    ConnectionFactory connectionFactory = new CachingConnectionFactory();
    RabbitAdmin amqpAdmin = new RabbitAdmin(connectionFactory);
    Queue queue = new Queue("quueuName");
    DirectExchange exchange = new DirectExchange("exchangeName");
    amqpAdmin.declareQueue(queue);
    amqpAdmin.declareExchange(exchange);
    amqpAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with("routeKey"));
Read more   2016/3/21 posted in  Spring Boot

Spring Boot Integration 测试

  1. 新建一个测试配置类 TestApplication

    @Configuration
    @EnableAutoConfiguration
    @ComponentScan(
    excludeFilters = @ComponentScan.Filter(value = {
    Application.class,
    ApplicationChecker.class
    }, type = FilterType.ASSIGNABLE_TYPE))
    public class TestApplication {
    // 配置测试使用内存数据库
    @Bean
    public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
    }
    }
Read more   2016/2/1 posted in  Spring Boot

Spring-data-redis 的使用记录

开始向导

添加 dependency spring-boot-starter-redis,它默认使用 jedis(还支持 JRedis,SRP 和 Lettuce)
一个简单的 Hash 示例:

@SpringBootApplication
public class RedisDemo implements CommandLineRunner {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public static void main(String[] args) {
        SpringApplication.run(RedisDemo.class).close();
    }

    public void run(String... args) throws Exception {
        BoundHashOperations<String, String, String> ops = stringRedisTemplate.boundHashOps("com.foo");
        ops.put("name", "bar");
        ops.put("sex", "man");
        System.out.println(ops.entries()); // 打印结果:{name=bar, sex=man}
    }
}
Read more   2016/1/9 posted in  Spring Boot

Spring Data JPA 一对一关联

使用注意

User user = new User();
user.setUsername("foo");
Email email = new Email();
email.setUser(user);  // 必须显示设置 user,否则关联字段值会为空
email.setEmail("foo@bar.com");
user.setEmail(email); 
userRepository.save(user);
Read more   2015/11/25 posted in  Spring Boot