Mybatis整合Spring的原理以及整合一个案例

目录

一.Mybatis整合Spring的好处

注册会话工厂(SqlSessionFactory),不用手动创建

自动创建线程安全的会话,自动获取mapper接口的代理类并放入spring容器

二.依赖、配置与实现

1.加入相关依赖

2.编写配置文件

3.代码流程

总结:


一.Mybatis整合Spring的好处

Mybatis整合Spring给我们带来的好处

  • Spring可以帮我们管理对象
  • 简化方法的调用

Mybatis利用Spring的扩展点,把自己与Spring进行了整合

注册会话工厂(SqlSessionFactory),不用手动创建

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--        配置主配置文件地址-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--        注册mapper.xml-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

原理:

org.mybatis.spring.SqlSessionFactoryBean这个类实现了FactoryBean、InitializingBean、ApplicationListener

熟悉Spring流程的应该知道FactoryBean是Spring注册bean的一种特殊的方式,他的getObject方法可以自定义的创建对象,他会解析我们的Mybitis的配置文件,最终把SqlSessionFactoryBean注册到Spring的容器,然后我们getbean(SqlSessionFactoryBean)的时候就可以得到SqlSessionFactory对象

自动创建线程安全的会话,自动获取mapper接口的代理类并放入spring容器

DefaultSqlSession是线程不安全的,所以我们并不可以直接用DefaultSqlSession。
SqlSessionTemplete 是他的替代品,他采用jdk动态代理 每次创建一个新的DefSqlSession
 

<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!--指定包名, 包名是mapper接口所在的包名。
     MapperscannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
     一次getMapper()方法 ,得到每个接口的代理对象。
     创建好的代理对象放入到spring的容器中的。-->
    <property name="basePackage" value="com.ws.mapper"/>
</bean>

原理:

org.mybatis.spring.mapper.MapperScannerConfigurer这个类实现了BeanDefinitionRegistryPostProcessor接口,他也是注册bean的一种方式,实现他的方法可以直接

注册beanDifinition.他会扫描我们注册的mapper接口,把扫描到的接口name注册成beanDefinition的beanNamesetBeanClass时,他传入了 MapperFactoryBean对象MapperFactoryBean是又实现了FactoryBean的类,他的getObject方法就是获取SqlSession,调用getMapper方法,所以Mybatis会帮他动态代理生成mapper接口的代理对象。

所以就不用我们手动的创建SqlSession,也不用手动调用getMapper.

他会先获取SqlSessionTemplete

二.依赖、配置与实现

1.加入相关依赖

<dependencies>
    <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.2.8.RELEASE</version>
    </dependency>

<!--    Mybitis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
<!--    mybitis整合spring-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.6</version>
    </dependency>

    <!-- 做事务依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

<!--    jdbc依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>

    <!--druid数据源依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.22</version>
    </dependency>

    <!--lombok依赖 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.16</version>
    </dependency>

    <!--Mysql驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.11</version>
    </dependency>

  </dependencies>

2.编写配置文件

spring主配置文件

<?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">

    <!--声明jdbc属性文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--声明数据源Datasource,作用是连接数据库 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxActive" value="20"/>

    </bean>

    <!--声明的是mybatis中提供的SqlSessionFactoryBean类 ,这个类内部创建SqlSessionFactory的 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--        配置主配置文件地址-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--        注册mapper.xml-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象。-->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--指定包名, 包名是mapper接口所在的包名。
         MapperscannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
         一次getMapper()方法 ,得到每个接口的代理对象。
         创建好的代理对象放入到spring的容器中的。-->
        <property name="basePackage" value="com.ws.mapper"/>
    </bean>

    <context:component-scan base-package="com.ws.service"/>



</beans>

Mybatis配置文件

<?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>

    <settings>
        <!-- 打印查询语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />

        <setting name="localCacheScope" value="SESSION"/>

        <!-- 控制全局缓存(二级缓存),默认 true-->
        <setting name="cacheEnabled" value="true"/>

        <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false  -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
        <setting name="aggressiveLazyLoading" value="true"/>
        <!--  Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
        <!--<setting name="proxyFactory" value="CGLIB" />-->

    </settings>

    <typeAliases>
        <typeAlias alias="student" type="com.ws.vo.Student" />
    </typeAliases>


    <!--配置插件-->
<!--    <plugins>-->
<!--        <plugin interceptor="com.github.pagehelper.PageInterceptor">-->
<!--        </plugin>-->
<!--    </plugins>-->

    <mappers>
        <!--一个mapper标签指定 一个文件的位置。
           从类路径开始的路径信息。target/clasess(类路径 )
          -->
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>



</configuration>

3.代码流程

实体类

@Data
public class Student implements Serializable {
    private Integer id;

    private String name;

    private Integer age;

    private Integer clazzNo;

    public Student(Integer id, String name, Integer age, Integer clazzNo) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.clazzNo = clazzNo;
    }

}

mapper接口

public interface StudentMapper {
    /**
     * 查询所有学生信息
     * @return
     */
//    List<Student> queryAllStudents(RowBounds rowBounds);
    List<Student> queryAllStudents();

    /**
     * 根据ID查学生信息
     * @return
     */
    Student querySyudentById(Integer id);

    /**
     * 添加学生
     * @return
     */
    int addStudent(Student student);

    /**
     * 修改学生信息
     * @return
     */
    int updateStudentById(Student student);

    /**
     * 删除学生
     * @return
     */
    int deletStudentById(Integer id);

//    /**
//     * 查询学生和班级
//     * @return
//     */
//    StudentAndClazz queryStudentAndeClazzById(Integer id);

}

mapper.xml

