欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring学习二-使用 Spring 的 IOC实现 CRUD 功能

程序员文章站 2022-04-23 16:02:13
...

1、使用 Spring 的 IOC 实现 CRUD

IOC 的 xml 配置 实现

1.1、POM依赖

<?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.wmding.spring</groupId>
    <artifactId>com.wmding.spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--spring的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
        </dependency>

        <!--dbutils操作数据库-->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!--JDBC连接池-->
        <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>

1.2、持久层实现

实现对数据库的查询,首先要创建数据库

 CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `age` int DEFAULT NULL COMMENT '年龄',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

操作数据库

public class UserDao {

    private QueryRunner runner;
		
    public void setRunner(QueryRunner runner) {
        this.runner = runner;
    }

    public int saveUser(User user) {
        try {
            return runner.update("insert into user(name,age) values(?,?)",user.getName(),user.getAge());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public List<User> list() {
        try {
            return runner.query("select * from user",new BeanListHandler<User>(User.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public int deleteUser(Integer userId) {
        try {
            return runner.update("delete from user where id=?",userId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public User getUserById(Integer id){
        try {
            return runner.query("select * from user where id = ?",new BeanHandler<User>(User.class),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

}

1.3、业务层实现

1.3.1、业务接口

public interface UserService {

    int saveUser(User user);

    List<User> list();

    int deleteUser(Integer userId);

    User getUserById(Integer id);
}

1.3.2、接口实现

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public int saveUser(User user) {
        return userDao.saveUser(user);
    }

    public List<User> list() {
        return userDao.list();
    }

    public int deleteUser(Integer userId) {
        return userDao.deleteUser(userId);
    }

    public User getUserById(Integer id) {
        return userDao.getUserById(id);
    }
}

1.4、IOC 配置(bean.xml)

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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
  
    <bean id="userService" class="com.wmding.spring.serivce.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean id="userDao" class="com.wmding.spring.dao.UserDao">
        <property name="runner" ref="runner"/>
    </bean>
		
  	<!--配置QueryRunner-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
      	<!--注入数据源-->
        <constructor-arg name="ds" ref="dataSource"/>
    </bean>

  	<!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
      	<!--连接数据库的必备信息-->
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=UTC"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>

</beans>

1.5、测试类

public class UserTest {

    @Test
    public void saveUser(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserService userService = (UserService) ac.getBean("userService");
        User user = new User();
        user.setAge(10);
        user.setName("1jfeklf");
        int i = userService.saveUser(user);
        System.out.println(i);
    }

    @Test
    public void list(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserService userService = (UserService) ac.getBean("userService");
        List<User> list = userService.list();

        for (User user : list) {
            System.out.println(user);
        }
    }

    @Test
    public void deleteUser(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserService userService = (UserService) ac.getBean("userService");
        userService.deleteUser(1);
    }


    @Test
    public void getUserById(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserService userService = (UserService) ac.getBean("userService");
        User user = userService.getUserById(1);
        System.out.println(user);
    }
}

2、基于注解的 IOC 配置

使用注解的方式实现

2.1、POM依赖

<?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.wmding.spring</groupId>
    <artifactId>com.wmding.spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--spring的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
        </dependency>

        <!--dbutils操作数据库-->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!--JDBC连接池-->
        <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>

2.2、持久层实现

使用了注解 @Repository,将 userDao 注入到 Spring 的容器中

@Repository("userDao")
public class UserDao {

    @Autowired
    private QueryRunner runner;


    public int saveUser(User user) {
        try {
            return runner.update("insert into user(name,age) values(?,?)",user.getName(),user.getAge());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public List<User> list() {
        try {
            return runner.query("select * from user",new BeanListHandler<User>(User.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public int deleteUser(Integer userId) {
        try {
            return runner.update("delete from user where id=?",userId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public User getUserById(Integer id){
        try {
            return runner.query("select * from user where id = ?",new BeanHandler<User>(User.class),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

}

2.3、业务层实现

2.3.1、业务接口

public interface UserService {

    int saveUser(User user);

    List<User> list();

    int deleteUser(Integer userId);

    User getUserById(Integer id);
}

2.3.2、业务实现

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    public int saveUser(User user) {
        return userDao.saveUser(user);
    }

    public List<User> list() {
        return userDao.list();
    }

    public int deleteUser(Integer userId) {
        return userDao.deleteUser(userId);
    }

    public User getUserById(Integer id) {
        return userDao.getUserById(id);
    }
}

2.4、使用注解代替bean.xml

/**
 * @author 明月
 * @version 1.0
 * @date 2020-04-20 22:40
 * @description:
 *
 * 该类是一个配置类,它的作用是和bean.xml是一样的
 *
 * @Configuration
 *  作用:指定当前类是一个配置类
 * @ComponentScan
 *  作用:用于通过注解指定spring在创建容器时要扫描的包
 *  属性:
 *      value 和 basePackage 的作用一样
 *      等同于bean.xml中的
 *      <context:component-scan base-package="com.wmding.spring"/>
 * @Bean
 *  作用:用于把当前方法的返回值作为 bean 对象存入到 spring 的容器中
 *  属性:
 *      name 和 value 的作用一样,指定 bean的 id;如果不写,默认是当前方法的名称
 *
 * @Import
 *  作用:用于引入其他的配置类
 *  属性:
 *   value:用于指定引入其他配置类的字节码
 *
 * @PropertySource
 *  作用:用于指定 properties 文件的位置
 *  属性:
 *      value:指定文件的名称和路径
 *      	classpath 表示类路径下
 *
 */
@Configuration
@ComponentScan(value = "com.wmding.spring")
@Import(value = JdbcConfig.class)
public class SpringConfig {
    
}
// 引入配置文件
@PropertySource(value = "classpath:jdbc.properties")
public class JdbcConfig {

    /**
     * <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
     * <constructor-arg name="ds" ref="dataSource"/>
     * </bean>
     *
     * <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
     * <property name="driverClass" value="com.mysql.jdbc.Driver"/>
     * <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=UTC"/>
     * <property name="user" value="root"/>
     * <property name="password" value="root"/>
     * </bean>
     */
    
    @Value("${jdbc.driver}")
    private String driver;

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


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


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


    @Bean(value = "runner")
    //@Scope(value = "prototype")
    public QueryRunner runner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }

    @Bean(value = "dataSource")
    public DataSource dataSource() {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        try {
            comboPooledDataSource.setDriverClass(driver);
            comboPooledDataSource.setJdbcUrl(url);
            comboPooledDataSource.setUser(username);
            comboPooledDataSource.setPassword(password);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }

        return comboPooledDataSource;
    }
}

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=UTC
jdbc.username=root
jdbc.password=root

2.5、测试类

public class UserTest {

    @Test
    public void saveUser(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) ac.getBean("userService");
        User user = new User();
        user.setAge(20);
        user.setName("王明2");
        int i = userService.saveUser(user);
        System.out.println(i);
    }

    @Test
    public void list(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) ac.getBean("userService");
        List<User> list = userService.list();

        for (User user : list) {
            System.out.println(user);
        }
    }

    @Test
    public void deleteUser(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) ac.getBean("userService");
        userService.deleteUser(1);
    }


    @Test
    public void getUserById(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) ac.getBean("userService");
        User user = userService.getUserById(1);
        System.out.println(user);
    }
}

3、Spring 整合 Junit

之前的 测试类中,需要使用如下代码,来实现从spring 容器中取bean。

ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = (UserService) ac.getBean("userService");

但是每个测试方法中都有重复代码,spring 已经提供了整合 junit 的方法。

3.1、添加依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.2.2.RELEASE</version>
</dependency>

3.2、测试类修改

Spring 整合 junit 的配置

  • 1、导入Spring整合Junit的jar

  • 2、使用Junit 提供的一个注解,把原来的 main 方法替换了,替换成Spring提供的

    @RunWith

  • 3、告知Spring运行器,Spring和IOC创建是基于xml的还是注解的,并说明位置

    @ContextConfiguation

    locations: 指定xml文件的位置,加上 classpath 关键字,表示在类路径下

    classes: 指定注解类所在的位置

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserTest2 {

    @Autowired
    private UserService userService;

    @Test
    public void saveUser(){
        User user = new User();
        user.setAge(20);
        user.setName("王明2");
        int i = userService.saveUser(user);
        System.out.println(i);
    }

    @Test
    public void list(){
        List<User> list = userService.list();

        for (User user : list) {
            System.out.println(user);
        }
    }

    @Test
    public void deleteUser(){
        userService.deleteUser(1);
    }

    @Test
    public void getUserById(){
        User user = userService.getUserById(1);
        System.out.println(user);
    }
}