10. 整合 Mybatis

空~2022年9月6日
  • Spring
大约 6 分钟

10. 整合 Mybatis

把 mybatis 框架和 spring 集成在一起,向一个框架一样使用

用的技术是: ioc

为什么 ioc 能把 mybatis 和 spring 集成在一起,像一个框架; 是因为 ioc 能创建对象

可以把 mybatis 框架中的对象交给 spring 统一创建, 开发人员从 spring 中获取对象

开发人员就不用同时面对两个或多个框架了, 就面对一个 spring

步骤:

  1. 新建 maven 项目

  2. 加入 maven 的依赖

    1. spring 依赖
    2. mybatis 依赖
    3. mysql 驱动
    4. spring 的事务的依赖
    5. mybatis 和 spring 集成的依赖: mybatis 官方体用的,用来在 spring 项目中创建 mybatis 的 SqlSesissonFactory,dao 对象的
  3. 创建实体类

  4. 创建 dao 接口和 mapper 文件

  5. 创建 mybatis 主配置文件

  6. 创建 Service 接口和实现类,属性是 dao

  7. 创建 spring 的配置文件: 声明 mybatis 的对象交给 spring 创建

    1. 数据源 DataSource
    2. SqlSessionFactory
    3. Dao 对象
    4. 声明自定义的 service
  8. 创建测试类,获取 Service 对象,通过 service 调用 dao 完成数据库的访问

1. 回忆 Mybatis

  1. 编写实体类

    @Data
    public class User {
        private String name;
        private int id;
        private String pwd;
    }
    
  2. 编写核心配置文件

    <?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>
    <typeAliases>
        <package name="com.demo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com/demo/dao"/>
    </mappers>
    </configuration>
    
  3. 编写 dao 接口

    public interface UserMapper {
        User getUserById(int id);
    }
    
  4. 编写 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.demo.dao.UserMapper">
    <select id="getUserById" resultType="user">
        select *
        from mybatis.user
        where id = #{id}
    </select>
    </mapper>
    
  5. maven 静态资源过滤问题

    <build>
    <resources>
        <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
        </resource>
        <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
        </resource>
    </resources>
    </build>
    
  6. 工具类

    public class MybatisUtils {
        private static SqlSessionFactory sqlSessionFactory;
    
        static {
            try {
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSession getSession() {
            return sqlSessionFactory.openSession(true);
        }
    }
    
  7. 测试

    @Test
    public void Test() {
        SqlSession session = MybatisUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User userById = mapper.getUserById(1);
        System.out.println(userById);
        session.close();
    }
    

2. 整合 Mybatis 的方式一

  1. 编写数据源配置

    <bean id="dataScore" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    
  2. sqlSessionFactory

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataScore"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/demo/dao/*.xml"/>
    </bean>
    
  3. sqlSessionTemplate

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    
  4. 给接口加实现类

    public class UserMapperImpl implements UserMapper {
        /** 原来的SqlSession 现在的SqlSessionTemplate */
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public User getUserById(int id) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.getUserById(id);
        }
    }
    
  5. 将自己写的实现类,注入到 spring

    <bean id="userMapper" class="com.demo.dao.UserMapperImpl">
    <property name="sqlSession" ref="sqlSession"/>
    </bean>
    
  6. 测试

    @Test
    public void Test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        User userById = userMapper.getUserById(1);
        System.out.println(userById);
    }
    

2. 整合 Mybatis 的方式二

  1. 不需要 sqlSessionTemplate

    <?xml version="1.0" encoding="UTF8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--DataScore:使用Spring的数据源替换Mybatis的配置-->
    <bean id="dataScore" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataScore"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/demo/dao/*.xml"/>
    </bean>
    </beans>
    
  2. 修改接口的实现类

    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
    
        @Override
        public User getUserById(int id) {
            UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
            return mapper.getUserById(id);
        }
    }
    

3. 整合 Mybatis 的方式三

