Spring使用XML+註解實現的小案例
項目結構
數據庫
配置文件
-
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xiaoge</groupId> <artifactId>account_xmlioc</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
-
bean.xml重點
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 告知spring在創建容器時要掃描的包, 配置所需要的標籤不是在bean的約束中, 而是一個名稱爲context名稱空間和約束中 --> <!-- base-package: 指定了包, 它就會掃描這個包下及其子包, 所有類上和接口上的註解 --> <context:component-scan base-package="com.xiaoge"></context:component-scan> <!-- 配置QueryRunner對象 配置成多例, 單例對象會有線程安全問題 --> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <!-- 帶參構造注入數據源 --> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <!-- 配置數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 注入鏈接數據庫的必備信息 --> <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> </beans>
實體類
-
Account
package com.xiaoge.domain; import java.io.Serializable; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:16 * @Description: 賬戶實體類 */ public class Account implements Serializable { private Integer id; private String name; private Float money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Float getMoney() { return money; } public void setMoney(Float money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } }
持久層
-
AccountDao接口
package com.xiaoge.dao; import com.xiaoge.domain.Account; import java.util.List; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:25 * @Description: 賬戶的持久層接口 */ public interface AccountDao { /** * 查詢所有 * @return */ public List<Account> findAllAccount(); /** * 查詢一個 * @return */ public Account findAccountById(Integer id); /** * 保存 */ public void saveAccount(Account account); /** * 更新 * @param account */ public void updateAccount(Account account); /** * 刪除 * @param id */ public void deleteAccount(Integer id); }
-
AccountDaoImpl實體類
package com.xiaoge.dao.impl; import com.xiaoge.dao.AccountDao; import com.xiaoge.domain.Account; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.sql.SQLException; import java.util.List; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:25 * @Description: 賬戶的持久層實現類 */ @Repository("accountDao") public class AccountDaoImpl implements AccountDao { @Autowired private QueryRunner runner; public List<Account> findAllAccount() { try { return runner.query("select * from account", new BeanListHandler<Account>(Account.class)); } catch (SQLException e) { throw new RuntimeException(e); } } public Account findAccountById(Integer id) { try { return runner.query("select * from account where id = ? ", new BeanHandler<Account>(Account.class), id); } catch (SQLException e) { throw new RuntimeException(e); } } public void saveAccount(Account account) { try { runner.update("insert into account(name, money) values(?, ?)", account.getName(), account.getMoney()); } catch (SQLException e) { throw new RuntimeException(e); } } public void updateAccount(Account account) { try { runner.update("update account set name = ?, money = ? where id = ?", account.getName(), account.getMoney(), account.getId()); } catch (SQLException e) { throw new RuntimeException(e); } } public void deleteAccount(Integer id) { try { runner.update("delete from account where id = ?", id); } catch (SQLException e) { throw new RuntimeException(e); } } }
業務層
-
AccountService接口
package com.xiaoge.service; import com.xiaoge.domain.Account; import java.util.List; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:14 * @Description: 賬戶的業務層接口 */ public interface AccountService { /** * 查詢所有 * @return */ public List<Account> findAllAccount(); /** * 查詢一個 * @return */ public Account findAccountById(Integer id); /** * 保存 */ public void saveAccount(Account account); /** * 更新 * @param account */ public void updateAccount(Account account); /** * 刪除 * @param id */ public void deleteAccount(Integer id); }
-
AccountServiceImpl實現類
package com.xiaoge.service.impl; import com.xiaoge.dao.AccountDao; import com.xiaoge.domain.Account; import com.xiaoge.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:14 * @Description: 賬戶的業務層實現類 */ @Service("accountService") public class AccountServiceImpl implements AccountService { @Autowired // 它會自動取核心容器(map集合 找值, 鍵都不會匹配的)中找AccountDao類型匹配的唯一個bean, 那就是我們用註解修飾了的@Repository AccountDaoImpl類 private AccountDao accountDao; public List<Account> findAllAccount() { return accountDao.findAllAccount(); } public Account findAccountById(Integer id) { return accountDao.findAccountById(id); } public void saveAccount(Account account) { accountDao.saveAccount(account); } public void updateAccount(Account account) { accountDao.updateAccount(account); } public void deleteAccount(Integer id) { accountDao.deleteAccount(id); } }
測試
-
AccountServiceTest
package com.xiaoge.test; import com.xiaoge.domain.Account; import com.xiaoge.service.AccountService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; /** * @Author: 瀟哥 * @DateTime: 2020/4/7 下午10:52 * @Description: 使用Junit單元測試, 測試我們的配置 * Spring整合junit的配置 * 1. 導入spring整合junit的jar(座標) * 2. 使用junit提供的一個註解把原有的main方法替換了, 替換成spring提供的 * @Runwith * 3. 告知spring的運行器, spring和ioc的創建基於xml還是註解的, 並且說明位置 * @ContextConfiguration * locations: 指定xml文件的位置, 加上classpath關鍵字, 表示在類路徑下 * classes: 指定註解類所在的位置 * * 當我們使用spring 5.x版本的時候, 要求junit的jar必須是4.12及以上版本 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:bean.xml") public class AccountServiceTest { @Autowired private AccountService accountService; @Test public void findAllTest() { // 1. 執行方法 List<Account> allAccount = accountService.findAllAccount(); for (Account account : allAccount) { System.out.println(account); } } @Test public void findOneTest() { // 1. 執行方法 Account account = accountService.findAccountById(1); System.out.println(account); } @Test public void saveAccountTest() { // 1. 構造對象 Account account = new Account(); account.setId(4); account.setName("ddd"); account.setMoney(2000f); // 2. 執行方法 accountService.saveAccount(account); } @Test public void updateAccountTest() { // 1. 構造對象 Account account = new Account(); account.setId(3); account.setName("ddd"); account.setMoney(2000f); // 2. 執行方法 accountService.updateAccount(account); } @Test public void deleteAccountTest() { // 1. 執行方法 accountService.deleteAccount(3); } }