Spring=Spring詳解IOC

一.DbUtils

(1)DbUtils是什麼?

DbUtils是Apache的一款用於簡化Dao層代碼的工具類,它底層封裝了JDBC技術。

核心對象:

QueryRunner queryRunner = new QueryRunner(DataSource dataSource);

核心方法:

int update(); 執行增、刪、改語句

T query(); 執行查詢語句
	ResultSetHandler<T> 這是一個接口,主要作用是將數據庫返回的記錄封裝到實體對象

舉個例子:

查詢數據庫所有賬戶信息到Account實體中

public class DbUtilsTest {

    @Test
    public void findAllTest() throws Exception {
        // 創建DBUtils工具類,傳入連接池
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        // 編寫sql
        String sql = "select * from account";
        // 執行sql
        List<Account> list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
        // 打印結果
        for (Account account : list) {
            System.out.println(account);
        }
    }
}

(2)DbUtils快速入門:

1)準備數據庫環境:

2)創建maven的java模塊: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.wsl</groupId>
    <artifactId>springday02-dbutils</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3)導入相關jar包

<!--依賴管理-->
<dependencies>
    <!--mysql驅動-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--druid連接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.15</version>
    </dependency>
    <!--dbUtils工具包-->
    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
        <version>1.6</version>
    </dependency>
    <!--junit單元測試-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!--spring核心-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
</dependencies>

工具類導入:

實體類:

public class Account {
    private Integer id;
    private  String name;
    private Double money;
    public Account() {
    }
    public Account(Integer id, String name, Double money) {
        this.id = id;
        this.name = name;
        this.money = 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 Double getMoney() {
        return money;
    }
    public void setMoney(Double money) {
        this.money = money;
    }

api介紹:

測試:

public class DbUtilsTest {
    @Test
    public void test01() throws  Exception{
        //新增記錄
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "insert into account(name,money) values(?,?)";
        queryRunner.update(sql,"張明明",30);
    }
    @Test
    public void test02() throws  Exception{
        //查詢一條記錄
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select * from account where id=?";
        Account account = queryRunner.query(sql, new BeanHandler<>(Account.class), 3);
        System.out.println(account);
    }
    @Test
    public void test03() throws  Exception{
        //查詢多條記錄
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select * from account";
        List<Account> accountList = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));
        System.out.println(accountList);
    }
}

 

(2)Spring的xml整合DbUtils

基於spring的xml配置實現賬戶的CRUD

AccountDao代碼:

public interface AccountDao {

    void save(Account account);

    void update(Account account);

    void delete(Integer id);

    List<Account> findAll();

    Account findById(Integer id);
}
public class AccountDaoImpl implements AccountDao {

    // 聲明 QueryRunner 對象
    private QueryRunner queryRunner;

    public void setQueryRunner(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }

