3.Spring整合MyBatis

本章目标

  1. Spring整合MyBatis(掌握)
  2. Druid连接池介绍及使用(扩展)

本章内容

本章为Spring中整合MyBatis初级版,目的为了加深对ioc的理解

一、Spring整合MyBatis

为了更好的理解依赖注入,我们先把Spring和MyBatis整合到一起

传统的mybatis-config.xml文件

 <?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>
     <properties resource="jdbc.properties">
         <property name="db.password" value="root1"/>
     </properties>
     <settings>
         <setting name="cacheEnabled" value="true"/>
         <setting name="lazyLoadingEnabled" value="true"/> <!--懒加载:当使用时再去加载-->
     </settings>
     <typeAliases>
         <typeAlias type="com.it.store.entity.Emp" alias="Emp"/>
     </typeAliases>

     <environments default="development">
         <environment id="development">
             <transactionManager type="JDBC"/>
             <dataSource type="POOLED">
                 <property name="driver" value="${db.driver}"/>
                 <property name="url" value="${db.url}"/>
                 <property name="username" value="${db.username}"/>
                 <property name="password" value="${db.password}"/>
             </dataSource>
         </environment>
     </environments>
     <mappers>
         <mapper resource="mapper/EmpMapper.xml"/>
         <mapper resource="mapper/TeacherMapper.xml"/>
         <mapper resource="mapper/ClassesMapper.xml"/>
     </mappers>
 </configuration>

SqlSessionFactory —>SqlSesssion—>Mapper(映射器接口类型的对象) 都交给Spring管理

1、 pom添加依赖

 <properties>
   <spring.version>5.3.10</spring.version>
   <mybatis.version>3.5.7</mybatis.version>
   <mybatis-spring.version>2.0.6</mybatis-spring.version>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <maven.compiler.source>8</maven.compiler.source>
   <maven.compiler.target>8</maven.compiler.target>
 </properties>
 <dependencies>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>6.1.0</version>
        </dependency>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.13.2</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-beans</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-expression</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-aop</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
   <dependency>
     <groupId>aopalliance</groupId>
     <artifactId>aopalliance</artifactId>
     <version>1.0</version>
   </dependency>
 
   <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-aspects</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-tx</artifactId>
     <version>${spring.version}</version>
   </dependency>
   <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>${mybatis.version}</version>
   </dependency>
   <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis-spring</artifactId>
     <version>${mybatis-spring.version}</version>
   </dependency>
   <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
     <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>druid</artifactId>
       <version>1.2.6</version>
     </dependency>
   <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.29</version>
   </dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
     <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.24</version>
       <scope>provided</scope>
     </dependency>
 <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
     <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.24</version>
       <scope>provided</scope>
     </dependency>
 </dependencies>

2、通过MybatisX生成实体类的相关信息

首先生成这些相关信息,方便配置spring-config.xml文件相关内容

实体类:

@Data:作用于类上,是以下注解的集合:@ToString @EqualsAndHashCode @Getter @Setter @RequiredArgsConstructor

注意要使用lombok,需要先安装插件,然后导入如下依赖才可以使用@Data注解

 package com.woniuxy.ssm.entity;
 
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
 
 /**
  *
  * @TableName user
  */
 @Data
 public class User implements Serializable {

     private Integer id;
     private String userName;
     private String password;
     private Integer age;
     private Date createDate;
     private String headImg;
     private Integer deptId;
     private static final long serialVersionUID = 1L;
 }

Mapper接口:

 package com.woniuxy.ssm.mapper;
 import com.woniuxy.ssm.entity.User;
 import java.util.List;
 
 public interface UserMapper {
     List<User> queryAll();
 }

映射文件:

 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.woniuxy.ssm.mapper.UserMapper">
     <select id="queryAll" resultType="User">
         select * from user
     </select>
 </mapper>

3、关键配置

Spring整合mybatis时,要把数据源的生成,以及SqlSession的生成都通过Spring依赖注入的方式来实现,涉及到如下配置

  • 配置DataSource数据源
  • 配置SqlSessionFactoryBean
  • 编写测试类测试运行结果

3.1 配置DataSource数据源

