--- tags: Spring MVC --- # 存取資料庫資料 Spring鼓勵藉由介面而不透過類別寫程式,讓程式更加彈性。 因此準備Service介面、Service、DAO介面、DAO以及Controller進行控制(前提,必須準備好bean,如Bookbeab、CompanyBean、MemberBean) ## Service介面(把所有要做的方法列出來): ``` public interface ProductService { List<BookBean> getAllProduct(); void updateAllStocks(); List<String> getAllCategories(); List<BookBean> getProductByCategory(String category); public BookBean getProductById(int productId); void addProduct(BookBean product); CompanyBean getCompanyById(int companyId); List<CompanyBean> getCompanyList(); } ``` ## Service.java 1. 註釋@Service 2. 要宣告session工廠,並透過@Autowired建構子注入 3. 每個方法都是一個交易,因此要註釋@Transactional,代表方法執行時,會自動開交易,結束會自動關交易,有錯誤會自動rollback ``` @Service public class ProductServiceImpl implements ProductService { SessionFactory factory; ProductDao productDao;//這是ProductDao 介面,不是類別(也就是對介面操作,不要對類別操作) @Autowired public ProductServiceImpl(SessionFactory factory, ProductDao productDao) { this.factory = factory; this.productDao = productDao; } /* @Transactional @Override public List<BookBean> getAllProduct() { Session session = factory.getCurrentSession(); Transaction tx=null; List<BookBean> list=null; try { tx=session.beginTransaction(); list = productDao.getAllProduct(); tx.commit(); } catch (Exception e) { if(tx!=null) { tx.rollback(); } throw new RuntimeException(e); } return list; } */ //select All Product @Transactional @Override public List<BookBean> getAllProduct() { List<BookBean> list=productDao.getAllProduct(); return list; } //update By Id @Transactional @Override public void updateAllStocks() { List<BookBean> allProducts = productDao.getAllProduct(); for(BookBean bb : allProducts) { if (bb.getStock() != null && bb.getStock() < 50) { productDao.updateStock(bb.getBookId(), bb.getStock() + 50); } } } //select All Categories @Transactional @Override public List<String> getAllCategories() { // TODO Auto-generated method stub return productDao.getAllCategories(); } //select by Category @Transactional @Override public List<BookBean> getProductByCategory(String category) { // TODO Auto-generated method stub return productDao.getProductByCategory(category); } //select Product By Id @Transactional @Override public BookBean getProductById(int productId) { return productDao.getProductById(productId); } //Insert Product @Transactional @Override public void addProduct(BookBean product) { // TODO Auto-generated method stub productDao.addProduct(product); } //select company by id @Transactional @Override public CompanyBean getCompanyById(int companyId) { // TODO Auto-generated method stub return productDao.getCompanyById(companyId); } // select All company @Transactional @Override public List<CompanyBean> getCompanyList() { // TODO Auto-generated method stub return productDao.getCompanyList(); } } ``` ## DAO介面(把所有要做的方法列出來): ``` public interface ProductDao { //介面把所有要做的方法列出來 List<BookBean> getAllProduct(); void updateStock(int productId,int newQuantity); List<String> getAllCategories(); List<BookBean> getProductByCategory(String category); public BookBean getProductById(int productId); void addProduct(BookBean product); CompanyBean getCompanyById(int companyId); List<CompanyBean> getCompanyList(); } ``` ## DAO: 1. 註釋@Repository 2. 要宣告session工廠,並透過@Autowired建構子注入 ``` @Repository public class ProductDaoImpl implements ProductDao { SessionFactory factory; // RootAppConfig.java已經註冊了,所以直接透過下面的建構子@Autowired @Autowired public ProductDaoImpl(SessionFactory factory) { this.factory = factory; } //select All @Override public List<BookBean> getAllProduct() { Session session = factory.getCurrentSession(); String hql = "FROM BookBean"; List<BookBean> resultList = session.createQuery(hql, BookBean.class).getResultList(); return resultList; } //update By Id @Override public void updateStock(int productId, int newQuantity) { Session session = factory.getCurrentSession(); String hql = "UPDATE BookBean bb SET bb.stock= :qty WHERE bb.bookId = :id"; session.createQuery(hql).setParameter("qty", newQuantity).setParameter("id", productId).executeUpdate(); } //select All Categories @Override public List<String> getAllCategories() { Session session = factory.getCurrentSession(); String hql = "SELECT DISTINCT bb.category FROM BookBean bb"; return session.createQuery(hql, String.class).getResultList(); } //select by Category @Override public List<BookBean> getProductByCategory(String category) { Session session = factory.getCurrentSession(); String hql = "FROM BookBean bb WHERE bb.category = :cate"; return session.createQuery(hql, BookBean.class).setParameter("cate", category).getResultList(); } //select Product By Id @Override public BookBean getProductById(int productId) { Session session = factory.getCurrentSession(); BookBean bb = session.get(BookBean.class, productId); if (bb == null) { throw new ProductNotFoundException("產品編號:" + productId + "找不到", productId); } return bb; } //Insert Product @Override public void addProduct(BookBean product) { Session session = factory.getCurrentSession(); CompanyBean cb = getCompanyById(product.getCompanyId()); product.setCompanyBean(cb); session.save(product); } //select company by id @Override public CompanyBean getCompanyById(int companyId) { Session session = factory.getCurrentSession(); CompanyBean cb = session.get(CompanyBean.class, companyId); return cb; } // select All company @Override public List<CompanyBean> getCompanyList() { Session session = factory.getCurrentSession(); String hql = "FROM CompanyBean"; List<CompanyBean> list = session.createQuery(hql, CompanyBean.class).getResultList(); return list; } } ``` ## Controller 1. 註釋@Controller 2. 要宣告session工廠,並透過@Autowired建構子注入 ``` @Controller public class ProductController { ProductService productService; ServletContext servletContext;//後面抓圖片要用的 @Autowired public ProductController(ProductService productService, ServletContext servletContext) { this.productService = productService; this.servletContext = servletContext; } @GetMapping("/products") public String list(Model model) { List<BookBean> beans = productService.getAllProduct(); model.addAttribute("products",beans); return "products"; } //後面可以有更多請求 } ``` 架構 DAO處理資料庫相關功能 Service除了資料庫相關方法(所以import DAO介面操作),還有商業邏輯的方法。 Control透過Service進行方法執行 ![](https://i.imgur.com/Qx98KEG.png)