<?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.ws.mapper.StudentMapper">

    <cache type="org.apache.ibatis.cache.impl.PerpetualCache"
           size="1024"
           eviction="LRU"
           flushInterval="120000"
           readOnly="false"/>

    <select id="queryAllStudents" resultType="com.ws.vo.Student">
        select id, name, age, clazz_no from student
    </select>

    <select id="querySyudentById" parameterType="int" resultType="student">
        select id, name, age, clazz_no from student where id=#{id}
    </select>

    <insert id="addStudent">
        insert into student (id,name,age,clazz_no)values (#{id},#{name},#{age},#{clazzNo})
    </insert>

    <update id="updateStudentById" parameterType="student">
        update  student set name=#{name}, age=#{age}, clazz_no=#{clazzNo} where id=#{id}
    </update>

    <delete id="deletStudentById" parameterType="int">
        delete from student where id = #{id}
    </delete>

    <!-- 根据clazz_no查询clazz信息,一对一查询的结果,嵌套查询 -->
<!--    <resultMap id="studentAndClazz" type="com.ws.vo.StudentAndClazz">-->
<!--        <id column="id" property="id" jdbcType="INTEGER"/>-->
<!--        <result column="name" property="name" jdbcType="VARCHAR"/>-->
<!--        <result column="age" property="age" jdbcType="INTEGER"/>-->
<!--        <result column="clazz_no" property="clazzNo" jdbcType="INTEGER"/>-->
<!--        <result column="clazz_name" property="clazzName"/>-->
<!--    </resultMap>-->

<!--    <select id="queryStudentAndeClazzById" parameterType="int" resultMap="studentAndClazz">-->
<!--        select s.id, s.name, s.age, s.clazz_no, c.clazz_name from student s join clazz c on s.clazz_no=c.id where s.id = #{id}-->
<!--    </select>-->

<!--    <select id="queryStudentAndeClazzById" parameterType="int" resultType="com.ws.vo.StudentAndClazz">-->
<!--        select s.id, s.name, s.age, s.clazz_no clazzNo, c.clazz_name clazzName from student s join clazz c on s.clazz_no=c.id where s.id = #{id}-->
<!--    </select>-->


</mapper>

Service

@Service
public class StudentService {
    @Autowired
    public StudentMapper studentMapper;

    public List<Student> queryAllStudents() {
        return studentMapper.queryAllStudents();
    }
}

Test

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        StudentService studentService = applicationContext.getBean(StudentService.class);
        List<Student> studentList = studentService.queryAllStudents();
        System.out.println(Arrays.toString(studentList.toArray())
                .replaceAll("\\[|\\]","")
                .replaceAll("\\)\\,","\\)\n"));
//        System.out.println(applicationContext.getBeanDefinitionNames());
    }
}

总结:

         Mybatis整合Spring实际上就是利用了Spring的扩展,所以我们要清楚Spring留给我们的钩子方法。一定要知道Spring注册bean的那几种方式。点击学习注册bean的方式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,以下是一个简单的Spring Boot整合MyBatis和Vue的案例: 1. 前端Vue部分 首先,我们创建一个Vue项目。在命令行中输入以下命令: ``` vue create vue-mybatis-demo ``` 接着,在`vue-mybatis-demo`目录下执行以下命令: ``` npm install axios --save ``` 这将安装`axios`,一个用于发送HTTP请求的JavaScript库。 接下来,我们在`src`目录下创建一个`components`目录,并在其中创建一个`UserList.vue`组件。在该组件中,我们将使用`axios`从后端获取用户列表。以下是`UserList.vue`组件的代码: ```html <template> <div> <h2>User List</h2> <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr v-for="user in users" :key="user.id"> <td>{{ user.id }}</td> <td>{{ user.name }}</td> <td>{{ user.age }}</td> </tr> </tbody> </table> </div> </template> <script> import axios from 'axios'; export default { data() { return { users: [] } }, mounted() { axios.get('/api/users') .then(response => { this.users = response.data; }) .catch(error => { console.log(error); }); } } </script> ``` 2. 后端Spring Boot部分 我们使用Spring Boot创建一个RESTful API,用于从数据库中获取用户列表。首先,在`pom.xml`文件中添加以下依赖项: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies> ``` 然后,在`application.properties`文件中添加以下配置: ``` spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= mybatis.mapper-locations=classpath:mapper/*.xml ``` 接下来,我们创建一个`User`实体类: ```java public class User { private Long id; private String name; private Integer age; // getters and setters } ``` 然后,我们创建一个`UserMapper`接口和对应的XML文件,用于从数据库中获取用户列表: ```java @Mapper public interface UserMapper { @Select("SELECT * FROM user") List<User> findAll(); } ``` ```xml <mapper namespace="com.example.demo.mapper.UserMapper"> <select id="findAll" resultType="com.example.demo.entity.User"> SELECT * FROM user </select> </mapper> ``` 最后,我们创建一个`UserController`类,用于处理从前端发送的请求: ```java @RestController @RequestMapping("/api") public class UserController { @Autowired private UserMapper userMapper; @GetMapping("/users") public List<User> findAllUsers() { return userMapper.findAll(); } } ``` 3. 整合后端 现在,我们需要将前端Vue项目打包并将其静态文件放入Spring Boot项目的`resources/static`目录下。在`vue-mybatis-demo`目录下执行以下命令: ``` npm run build ``` 这将生成一个`dist`目录,其中包含前端Vue项目的静态文件。将该目录下的所有文件复制到Spring Boot项目的`resources/static`目录下。 最后,我们启动Spring Boot应用程序,并在浏览器中访问`http://localhost:8080`,即可看到从数据库中获取的用户列表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w7486

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值