spring-boot入门(四)与数据库交互

spring-boot入门(四)与数据库交互

前面几章已经介绍了如何与页面交互,这章将介绍如何与数据库进行交互
1. 配置数据源
这里为了方便使用tomcat数据源,后面会讲解其它数据源的配置。在application.yml里面添加如下代码:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_order?useSSL=false&requireSSL=false
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    tomcat:
      max-wait: 10000
      min-idle: 0
      initial-size: 25
      validation-query: SELECT 1
      test-on-borrow: false
      test-while-idle: true
      time-between-eviction-runs-millis: 18800
      remove-abandoned: true
      remove-abandoned-timeout: 180
2. 配置hibernate
这里介绍hibernate如何使用Java配置,其实配置了数据源可以使用spring boot默认的jdbcTemplate进行交互。由于hibernate对实体的创建来说是非常方便的,难免会用到。
配置hibernate无非涉及到3个地方
  1. sessionFactory,hibernate实现sessionFactory接口的类为LocalSessionFactoryBean
  2. transactionManager,hibernate实现transactionManager接口的类为HibernateTransactionManager
  3. hibernateTemplate
配置类的代码如下:
package com.foo.configura;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;

import java.util.Properties;

/**
 * @author JasonLin
 * @version V1.0
 * @date 2017/12/1
 */
@Configuration
public class Conf {

    @Bean(name = "sessionFactory")
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.put("hibernate.show_sql", true);
        properties.put("hibernate.connection.release_mode", "after_transaction");
        properties.put("hibernate.cache.use_second_level_cache", false);
        properties.put("hibernate.cache.use_query_cache", false);
        sessionFactory.setHibernateProperties(properties);
        sessionFactory.setPackagesToScan("com.foo.model");
        return sessionFactory;
    }

    @Bean("transactionManager")
    HibernateTransactionManager getHibernateTransactionManager(@Qualifier("sessionFactory") SessionFactory sessionFactory){
        return new HibernateTransactionManager(sessionFactory);
    }

    @Bean("hibernateTemplate")
    HibernateTemplate getHibernateTemplate(@Qualifier("sessionFactory") SessionFactory sessionFactory) {
        HibernateTemplate hibernateTemplate = new HibernateTemplate();
        hibernateTemplate.setSessionFactory(sessionFactory);
        return hibernateTemplate;
    }
}
3. 业务代码
a.订单实体和订单项实体:
@Getter
@Setter
@Entity
@Table(name = "_order")
public class Order implements Serializable {

    private static final long serialVersionUID = 1854996605034612378L;

    @Id
    private String id;

    @Column(name = "total_list_price")
    private BigDecimal totalListPrice;

    @Column(name = "total_sale_price")
    private BigDecimal totalSalePrice;

    @Column(name = "purchase_quantity")
    private Integer purchaseQuantity;

    /**
     * 品种数量
     */
    @Column(name = "purchase_kinds")
    private Integer purchaseKinds;

    @Column
    //正常情况下存储的是客户ID
    private String customer;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "order", targetEntity = OrderItem.class)
    private Set itemList;
}
@Getter
@Setter
@Entity
@Table(name = "order_item")
public class OrderItem implements Serializable{
    private static final long serialVersionUID = 8272679709545182358L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "_order")
    private Order order;

    /**
     * 商品ID
     */
    @Column(name = "product_sale")
    private Long productSale;

    /**
     * 购买数量
     */
    @Column(name = "purchase_quantity")
    private Integer purchaseQuantity;

    /**
     * 码洋
     */
    @Column(name = "list_price")
    private BigDecimal listPrice;

    /**
     * 实洋
     */
    @Column(name = "sale_price")
    private BigDecimal salePrice;
}

b.service服务层:
@Service("orderService")
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl implements OrderService {

    private static final Log LOG = LogFactory.getLog(OrderServiceImpl.class);

    @Autowired
    private OrderDao orderDao;

    @Override
    public void create(Order order) {
        checkOrder(order);
        initOrder(order);
        orderDao.save(order);
        LOG.info("create order successed,orderId:" + order.getId());
//        throw new RuntimeException("test exception");
    }

    private void checkOrder(Order order) {
        Preconditions.checkNotNull(order, "order is null.");
        Preconditions.checkArgument(!CollectionUtils.isEmpty(order.getItemList()), "OrderItem is empty.");
    }

    private void initOrder(Order order) {
        BigDecimal totalListPrice = BigDecimal.ZERO;
        BigDecimal totalSalePrice = BigDecimal.ZERO;
        Integer purchaseQuantity = 0;
        Integer purchaseKind = order.getItemList().size();
        for (OrderItem orderItem : order.getItemList()) {
            totalListPrice = totalListPrice.add(orderItem.getListPrice());
            totalSalePrice = totalSalePrice.add(orderItem.getSalePrice());
            purchaseQuantity += orderItem.getPurchaseQuantity();
        }
        order.setTotalListPrice(totalListPrice);
        order.setTotalSalePrice(totalSalePrice);
        order.setPurchaseKinds(purchaseKind);
        order.setPurchaseQuantity(purchaseQuantity);
    }
}
c. dao层:
@Repository("orderDao")
public class OrderDaoImpl implements OrderDao{

    @Autowired
    private HibernateTemplate hibernateTemplate;

    @Override
    public void save(Order order) {
        hibernateTemplate.save(order);
    }
}
4. 测试
在编写测试类的时候会用到两个注解:@RunWith,@SpringBootTest 。spring boot会自动加载启动类进行测试。
测试类代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestOrderService {

    @Autowired
    private OrderService orderService;

    @Test
    public void testCreate(){
        Order order  = new Order();
        Set orderItems = Sets.newHashSet();

        OrderItem orderItem1 = new OrderItem();
        orderItem1.setListPrice(new BigDecimal("11.02"));
        orderItem1.setSalePrice(new BigDecimal("9.99"));
        orderItem1.setOrder(order);
        orderItem1.setProductSale(1222021L);
        orderItem1.setPurchaseQuantity(1);

        OrderItem orderItem2 = new OrderItem();
        orderItem2.setListPrice(new BigDecimal("8.5"));
        orderItem2.setSalePrice(new BigDecimal("8.0"));
        orderItem2.setOrder(order);
        orderItem2.setProductSale(1222056L);
        orderItem2.setPurchaseQuantity(2);

        orderItems.add(orderItem1);
        orderItems.add(orderItem2);

        order.setId(String.valueOf(IdUtils.next()));
        order.setCustomer("jasonLin");
        order.setItemList(orderItems);
        orderService.create(order);
    }

}
运行测试方法,查看数据库:


数据已经成功插入。在service层里面有行注释了的代码,用于测试hibernate事物是否正确配置,必须配置HibernateTransactionManager否则使用使用hibernateTemplate事物将不会生效。
最后放上pom.xml文件的依赖:
    
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            mysql
            mysql-connector-java
        
    
ps:
1、使用jpa包自动添加hibernate依赖
2、使用hibernateTemplate需要设置sessionFactory
3、springboot会自动注入DataSource,但是在配置文件中必须以sprping.datasource.*开头的配置项,
4、默认使用Tomcat连接池
5、springboot自动注入JdbcTemplate

本文的其它详细代码在:https://github.com/Json-Lin/spring-boot-practice/tree/master/spring-boot-paractice-data-jpa

end






你可能感兴趣的:(spring-boot)