1.看图
2.实体类:
package com.domin;
import java.io.Serializable;
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 +
'}';
}
}
//(重写toString)
3.业务层接口:IAccountService
package com.service;
import com.domin.Account;
import java.util.List;
public interface IAccountService {
/*查询所有*/
List<Account> findAllAccount();
/*查询一个*/
Account findAccountById(Integer accountId);
/*保存一个*/
void saveAccount(Account account);
/*更新*/
void updateAccount(Account account);
/*删除一个*/
void deleteAccount(Integer accountId);
}
4.业务层实现类(写入方法)AccountServiceImp:
package com.service.Imp;
import com.dao.IAccountDao;
import com.domin.Account;
import com.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/*交给spring容器去管理*/
@Service("accountService")
public class AccountServiceImp implements IAccountService {
/*交给spring容器去管理:配置accountService中的accountDao*/
@Autowired
//调用持久层
private IAccountDao accountDao;
/*当使用注解的时候,set方法就不是必须的了*/
/*public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}*/
@Override
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
@Override
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}
@Override
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
@Override
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
@Override
public void deleteAccount(Integer accountId) {
deleteAccount(accountId);
}
}
5.持久层接口IAccountDao:
package com.dao;
import com.domin.Account;
import java.util.List;
public interface IAccountDao {
/*查询所有*/
List<Account> findAllAccount();
/*查询一个*/
Account findAccountById(Integer accountId);
/*保存一个*/
void saveAccount(Account account);
/*更新*/
void updateAccount(Account account);
/*删除一个*/
void deleteAccount(Integer accountId);
}
6.持久层实现类:AccountDaoImp
package com.dao.Imp;
import com.dao.IAccountDao;
import com.domin.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.util.List;
/*交给spring去管理*/
@Repository("accountDao")
public class AccountDaoImp implements IAccountDao {
@Autowired/*不指定的话默认类名为id*/
private QueryRunner runner;/*自动注入它的方法:当使用注解的时候set的方法既不是必须的了*/
/*public void setRunner(QueryRunner runner) {
this.runner = runner;
}*/
@Override
public List<Account> findAllAccount() {
/*泛型使用字解码创建对象*/
try{
return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
public Account findAccountById(Integer accountId) {
try{
return runner.query("select * from account where id = ?",new BeanHandler<Account>(Account.class),accountId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
public void saveAccount(Account account) {
try{
runner.update("insert into account(name,money)value(?,?)",account.getName(),account.getMoney());
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
public void updateAccount(Account account) {
try{
runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
public void deleteAccount(Integer accountId) {
try{
runner.update("delete from account where id=?",accountId);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
7.配置类(大模块)ConfigurationTest
package config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
/*
* 该类是一个配置类,它的作用和bean.xml是一样的
* spring中的新注解
* Configuration
* 作用:指定当前类是一个配置类
* 细节:
* 当配置类作为AnnotationConfigApplicationContext对象创建的参数的时候,该注解可以不写。
* (在测试类当中,直接通过类名.class传入,然后注解直接被扫描解读、、但是不绝对)
* 为什么:当你独立开始使用jdbcConfig的时候,那么AnnotationConfigApplicationContext里面的配置文件
* 不再进行整个包的扫描,而是只单独解析类,所以,我们的@Configuration得注上,预防隔离开来的单独一个文件,
* 所以进行扫描包的注解还是必须的
*
* ComponentScan
* 作用:用于通过注解指定spring在创建容器时要扫描的包。
* 属性:
* value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
* 我们使用此注解就等同于在XML中配置了:扫描包的语法
* <context:component-scan base-package="com"></context:component-scan>
* Bean
* 作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
* (容器是有键值对的[key,value],不写有默认值)
* 属性:
* name:用于指定bean的id。默认值是当前方法的名称
* 细节:当我们使用注解配置方法的时候,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象
* 查找的方式和Autowired是一样的
* Scope:作用域(单例singleton、多例prototype)
* Import
* 作用:用于导入其他的配置类 统一在大模块中导入,然后分别写小的子类模块就可以
* 属性:
* value:用于指定其他配置类的字节码。
* 当我们使用Import的注解之后,有Import注解的类就是父配置类,而导入的都是子配置类
* */
/*替代xml中的配置文件*/
@Configuration
//@ComponentScan({"com","config"}) 这里多个必须使用对象
@ComponentScan("com")
@Import(JdbcConfig.class)/*引入*/
public class ConfigurationTest {
/*
* 用于创建一个 QueryRunner对象
*
* */
/*全部移入到JdbcConfig中去*/
// @Bean(name="runner")/*用于把当前方法的返回值作为bean对象存入spring的ioc容器中*/
// @Scope("prototype")/*默认单例,变为多例*/
// public QueryRunner createQueryRunner(DataSource dataSource){
// return new QueryRunner (dataSource);
// }
// /*
// * 创建数据源对象
// *
// * */
// /*和上面的dataSource一样:这样容器中就有了这个对象,就不会报错*/
// @Bean(name = "dataSource")
// public DataSource createDataSource(){
// try {
// ComboPooledDataSource dataSource = new ComboPooledDataSource();
// dataSource.setDriverClass("com.mysql.jdbc.Driver");
// dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/eesy");
// dataSource.setUser("root");
// dataSource.setPassword("123456");
// return dataSource;
// }catch (Exception e){
// throw new RuntimeException(e);
// }
// }
}
8.配置类子模块:JdbcConfig
package config;
/*
* 使用Junit单元测试,测试我们的配置
*
* */
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import javax.sql.DataSource;
//@Configuration 已经在大模块使用@Import了
public class JdbcConfig {
@Bean(name="runner")/*用于把当前方法的返回值作为bean对象存入spring的ioc容器中*/
@Scope("prototype")/*默认单例,变为多例*/
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner (dataSource);
}
/*
* 创建数据源对象
*
* */
/*和上面的dataSource一样:这样容器中就有了这个对象,就不会报错*/
@Bean(name = "dataSource")
public DataSource createDataSource(){
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/eesy");
dataSource.setUser("root");
dataSource.setPassword("123456");
return dataSource;
}catch (Exception e){
throw new RuntimeException(e);
}
}
/*
* 总结一下:原来JdbcConfig里面的东西是放在ConfigurationTest里面的,相当于,大模块是ConfigurationTest 然后
* 1. 大模块里面需要扫描包@ComponentScan({"com"})[email protected]容器配置注解(当这样的时候,可以写,也可以不写这一个)
* 并且配置ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
* 2. 但是小模块分离出来之后JdbcConfig,
* 大模块里面的就变为了这样@ComponentScan({"com","config"})[email protected](/或者/dbcConfig.class)其中一个
* 在小模块中的注解才能被扫描到JdbcConfig中的注解
* 3.我也知道这种方式很繁琐,比较容易乱,所以想要原来的方式,就用到这个注释:@import
* 使用Import的注解就(细节:import可以传多个)
* 大模块ConfigurationTest中:@[email protected]("com")[email protected](JdbcConfig.class)+ ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
* 就可以了
*
* */
}
9.测试类:TestCode
package com.itheima;
import com.domin.Account;
import com.service.IAccountService;
import config.ConfigurationTest;
import config.JdbcConfig;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.List;
public class TestCode {
@Test
public void findAllAccount() {
/*bean.xml 配置文件中*/
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
/*配置类的注解方式使用的*/
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
IAccountService as = (IAccountService) ac.getBean("accountService");
/*类型要注意*/
List<Account> accounts = as.findAllAccount();
for (Account account :accounts){
System.out.println(account);
}
}
@Test
public void findAccountById() {
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
/*配置类的注解方式使用的*/
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
IAccountService as = (IAccountService) ac.getBean("accountService");
Account acc = as.findAccountById(4);
System.out.println(acc);
}
@Test
public void saveAccount() {
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
IAccountService as = (IAccountService) ac.getBean("accountService");
Account acc = new Account();
acc.setName("lalala");
acc.setMoney((float)10000000.00);
as.saveAccount(acc);
System.out.println("执行成功");
}
@Test
public void updateAccount() {
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
IAccountService as = (IAccountService) ac.getBean("accountService");
Account id = as.findAccountById(9);
id.setName("zhou");
id.setMoney((float)100000.00);
/*调用存放*/
as.updateAccount(id);
}
@Test
public void deleteAccount() {
/*bean.xml可以删了*/
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
IAccountService as = (IAccountService) ac.getBean("accountService");
as.deleteAccount(9);
}
}
注:检查单例和多例
10.QueryRunnerTest
package com.itheima;
import config.ConfigurationTest;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class QueryRunnerTest {
@Test
public void RunnerTest() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ConfigurationTest.class);
/*两种方式都可以,获取QueryRunner的对象runner1和runner2,查看是否单例还是多例*/
QueryRunner runner1 = ac.getBean("runner",QueryRunner.class);
QueryRunner runner2 = (QueryRunner) ac.getBean("runner");
if (runner1 == runner2){
System.out.println("一样:"+runner1+"\n"+runner2);
}else{
System.out.println("不一样:"+runner1+"\n"+runner2);
}
}
/*执行sql语句的时候:在持久层的实现类,使用该方法可以会造成占用,所以变为多例*/
}
10.pom.xml依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--spring框架依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--C3P0依赖-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--jdbc依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!--dubcy依赖-->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
总结:在配置类中的常用注解
* 该类是一个配置类,它的作用和bean.xml是一样的 * spring中的新注解 * Configuration * 作用:指定当前类是一个配置类 * 细节: * 当配置类作为AnnotationConfigApplicationContext对象创建的参数的时候,该注解可以不写。 * (在测试类当中,直接通过类名.class传入,然后注解直接被扫描解读、、但是不绝对) * 为什么:当你独立开始使用jdbcConfig的时候,那么AnnotationConfigApplicationContext里面的配置文件 * 不再进行整个包的扫描,而是只单独解析类,所以,我们的@Configuration得注上,预防隔离开来的单独一个文件, * 所以进行扫描包的注解还是必须的 * * ComponentScan * 作用:用于通过注解指定spring在创建容器时要扫描的包。 * 属性: * value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。 * 我们使用此注解就等同于在XML中配置了:扫描包的语法 * <context:component-scan base-package="com"></context:component-scan> * Bean * 作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中 * (容器是有键值对的[key,value],不写有默认值) * 属性: * name:用于指定bean的id。默认值是当前方法的名称 * 细节:当我们使用注解配置方法的时候,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象 * 查找的方式和Autowired是一样的 * Scope:作用域(单例singleton、多例prototype) * Import * 作用:用于导入其他的配置类 统一在大模块中导入,然后分别写小的子类模块就可以 * 属性: * value:用于指定其他配置类的字节码。 * 当我们使用Import的注解之后,有Import注解的类就是父配置类,而导入的都是子配置类 *
注:本人是小白,学习上的错误还希望大家多多指教,共同进步才好,加油加油