    @Override
    public void save(Account account) {
        try {
            // 1.編寫sql
            String sql = "insert into account(name,money)values(?,?)";
            // 2.執行sql
            queryRunner.update(sql, account.getName(), account.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(Account account) {
        try {
            // 1.編寫sql
            String sql = "update account set name = ? , money = ? where id = ?";
            // 2.執行sql
            queryRunner.update(sql, account.getName(), account.getMoney(), account.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void delete(Integer id) {
        try {
            // 1.編寫sql
            String sql = "delete from account  where id = ?";
            // 2.執行sql
            queryRunner.update(sql, id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Account> findAll() {
        List<Account> list = null;
        try {
            // 1.編寫sql
            String sql = "select * from account";
            // 2.執行sql
            list = queryRunner.query(sql, new BeanListHandler<>(Account.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public Account findById(Integer id) {
        Account account = null;
        try {
            // 1.編寫sql
            String sql = "SELECT * FROM account WHERE id = ?";
            // 2.執行sql
            account = queryRunner.query(sql, new BeanHandler<>(Account.class), id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return account;
    }
}

AccountService

public interface AccountService {

    void save(Account account);

    void update(Account account);

    void delete(Integer id);

    List<Account> findAll();

    Account findById(Integer id);
}
public class AccountServiceImpl implements AccountService {

    // 聲明
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void delete(Integer id) {
        accountDao.delete(id);
    }

    @Override
    public List<Account> findAll() {
        return accountDao.findAll();
    }

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }
}

Spring的核心配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--druid連接交給ioc容器-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    
    <!--queryRunner交給ioc容器-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <!--accountDao交給ioc容器-->
    <bean id="accountDao" class="cn.wsl.dao.impl.AccountDaoImpl">
        <property name="queryRunner" ref="queryRunner"></property>
    </bean>

    <!--accountService交給ioc容器-->
    <bean id="accountService" class="cn.wsl.serivce.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
</beans>

代碼測試:

public class AccountTest {
    //新增
    @Test
    public  void test01() throws  Exception{
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService  accountService  = app.getBean(AccountService.class);
       accountService.save(new Account(4,"張三",2000.0));
    }
    //修改
    @Test
    public  void test02() throws  Exception{
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService  accountService  = app.getBean(AccountService.class);
        accountService.update(new Account(4,"張三",2050.0));
    }
//刪除
    @Test
    public  void test03() throws  Exception{
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService  accountService  = app.getBean(AccountService.class);
        accountService.delete(4);
    }
//查詢所有
    @Test
    public  void test04() throws  Exception{
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService  accountService  = app.getBean(AccountService.class);
        List<Account> all = accountService.findAll();
        System.out.println(all);
    }
//查詢一個
    @Test
    public  void test05() throws  Exception{
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService  accountService  = app.getBean(AccountService.class);
        Account account = accountService.findById(3);
        System.out.println(account);
    }
}

配置文件抽取:

引入context命名空間(約束)

修改配置文件標籤:

 

二.Spring註解開發:

Spring是輕代碼而重配置的框架,配置比較繁重,影響開發效率,所以註解開發是一種趨勢,註解代替xml配置文件可以簡化配置,提高開發效率。

(1)Spring常用註解:

Spring常用註解主要是替代<bean>的配置

IOC控制反轉:

- @Component:相當於 <bean></bean>

- @Repository:專門處理dao層,交給ioc容器

- @Service:專門處理service層,交給ioc容器

- @Controller:專門處理web層,交給ioc容器

注意,如果使用註解開發,必須開啓註解組件掃描:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.wsl"></context:component-scan>

   <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
    
</beans>

AccountDao

AccountService

DI:依賴注入

- @Autowired:相當於 <property></property> ,根據類型注入

- @Qualifies:與@Autowired一起使用,根據id查找同類型下的實例

- @Resource :jdk提供的註解(@Autowired+@Qualifies)

補充:

- @Scope:相當於 <bean scope=""></bean>
	singleton:單例對象(默認)
	prototype:多例對象

- @PostConstruct:相當於  <bean init-method=""></bean>

- @PreDestroy:相當於  <bean detroy-method=""></bean>

- @Value:通過${} SPEL,從配置文件中獲取數據

 

// <bean id="userService" class="cn.wsl.service.impl.UserServiceImpl"></bean>
@Service
@Scope("prototype") // 多例對象
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDaoImpl")*/
    @Resource(name = "userDaoImpl")
    private UserDao userDao;

    // <property name="userDao" ref="userDao"></property>
    // @Autowired
    /*public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }*/

    @Value("張三")
    private String name ;

    @Value("${jdbc.driver}")
    private String driver;

    @Override
    public void save() {
        System.out.println(name);
        System.out.println(driver);
        userDao.save();
    }

    @PostConstruct
    public void init(){
        System.out.println("init執行了...");
    }

    @PreDestroy
    public void detroy(){
        System.out.println("destroy執行了...");
    }
}

 

(2)Spring常用註解整合DbUtils

改造:

AccountDao

@Repository
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private QueryRunner queryRunner;
    @Override
    public void save(Account account) {
        String sql ="insert into account(name,money) values(?,?)";
        try {
            queryRunner.update(sql,account.getName(),account.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(Account account) {
        String sql = "update account set name=?,money =? where id=?";
        try {
            queryRunner.update(sql,account.getName(),account.getMoney(),account.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void delete(Integer id) {
        String sql ="delete from account where id = ? ";
        try {
            queryRunner.update(sql,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Account> findAll() {
        List<Account> list = null;
        String sql = "select * from account";
        try {
            list = queryRunner.query(sql,new BeanListHandler<>(Account.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public Account findById(Integer id) {
        Account account = null;
        String sql = "select * from account where id = ?";
        try {
            account = queryRunner.query(sql,new BeanHandler<>(Account.class),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return account;
    }
}

AccountService

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void delete(Integer id) {
        accountDao.delete(id);
    }

    @Override
    public List<Account> findAll() {
        List<Account> all = accountDao.findAll();
        return all;
    }

    @Override
    public Account findById(Integer id) {
        Account account = accountDao.findById(id);
        return account;
    }
}

修改配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd">

    <!--開啓註解組件掃描-->
    <context:component-scan base-package="com.wsl"/>

    <!--加載第三方配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--druid連接交給ioc容器:第三方類目前只能使用bean標籤 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!--queryRunner交給ioc容器:第三方類目前只能使用bean標籤-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

</beans>

測試:

 

(3)Spring新註解:

使用上面的註解還不能全部替代xml配置文件,還需要使用註解替代的配置

- @Configuration : 相當於applicationContext.xml

- @Bean:加載第三方類(對象),交給ioc容器

- @PropertySource  :相當於 <context:property-placeholder location=""/>

- @ComponentScan :相當於 <context:component-scan base-package=""/>

- @Import :相當於 <import resource=""></import>

(4)利用純註解整合DbUtils

創建SpringConfig配置類

@Configuration // applicationContext.xml
@ComponentScan("cn.wsl") // <context:component-scan base-package="cn.wsl"/>
@PropertySource("classpath:jdbc.properties") // <context:property-placeholder location="classpath:jdbc.properties"/>
public class SpringConfig {

    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    // 自定義druid對象,交給ioc容器
    /*
         <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
     */
    @Bean("dataSource")
    public DataSource createDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }

    // 自定義queryRunner對象,交給ioc容器
    /*
        <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
            <constructor-arg name="ds" ref="dataSource"></constructor-arg>
        </bean>
     */
    @Bean("queryRunner")
    public QueryRunner createQueryRunner(@Autowired DataSource dataSource) { // 這裏的代碼就是從ioc容器中,完成了依賴注入...
        QueryRunner queryRunner = new QueryRunner(dataSource);
        return queryRunner;
    }
}

測試

 

(5)配置類模塊化

編寫DataSourceConfig

public class DataSourceConfig {

    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    // 自定義druid對象,交給ioc容器
    /*
         <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
     */
    @Bean("dataSource")
    public DataSource createDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }
}

修改主配置類:

 

三.Spring整合Junit

(1)介紹:

Junit是一個單元測試工具,點擊run的執行測試方法時,其實底層是通過runner(運行器)來工作的,默認的Junit是不會自動加載spring環境。

如果想在Junit中直接獲取spring的容器,我們需要導入spring提供的測試整合包,切換爲spring的運行器,就可以直接獲取IOC容器中的對象了。

<!--單元測試-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

(2)使用

在進行單元測試時,指定junti的運行器爲spring的

指定加載配置文件或者配置類

注意:註解-@ContextConfiguration(locations = "classpath:applicationContext.xml")  可以加載全註解配置類,也可以加載xml文件配置文件


@RunWith(SpringRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountTest {
    @Autowired
    AccountService  accountService;
    //新增
    @Test
    public  void test01() throws  Exception{
       accountService.save(new Account(7,"張hah",2650.0));
    }
    //修改
    @Test
    public  void test02() throws  Exception{
        accountService.update(new Account(4,"張三",2050.0));
    }
//刪除
    @Test
    public  void test03() throws  Exception{
        accountService.delete(4);
    }
//查詢所有
    @Test
    public  void test04() throws  Exception{
        List<Account> all = accountService.findAll();
        System.out.println(all);
    }
//查詢一個
    @Test
    public  void test05() throws  Exception{
        Account account = accountService.findById(5);
        System.out.println(account);

    }
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章