使用 druid 连接池

  1. 编写实体类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
        private Integer id;
        private String name;
        private String email;
        private Integer age;
    }
    
  2. 编写 dao 层

    public interface StudentDao {
        /**
         * 插入
         *
         * @param student 学生
         * @return 受影响的行
         */
        int insertStudent(Student student);
    
        /**
         * 查询全部
         *
         * @return 全部
         */
        List<Student> selectStudents();
    }
    
    <?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="demo.dao.StudentDao">
    <insert id="insertStudent">
        insert into mybatis.student
        values (#{name}, #{email}, #{age});
    </insert>
    <select id="selectStudents" resultType="demo.domain.Student">
        select *
        from mybatis.student;
    </select>
    </mapper>
    
  3. 编写 service 层

    public interface StudentService {
        /**
         * 插入
         *
         * @param student 学生
         * @return 受影响的行
         */
        int addStudent(Student student);
    
        /**
         * 查询全部
         *
         * @return 全部
         */
        List<Student> queryStudents();
    }
    
    public class StudentServiceImpl implements StudentService {
        private StudentDao studentDao;
    
        public void setStudentDao(StudentDao studentDao) {
            this.studentDao = studentDao;
        }
    
        @Override
        public int addStudent(Student student) {
            return studentDao.insertStudent(student);
        }
    
        @Override
        public List<Student> queryStudents() {
            return studentDao.selectStudents();
        }
    }
    
  4. jdbc.properties 数据库配置信息

    jdbc.url=jdbc:mysql://localhost:3306/mybatis
    jdbc.username=root
    jdbc.password=root
    
  5. mybatis-config.xml 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: 控制mybatis全局行为-->
    <settings>
        <!--设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--设置别名-->
    <typeAliases>
        <!--
                name:实体类所在的包名
                表示com.bjpowernode.domain包中的列名就是别名
                你可以使用Student表示com.bjpowenrode.domain.Student
            -->
        <package name="demo.domain"/>
    </typeAliases>
    <!-- sql mapper(sql映射文件)的位置-->
    <mappers>
        <!--name: 是包名, 这个包中的所有mapper.xml一次都能加载-->
        <package name="demo.dao"/>
    </mappers>
    </configuration>
    
  6. applicationContext.xml spring 配置信息

    <?xml version="1.0" encoding="UTF8"?>
    <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">
     <!--
            把数据库的配置信息,写在一个独立的文件,便于修改数据库的配置内容
            spring需要知道jdbc.properties文件的位置
     -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--声明数据源DataSource, 作用是连接数据库的-->
    <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--set注入给DruidDataSource提供连接数据库信息 -->
        <!--使用属性配置文件中的数据,语法 ${key} -->
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
     <!--
            声明的是mybatis中提供的SqlSessionFactoryBean类,
            这个类内部创建SqlSessionFactory的
            SqlSessionFactory sqlSessionFactory = new ..
     -->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--set注入,把数据库连接池付给了dataSource属性-->
        <property name="dataSource" ref="druid"/>
        <!--
                mybatis主配置文件的位置
                configLocation属性是Resource类型,读取配置文件
                它的赋值,使用value,指定文件的路径,使用classpath:表示文件的位置
            -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
     <!--
            创建dao对象,使用SqlSession的getMapper(StudentDao.class)
            MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象
     -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定SqlSessionFactory对象的id-->
        <property name="sqlSessionFactoryBeanName" value="factory"/>
        <!--
                指定包名, 包名是dao接口所在的包名
                MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
                一次getMapper()方法,得到每个接口的dao对象
                创建好的dao对象放入到spring的容器中的 dao对象的默认名称是 接口名首字母小写
            -->
        <property name="basePackage" value="demo.dao"/>
    </bean>
    <!--声明service-->
    <bean id="setStudentService" class="demo.service.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>
    </beans>
    
  7. 测试

    public class MyTest {
        @Test
        public void MyTest() {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            StudentService setStudentService = context.getBean("setStudentService", StudentService.class);
            List<Student> studentList = setStudentService.queryStudents();
            for (Student student : studentList) {
                System.out.println(student);
            }
        }
    }
    
  8. 结果

    整合