支付网站建设费入什么科目网络推广方案设计
在“SSM1==springframework。XML实现IOC的4种方式,实现DI的8种方式。”中,我们知道,spring(springframework)的能够通过IOC将对象A交给IOC容器管理(创建),并且通过DI将对象A需要的一些属性和对象B注入到对象A。上述的对象AB都是我们自己写的,那么真实项目中使用到的都是第三方提供的jar包,那么该怎么将他们交给IOC容器管理?
现在针对三层架构MVC中的三层,我们使用servlet作为controller层,在service中通过mybatis去操作model(pojo),整个过程中哪些可以交给IOC容器创建?交给IOC容器创建的对象又需要哪些依赖注入?
首先,controller层中使用的service对象可以交给IOC容器创建,其次service层中需要的mybaitis的sqlsessionfactory对象可以交给IOC容器创建,mybaitis需要调用DRUID连接池对象也可以交给IOC容器创建,即将上述三者配置为bean。同时需要配置三个bean中的依赖注入关系。
=================================================================
一:通过spring管理DRUID连接池对象。
先看一下不使用spring是怎么使用DRUID连接池的。步骤为:
//java通过德鲁伊连接池连接mysql CRUD//导入jar包 druid-1.1.12.jar,mysql-connector-java-5.1.48.jar//定义配置文件druid.properties//加载配置文件prop.load(new FileInputStream("src\\druid.properties"));//获取数据库连接池对象方式一DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);//获取数据库连接池对象方式二 先DruidDataSource dataSource;然后通过set配置属性//获取连接 connection = dataSource.getConnection();
BrandTest代码
package com.ldj.test;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.ldj.pojo.Brand;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;//java通过德鲁伊连接池连接mysql CRUD
//导入jar包 druid-1.1.12.jar,mysql-connector-java-5.1.48.jar
//定义配置文件druid.properties
//加载配置文件prop.load(new FileInputStream("src\\druid.properties"));
//获取数据库连接池对象方式一DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//获取数据库连接池对象方式二 先DruidDataSource dataSource;然后通过set配置属性
//获取连接 connection = dataSource.getConnection();
public class BrandTest {private Connection connection;@Beforepublic void before() throws Exception {Properties prop = new Properties();System.out.println("相对地址向对方为====" + System.getProperty("user.dir"));prop.load(new FileInputStream("src\\druid.properties"));//获取DataSource的第一种方式
// DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);//获取DataSource的第二种方式DruidDataSource dataSource;String driverClassName = prop.getProperty("driverClassName");String url = prop.getProperty("url");String username = prop.getProperty("username");String password = prop.getProperty("password");String initialSize = prop.getProperty("initialSize");String maxActive = prop.getProperty("maxActive");String maxWait = prop.getProperty("maxWait");dataSource = new DruidDataSource(); // 创建Druid连接池dataSource.setDriverClassName(driverClassName); // 设置连接池的数据库驱动dataSource.setUrl(url); // 设置数据库的连接地址dataSource.setUsername(username); // 数据库的用户名dataSource.setPassword(password); // 数据库的密码dataSource.setInitialSize(Integer.parseInt(initialSize)); // 设置连接池的初始大小dataSource.setMaxActive(Integer.parseInt(maxActive)); // 设置连接池大小的上限dataSource.setMaxWait(Long.parseLong(maxWait));// 设置连接池保留时间connection = dataSource.getConnection();}@Testpublic void selectAll() throws SQLException {System.out.println(System.getProperty("user.dir"));String sql = "select * from tb_brand";PreparedStatement pstmt = connection.prepareStatement(sql);ResultSet res = pstmt.executeQuery();ArrayList<Brand> brandList = new ArrayList<>();while (res.next()) {int id = res.getInt("id");String brandName = res.getString("brand_name");String companyName = res.getString("company_name");int ordered = res.getInt("ordered");String description = res.getString("description");int status = res.getInt("status");Brand brand = new Brand(id, brandName, companyName, ordered, description, status);brandList.add(brand);}System.out.println(brandList);pstmt.close();res.close();}@Afterpublic void after() throws SQLException {connection.close();}
}
然后我们根据上述步骤,将druid交给IOC容器管理。因为使用DRUID连接池有两种方式,所以交给spring也有多种方法。方法一是将DruidDataSourceFactory的实例化对象交给IOC容器管理,但比较复杂。我们最好将DruidDataSource的实例化对象的创建交给IOC容器管理,并且通过DI将数据库账号密码等属性注入到相应的对象bean,另外还要有一步是读取properties文件获取属性值。下面为实现步骤:
1、新建一个maven基础项目,导入springframework基础依赖包spring-context
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
2、导入DRUID、jdbc、junit依赖包
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency>
3、编辑spring配置文件,读取存账号密码等的properties文件。需要用到context命名空间,所以先改xmlns和xsi
<?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
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:property-placeholder location="druid.properties" system-properties-mode="NEVER"/><!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型//以下配置的意思就是将这两个类的对象交给IOC容器创建--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" ><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${url}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property><property name="initialSize" value="${initialSize}"></property><property name="maxActive" value="${maxActive}"></property><property name="maxWait" value="${maxWait}"></property></bean>
</beans>
4、将DruidDataSource 配置成一个由IOC容器管理的bean,并指定实例化方法为默认的空参构造方法实例化bean。见“SSM1==springframework。XML实现IOC的4种方式,实现DI的8种方式。”
5、根据DruidDataSource 的源码选择DI依赖注入的实现方式为setter注入。根据源码可以得知,DruidDataSource类只有两个构造器,而且他能用的参数比较多,使用者是根据自己的需求配置参数,阿里也没法挨个提供相应的构造器。所以只能用setter注入方式。“SSM1==springframework。XML实现IOC的4种方式,实现DI的8种方式。”
6、获取bean得到一个DruidDataSource对象,getConnection获取Connection对象,进行CRUD操作。
private Connection connection;@Beforepublic void before() throws Exception {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");DruidDataSource datasource = (DruidDataSource) ctx.getBean("dataSource");System.out.println(datasource);connection = datasource.getConnection();System.out.println(datasource);}
===============================================================
spring配置druid连接池项目结构和代码如下:
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>org.example</groupId><artifactId>springDruid</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency></dependencies></project>
Brand
public class Brand {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态:0:禁用 1:启用private Integer status;
druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
#与spring配合使用时,key一定不要用username,因为win系统有个内置的变量交username会起冲突。
# 或者在配置文件中加上 system-properties-mode="NEVER"
username=root
password=1234
# ???????
initialSize=5
# ?????
maxActive=10
# ??????
maxWait=3000
applicationContext.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
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:property-placeholder location="druid.properties" system-properties-mode="NEVER"/><!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型//以下配置的意思就是将这两个类的对象交给IOC容器创建--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" ><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${url}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property><property name="initialSize" value="${initialSize}"></property><property name="maxActive" value="${maxActive}"></property><property name="maxWait" value="${maxWait}"></property></bean>
</beans>
BrandTest
import com.alibaba.druid.pool.DruidDataSource;
import ldj.pojo.Brand;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;//java通过德鲁伊连接池连接mysql CRUD
//导入jar包 druid-1.1.12.jar,mysql-connector-java-5.1.48.jar
//定义配置文件druid.properties
//加载配置文件prop.load(new FileInputStream("src\\druid.properties"));
//获取数据库连接池对象方式一DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//获取数据库连接池对象方式二 先DruidDataSource dataSource;然后通过set配置属性
//获取连接 connection = dataSource.getConnection();
public class BrandTest {private Connection connection;@Beforepublic void before() throws Exception {
//获取容器ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中取出beanDruidDataSource datasource = (DruidDataSource) ctx.getBean("dataSource");System.out.println(datasource);connection = datasource.getConnection();System.out.println(datasource);}@Testpublic void selectAll() throws SQLException {System.out.println(System.getProperty("user.dir"));String sql = "select * from tb_brand";PreparedStatement pstmt = connection.prepareStatement(sql);ResultSet res = pstmt.executeQuery();ArrayList<Brand> brandList = new ArrayList<>();while (res.next()) {int id = res.getInt("id");String brandName = res.getString("brand_name");String companyName = res.getString("company_name");int ordered = res.getInt("ordered");String description = res.getString("description");int status = res.getInt("status");Brand brand = new Brand(id, brandName, companyName, ordered, description, status);brandList.add(brand);}System.out.println(brandList);pstmt.close();res.close();}}
====================================================================
如上,我们根据druid的传统代码,将druid连接池整合到了spring中。那如果换一个连接池(如DBCP,C3P0)也是一样的道理,先找到连接池需要注入参数的对象,然后交给spring IOC容器管理,并通过适当的DI注入方式注入必要的参数即可。如C3P0连接池,上官网可以看到这个对象是ComboPooledDataSource,将他交给IOC容器管理,用setter注入必要参数即可。使用的时候获取容器,从容器中取出bean,调用方法,即可。
获取容器的方式有两种,最好用第一种,第二种当项目的位置发生变化后,代码也需要跟着改,耦合度较高,不推荐使用。
从上,能够看到我们获得到的IOC容器其实是一个叫做ApplicationContext的接口,那其实使用它实现的BeanFacory也可以,两者加载bean的时机不一样,BeanFacory默认lazy-init延迟加载bean到容器中,ApplicationContext程序一启动ApplicationContext容器一获取就会加载bean到容器中虽然可以通过设置来更改。理解如下,spring的设计人员一开始只设计了顶层接口BeanFacory作为IOC容器,后来发现功能不够用,就设计了ApplicationContext核心接口作为IOC容器,后者还实现了其他的一些接口的功能,比如关闭容器功能,暴力关容器ctx.close(), 注册钩子关闭器 ctx.registerShutDownHook()。
获取bean的方式有三种:
=========================================================================
二:通过spring管理mybatis对象。
先看一下不使用spring是怎么使用DRUID连接池的。步骤为:
1、新建maven项目,导入mybatis、jdbc依赖包
2、编写mybatis全局配置文件(别名,配置数据库连接环境信息含连接池,配置mapper的路径)
3、编写mapper、mapper.xml
4、读取全局配置文件,获取会话工厂SqlSessionFactory,获取会话对象SqlSession,通过SqlSession获取mapper对象,通过mapper对象调用CRUD方法。
参照mybatis官网
mybatis – MyBatis 3 | 入门https://mybatis.org/mybatis-3/zh/getting-started.html 可以看出,重要的是将SqlSessionFactory交给spring IOC容器管理,管理简单,但是SqlSessionFactory需要全局配置文件中的一堆参数,全局配置文件里面还需要一堆参数,由我们挨个编写DI依赖注入的话非常复杂。参照之前的bean的4种实例化方式,可以实现spring提供的一个接口FactoryBean来实例化对象,mybatis提供了一个依赖包叫做mybatis-spring,依赖包里实现了FactoryBean的类叫做SqlSessionFactoryBean。
所以,我们引入依赖包后,将SqlSessionFactoryBean交给IOC容器管理,然后注入几个简单的参数就行了(其中连接池对象必须也交给spring管理并注入都SqlSessionFactoryBean)。ctx.getBean时,会自动调用SqlSessionFactoryBean中的getObjectType方法返回SqlSessionFactory对象。
以上流程我们就得到了SqlSessionFactory对象,然后openSession,getMapper得到mapper,然后调用方法即可。
根据三层架构,我们还可以将service也交给spring IOC容器管理,并用自动装配的方式将mapper注入到service对象中,controller的对象较为复杂,暂时不交给spring管理
上述交给IOC容器管理的对象,我们既可以单独获得然后自行补全后续流程来使用,比如单独获得DataSource使用,单独获得SqlSessionFactory使用,单独获得mapper来使用,也可直接获得service来使用。
spring整合mybatis步骤如下:
1、新建一个MAVEN项目,导入依赖
2、编写entity、mapper、mapper.xml、service
3、编写数据库properties配置文件
4、编写spring配置文件
5、测试
项目结构:
完整代码:
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>org.example</groupId><artifactId>springMybatis</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--spring IOC容器必须的依赖,可以单独导入四个,也可以直接导入一个spring-context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.12</version></dependency><!--连接数据源必须的,spring-jdbc将mysql事务交给spring管理--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.12</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><!--数据库连接池Druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!--mybatis依赖包2个,mybatis-spring简化配置书写--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency><!--测试工具依赖包--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies></project>
Book
package com.ldj.entity;public class Book {private String bookname;private Integer id;private int price;@Overridepublic String toString() {return "Book{" +"bookname='" + bookname + '\'' +", id=" + id +", price=" + price +'}';}public String getBookname() {return bookname;}public void setBookname(String bookname) {this.bookname = bookname;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}
}
mapper
package com.ldj.mapper;import com.ldj.entity.Book;import java.util.List;public interface BookMapper {List<Book> findAll();
}
mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ldj.mapper.BookMapper"><select resultType="com.ldj.entity.Book" id="findAll">select * from book</select></mapper>
service
package com.ldj.service;import com.ldj.mapper.BookMapper;
import com.ldj.entity.Book;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class BookService {private BookMapper bookMapper;public List<Book> findAll() {return bookMapper.findAll();}
//setter。不使用注解,service获得bookMapper的方式也有两种:
// 一是通过自动装配setter注入,
// 二是我们可以在这里也获取一次IOC容器,然后从IOC容易中取出。public void setBookMapper(BookMapper bookMapper) {this.bookMapper = bookMapper;}
}
数据库配置
db.driveClass=com.mysql.cj.jdbc.Driver
db.username=root
db.password=1234
db.url=jdbc:mysql:///db1?useSSL=false&&useServerPrepStmts=true
spring配置
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd"><!--导入属性文件 这样其中的数据就可以用占位符访问--><context:property-placeholder location="classpath:db/db.properties"></context:property-placeholder><!--将连接池交给spring IOC容器管理:配置数据源--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${db.driveClass}"></property><property name="url" value="${db.url}"></property><property name="username" value="${db.username}"></property><property name="password" value="${db.password}"></property></bean><!--将mybatis工厂交给spring IOC容器管理:sqlsessionfactory的配置,获取到的是DefaultSqlSessionFactory对象--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><property name="mapperLocations" value="classpath:mapper/BookMapper.xml"></property></bean><!--将mapper交给spring IOC容器管理:mapper扫描,不用配置ID,使用时候直接首字母小写即可调用,方便多个mapper管理--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property><!--dao 接口所对应的包--><property name="basePackage" value="com.ldj.mapper"></property></bean><!--将service交给spring IOC容器管理:autowire属性:开启自动装配,因为只使用了一个Mapper,所以使用按类型自动装配。一定要在service中写对应的setter,因为实际上默认也是使用setter注入,只是减少了spring配置的书写,不用再写property配置属性了,但没简化类的书写。而且我们上面的mapper是用的免写ID的方式,所以这里最好也用自动装配。当然也可以采用实例化方式中的构造器注入,因为没有ID,可以通过index和type来指定注入的东西--><bean id="bookService" class="com.ldj.service.BookService" autowire="byType"/></beans>
编写测试类MyTest
import com.ldj.mapper.BookMapper;
import com.ldj.entity.Book;
import com.ldj.service.BookService;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class MyTest {@Testpublic void test01() {//获取交给spring IOC容器管理的DRUID连接池对象ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println(ctx);Object dataSource = ctx.getBean("dataSource");System.out.println("获取交给spring IOC容器管理的DRUID连接池对象===" + dataSource);}@Testpublic void te2() {//获取交给spring IOC容器管理的SqlSessionFactoryBean,会直接返回一个DefaultSqlSessionFactory对象ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) ctx.getBean("sqlSessionFactory");System.out.println("获取交给spring IOC容器管理的SqlSessionFactory" + sqlSessionFactory);//这里不需要手动配置mysql jdbc事务,因为我们的依赖包spring-jdbc中的spring-tx已经自动帮我们处理事务了!!!SqlSession sqlSession = sqlSessionFactory.openSession();BookMapper mapper = sqlSession.getMapper(BookMapper.class);List<Book> all1 = mapper.findAll();System.out.println(all1);}@Testpublic void te3() {//获取交给spring IOC容器管理的mapperApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookMapper bookMapper = (BookMapper) ctx.getBean("bookMapper");System.out.println(bookMapper);List<Book> all = bookMapper.findAll();System.out.println(all);}@Testpublic void te4() {//获取交给spring IOC容器管理的service,因为配置了按类型自动装配,所以同时会自动生成service需要的bookMapperApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookService bookService = (BookService) ctx.getBean("bookService");List<Book> all2 = bookService.findAll();System.out.println(all2);}
}