Spring
内容管理
Javaweb —Spring
Spring整合Mybatis
前面已经分享了IOC和AOP 导入的依赖是spring-context和spring-aspects;如果IOC中要使用Resource注解,高版本需要加入javax-annotation-api依赖; IOC和Aop都是可以实现解耦的,IOC是控制反转,创建单例对象;Aop是动态代理,插入切面
Spring集成Mybatis
将Mybatis和Spring进行整合,解决的问题就是将sqlSession对象交给Spring进行管理,所以,整合就是将sqlSessionFactory的对象生成器SqlSessionFactoryBean注册到Spring容器,在将其注入给Dao的实现类就完成了整合; 之前分析动态代理,只要命名空间和id一致就可以通过session对象的getMapper方法获得一个Dao接口的代理类 【也就是IOC集成】
实现Spring和Mybatis整合常用的方式: 扫描的Mapper动态代理; 两个框架一组合就形成一个整体,把mybatis中的对象交给spring统一创建
之前使用mybatis步骤
- 定义Dao接口
- 定义mapper文件,命名空间和接口名一致
- 定义mybatis的主配置文件,可以有数据库的配置文件properties
- 使用dao的代理对象,通过SqlSession对象的getMapper(Dao.class)使用
要想使用dao对象,必须有SqlSession实例对象,使用sqlsessionFactoryBuilde的build然后使用SqlSessionFactory的openSession方法【自动提交事务与否】
之前在使用Mybatis的时候,主配置文件中的environment标签中的transactionManager使用的是JDBC;DataSource的type是POOLED;但是大型项目的POOLED的比较弱,一般采用独立的连接池类的对象,一般使用阿里的德鲁伊druid连接池
所以IOC只需要创建3个对象 : druid对象、SqlSessionFactory对象,dao对象 就可以使用mybatis了
加入依赖
要在spring中使用mybatis,要加入几种依赖
- spring依赖,也就是context 【还可能有javax-annotation-api依赖】
<!--加入Spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<!-- 加入J2EE的依赖,使用@Resource -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 加入AspectJ依赖,方便实现AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
- mybatis依赖
<!-- 添加mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
- mysql依赖
<!--添加mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
//pageHelper也可以加入
<!-- 加入pageHelper依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
- spring的事务依赖 spring-tx 和jdbc
<!--spring transaction -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.14</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.14</version>
</dependency>
- mybatis和spring的集成的依赖,mybatis官方提供,用来在spring中创建mybatis中的sqlsessionFactory、dao对象 [还有连接池的依赖]
<!-- mybatis 和spring集成-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- 德鲁伊druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
还要注意pom文件的build一定要加上Resource和java中的资源,不然无法正常访问
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<!-- 还要配置上原来编译资源的路径-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
创建实体类
这里和mybatis中相同,没有特别的,就还是使用cfengbase中的student表,属性值和字段名一致【简单】
package cfeng.entiry;
public class Student {
private int stuno;
private String stuname;
private String stuclass;
public Srudent() {
}
public Srudent(int stuno, String stuname, String stuclass) {
this.stuno = stuno;
this.stuname = stuname;
this.stuclass = stuclass;
}
public int getStuno() {
return stuno;
}
public void setStuno(int stuno) {
this.stuno = stuno;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public String getStuclass() {
return stuclass;
}
public void setStuclass(String stuclass) {
this.stuclass = stuclass;
}
@Override
public String toString() {
return "Srudent{" +
"stuno=" + stuno +
", stuname='" + stuname + '\'' +
", stuclass='" + stuclass + '\'' +
'}';
}
}
//代码自动生成即可,所以实体类非常简单
创建dao接口和mapper文件
这里的接口中就是想要实现的方法,一个接口对应一个mapper文件,一个mapper文件对应一个数据库表的操作
package cfeng.dao;
import cfeng.entiry.Student;
import java.util.List;
public interface StudentDao {
//获取数据库表中所有的学生
public List<Student> selectStudents();
//插入学生对象
public int insertStudent(Student student);
}
之后创建mapper文件,一般将这个文件放在和Dao接口同一目录下,这个mapper文件就相当于实现类; 直接使用之前的模板文件archtype
<?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="cfeng.dao.StudentDao">
<select id="selectStudents" resultType="cfeng.entity.Student">
SELECT stuno,stuname,stuclass FROM student ORDER BY stuno ASC
</select>
<insert id="insertStudent">
INSERT INTO student VALUES (#{stuno},#{stuname},#{stuclass})
</insert>
</mapper>
创建mybatis主配置文件
这里还是使用模板,但是还是需要知道最高级的是configuration标签;其中的settings是日志,environments是数据库环境;需要注意的是,集成之后不需要environment了,可以使用别名,就不需要写全限定名称了,mapper文件的加载也可以使用package;两者异曲同工
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 这里也是从类路径的根开始,因为resource直接复制到classes下面,这里就直接写名称即可-->
<properties resource="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="cfeng.entity"/>
</typeAliases>
<!-- 以后的环境都是用druid了 -->
<mappers>
<!-- <mapper resource="cfeng\dao\StudentDao.xml"/> 直接按照包导入就可-->
<package name="cfeng\dao"/>
</mappers>
</configuration>
创建service接口和实现类,属性为dao
创建service接口
package cfeng.service;
import cfeng.entiry.Student;
import java.util.List;
public interface StudentService {
public int addStudent(Student student);
public List<Student> queryStudents();
}
-----------------------------------实现类----------------
package cfeng.service.impl;
import cfeng.dao.StudentDao;
import cfeng.entiry.Student;
import cfeng.service.StudentService;
import java.util.List;
public class StudentServiceImpl implements StudentService {
//引用类型,关联关系
private StudentDao dao;
//使用set injection
public void setDao(StudentDao dao) {
this.dao = dao;
}
@Override
public int addStudent(Student student) {
return dao.insertStudent(student);
}
@Override
public List<Student> queryStudents() {
return dao.selectStudents();
}
}
创建spring的配置文件,声明mybatis对象交给spring管理
数据源配置
这是一个非常重要的配置;使用JDBC的模板,需要先配置好数据源,数据源直接以Bean的形式配置在Spring的配置文件中,这里选择的数据源是druid
druid是阿里的开源数据库连接池,Druid能够提供强大的监控和扩展功能 官网:https://github.com/alibaba/druid
要想在Spring中使用properties配置文件,可以借助context命名空间中的property-placeholder标签, location需要指定classpath:
#####################mysql configuration###########################
#jdbc.driver= com.mysql.cj.jdbc.Driver 德鲁伊支持数据库,不需要驱动
jdbc.url = jdbc:mysql://localhost:3306/cfengbase?servertimezone=GMT%2B8
jdbc.user = cfeng
jdbc.pwd = **************
配置文件
</bean><!-- 声明数据源Datasource ,作用是连接数据库,不需要之前mybatis的environment;数据源对象自带数据库的信息-->
<!-- 连接阿里巴巴的德鲁伊数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/> <!-- 配置文件的类型,会自动提示是否含有这个属性name 这里pwd和properties文件相同 -->
<!--<property name="driver" value="${jdbc.driver}"/> 不需要-->
<property name="maxActive" value="20"/>
</bean>
创建SqlSessionFactory对象
声明的是mybatis中提供的sqlSessionFactoryBean类,在这个类的内部会创建SqlSessionFactory对象;之前通过builder创建factory的,需要mybatis的主配置文件,所以这里需要数据源和mybatis的主配置文件,需要的就是datasource和configLocation;
DataSource
: 数据源,因为之前的mybatis中数据源是在配置文件中,但是Spring使用的是德鲁伊的数据源,所以需要加入才能创建对象,这里的ref就是 datasource对象的id ---- 也就是这个对象依赖datasouurce对象,需要使用ref进行属性注入【引用类型】
configLocation
: 这个属性是Resource类型,读取配置文件的 -----> 它的赋值,使用vlaue,使用classpath:指定是类路径
<!--声明的是SqlSessionFactoryBean类,其内部会创建SqlSessionFacory对象,按照
原来的经验,需要读取主配置文件,其中包括dataSource
-->
<bean id="mySqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<!-- 还有主配置文件的其他的信息 读取文件-->
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>
这样就可以得到一个SqlSessionFactory对象,可以验证一下
mySqlSession对象的类型 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@a43ce46
而在mybatis中提到过,就是DefaultSqlSessionFactory作为默认的实现类;所以成功创建了对象
创建dao对象
在mybatis中创建dao对象要使用factory的getMapper方法,所以在配置文件中要想使用,首先要有factory对象,注意这里的是name,为String简单类型,不是ref,而是value; dao的创建借助的是非自定义名称的MapperScannerConfig对象; 指定包,就会扫描包中的所有的接口,为每一个都创建对象
<!--创建Dao对象,使用sqlSession的getMapper就可以了 使用mybatis的对象MapperScannerConfig类型-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 相当于内部调用这个方法,所以需要factory对象,还需要接口的类型 看到是String类型的,使用value,不是ref-->
<property name="sqlSessionFactoryBeanName" value="mySqlSession"/>
<!-- 指定包名,包名是dao接口所在的包名,MapperScannerConfig会扫描这个包中所有的接口,
都调用getMapper方法为每一个接口代理一个dao对象,创建好的所有的dao对象存放在容器中
-->
<property name="basePackage" value="cfeng.dao"/>
</bean>
可以查看容器的对象
org.mybatis.spring.mapper.MapperScannerConfigurer#0对象的类型 org.mybatis.spring.mapper.MapperScannerConfigurer@f79a760
studentDao对象的类型 org.apache.ibatis.binding.MapperProxy@652a7737
可以看到MapperScannerConfiguer对象创建在容器中,该对象对包进行扫描,创建了与id接口同名的dao对象
这些代码都是固定的,所以Spring是模板编程
接下来在Spring容器中创建一个service对象,dao属性的赋值就用上面创建的对象【接口名的、首字母小写】
<!-- 利用上面的dao对象进行属性注入 -->
<bean name="studentService" class="cfeng.service.impl.StudentServiceImpl">
<property name="dao" ref="studentDao"/>
</bean>
Spring和mybatis整合在一起的时候,事务默认自动提交
这里可以利用test来调用service执行方法
@Test
public void testMybatis() {
//要读取spring的属性配置文件进行容器的创建
ApplicationContext springContainer = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService service = (StudentService) springContainer.getBean("studentService");
List<Student> list = service.queryStudents();
list.forEach(System.out :: println);
}
这里可以查看执行的结果,完全是符合预期的
==> Preparing: SELECT stuno,stuname,stuclass FROM student ORDER BY stuno ASC
==> Parameters:
<== Columns: stuno, stuname, stuclass
<== Row: 1, 张三, HC2001
<== Row: 2, 李四, HC2002
这里就是在Spring中使用mybatis了,现在就不需要再手工创建SqlsessionFactory了; 所有的对象的创建都是再配置文件中完成,使用的datasource就是druid的,需要导入依赖,该对象不需要导入driver,MaxActive是最大连接的个数;使用Spring整合之后的mybatis只剩下了创建配置文件了。 导入的依赖除了本身的mybatis之外,还有mybatis-spring; 如果要分页,需要pageHelper🎄