在resources目录下创建添加jdbc.properties文件,内容如下

属性文件的key不能直接为username和password,可能会出现得不到值的情况

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456

在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/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    <!--加载jdbc.properties中配置信息-->
    <context:property-placeholder location="classpath:config.properties"/>
    <bean id="dataSource" destroy-method="close" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

注意<context标签的引入方式,可以通过官网搜索到相应的头部信息

此处使用的是阿里的连接池

3.2 配置SqlSessionFactoryBean

拷贝过来直接使用

通过mybatis-spring中提供的SqlSessionFactoryBean来实现对SqlSessionFactory的创建,确保pom.xml文件中添加起步依赖

<!--配置SqlSessionFactoryBean,SqlSessionFactoryBean会根据数据源创建sqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置实体类所处的包为别名包,多个包之间用逗号隔开-->
        <property name="typeAliasesPackage" value="com.woniuxy.hrms.entity"/>
        <!--配置映射文件的路径-->
        <property name="mapperLocations" value="mapper/*"/>
        <!--配置实mybatis其他的相关配置-->
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <!--配置SQL日志的打印,懒加载的配置-->
                <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
                <property name="cacheEnabled" value="true"/>
                <property name="lazyLoadingEnabled" value="true"/>
            </bean>
        </property>
        <!--配置pagehelper插件-->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor"/>
            </array>
        </property>
        <!--如果想加载mybatis-config的主配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>

    </bean>

mybatis交给spring管理之后 ,不再需要mybatis-config.xml文件

typeAliasesPackage中value属性可以有多个值,多个值之间用逗号隔开

4、Mapper接口实现类

注意:需要给sqlSessionFactory添加set方法,通过设置注入方式来实现注入

Mybatis默认是手动提交事务的

JDBC默认是自动提交事务的

当Spring整合Mybatis时,事务默认是自动提交的

 package com.woniuxy.ssm.mapper.impl;
 
 import com.woniuxy.ssm.entity.User;
 import com.woniuxy.ssm.mapper.UserMapper;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
 
 import java.util.List;
 
 public class UserMapperImpl implements UserMapper {
     //需要spring注入进来sqlSessionFactory
     private SqlSessionFactory sqlSessionFactory;
 
     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
         this.sqlSessionFactory = sqlSessionFactory;
     }
 
     @Override
     public List<User> queryAll() {
         List<User> list;
         try(SqlSession sqlSession = sqlSessionFactory.openSession()){
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            list = UserMapper.queryAll();
         }
         return list;
     }
 }

https://mybatis.org/mybatis-3/zh/getting-started.html中有相关内容

try括号中可以写多行语句,会自动关闭括号中的资源

带参数的try(){}语法含义

最简形式为

 try(Resource res = xxx)//可指定多个资源
 {
 work with res
 }

try块退出时,会自动调用res.close()方法,关闭资源。

需要注意的是

try()的括号中可以写多行声明,每个声明的变量类型都必须是Closeable的子类,用分号隔开。

5、Service层代码

Service接口:

 package com.woniuxy.ssm.service;
 import com.woniuxy.ssm.entity.User;
 import java.util.List;
 
 public interface UserService {
     List<User> queryAll();
 }
 

Service实现类:

注意:给userMapper添加set方法,通过设置注入的方式注入

 package com.woniuxy.ssm.service.impl;
 
 import com.woniuxy.ssm.entity.User;
 import com.woniuxy.ssm.mapper.UserMapper;
 import com.woniuxy.ssm.service.UserService;
 
 import java.util.List;
 
 public class UserServiceImpl implements UserService {
     //需要spring注入进来
     private UserMapper userMapper;
 
     public void setUserMapper(UserMapper userMapper) {
         this.userMapper = userMapper;
     }
     @Override
     public List<User> queryAll() {
         return userMapper.queryAll();
     }
 }

6、完善spring-config.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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--加载配置文件信息-->
    <context:property-placeholder location="classpath:config.properties"/>
    <!--    配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.woniuxy.entity"/>
        <property name="mapperLocations" value="mapper/*"/>
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
            </bean>
        </property>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor"/>
            </array>
        </property>

    </bean>
    <bean id="employeeMapper" class="com.woniuxy.mapper.impl.EmployeeMapperImpl">
        <property name="sqlSessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="employeeService" class="com.woniuxy.service.impl.EmployeeServiceImpl">
        <property name="employeeMapper" ref="employeeMapper"/>
    </bean>
</beans>

7、测试

 public class SSMApplication {
     public static void main(String[] args) {
         ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
         UserService UserService = ac.getBean("userService", UserService.class);
         List<User> list = UserService.queryAll();
         for (User user:list) {
             System.out.println(user);
         }
     }
 }

二、Druid连接池介绍及使用(扩展)

/ˈdruːɪd/

1、连接池的定义

什么叫连接池?顾名思义,连接池就是将应用所需的连接对象放在池中,每次访问时从池中获取,使用完毕再放回池中,以达到连接复用的目的。连接池和线程池很像,都是为了减少连接对象在创建、销毁连接过程中不必要消耗的资源

大家接触最多的连接池、大概是数据库连接或者tomcat连接池,C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等。这些连接池的目的都非常的纯粹,即在服务启动的时候,预先生成若干条连接,每当有请求过来,就从中取出一个,执行操作,执行完成后再放回,从而避免反复的建立和销毁连接,以提升性能

2、主流数据库连接池

常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等

名称 介绍
C3p0 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右
DBCP (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统
Tomcat Jdbc Pool Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入了新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超级简单核心文件只有8个,支持JMX,支持XA Connection
BoneCP 官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右
Druid Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上

3、Druid连接池介绍及使用

Druid是Java语言中最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过生产环境大规模部署的严苛考验。

Druid连接池为监控而生,内置强大的监控功能,监控特性不影响整体性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为

4、配置Druid连接池

 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
     <!-- jdbc_url是MySQL的连接地址URL。-->
     <property name="url" value="${jdbc_url}" />

     <!-- jdbc_user是MySQL中的用户账号:高权限账号或者普通账号。 -->
     <property name="username" value="${jdbc_user}" />

     <!-- jdbc_password是 MySQL用户账号对应的密码。 -->
     <property name="password" value="${jdbc_password}" />

     <!-- 配置初始化连接池大小、最小连接数、最大连接数。 -->
     <property name="initialSize" value="5" />
     <property name="minIdle" value="10" />
     <property name="maxActive" value="20" />

     <!-- 配置获取连接等待超时的时间。 -->
     <property name="maxWait" value="60000" />

     <!-- 配置一个连接在连接池中的最小生存时间、最大生存时间,超过最大生存时间会被移除,单位毫秒。 -->
     <property name="minEvictableIdleTimeMillis" value="600000" />
     <property name="maxEvictableIdleTimeMillis" value="900000" />

     <!-- 配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位毫秒。 默认是60s,太长可能会导致无法及时检测到连接中断。  -->
     <property name="timeBetweenEvictionRunsMillis" value="2000" />

     <!-- 配置从连接池获取连接时,当连接空闲时间大于timeBetweenEvictionRunsMillis时是否检查连接有效性,true每次都检查;false不检查。 -->
     <property name="testWhileIdle" value="true" />

     <!-- 配置从连接池获取连接时和向连接池归还连接时,是否检查连接有效性。  -->
     <!-- 每次获取或归还连接都检测太频繁,除非特别重要或网络特别不可靠等情况,建议用testWhileIdle + timeBetweenEvictionRunsMillis代替。  -->
     <property name="testOnBorrow" value="false" />
     <property name="testOnReturn" value="false" />

     <!-- 配置是否定期探活、探活间隔。 -->
     <property name="keepAlive" value="true" />
     <property name="keepAliveBetweenTimeMillis" value="3000" />  <!-- 默认120s。 -->

     <!-- 探活、验证链接有效性的查询,新版本默认使用mysqlPing代替。 -->
     <property name="validationQuery"  value="select 1" />

     <!-- 配置监控统计拦截的filters。 -->
     <property name="filters" value="stat" />
 </bean>
posted @ 2025-04-21 17:39  icui4cu  阅读(39)  评论(0)    收藏  举报