首页 > 技术文章 > Spring集成Mybatis

changtong1819 2021-03-09 15:50 原文

Spring集成Mybatis

Mybatis的快速使用

使用Mybatis需要的maven坐标及插件

<dependencies>
     <dependency><!--mybatis-->
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>3.5.1</version>
    </dependency>
     <dependency><!--mysql-->
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.9</version>
     </dependency>
 </dependencies>
<build>
     <resources><!--使用配置文件时需要获取文件-->
         <resource>
             <directory>src/main/java</directory><!--所在的目录-->
             <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
             <include>**/*.properties</include>
             <include>**/*.xml</include>
             </includes>
             <filtering>false</filtering>
         </resource>
    </resources>
</build>

编写实体类及接口

在domain包中编写实体类

public class Student {
 //属性名和列名一样
 private Integer id;
 private String name;
 private String email;
 private Integer age;
 //以及get、set、toString
}

在dao包中编写接口

public interface StudentDao {//增删改查
    int deleteStudentById(int id);//删除
    int updateStudent(Student student);//更新
    int insertStudent(Student student);//插入
    Student selectStudentById (int id);//查询一个
    List<Student> selectAllStudents ();//查询多个
}

编写Dao接口的Mapper映射文件

要求:

  1. 在 dao 包中创建文件StudentDao.xml
  2. StudentDao.xml文件名称和接口StudentDao完全一样

Mapper文件模板:

<?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">
<!--
     namespace:必须有值,自定义的唯一字符串
     推荐使用:dao 接口的全限定名称
-->
<mapper namespace="top.changtong1819.dao.StudentDao">
     <!--
         <select>: 查询数据, 标签中必须是 select 语句
         id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
         使用名称表示要执行的 sql 语句
         resultType: 查询语句的返回结果数据类型,使用全限定类名
         根据需求,有insert、delete、update、select标签
     -->
     <select id="selectStudents" resultType="top.changtong1819.domain.Student">
         <!--要执行的 sql 语句-->
         select id,name,email,age from student
     </select>
</mapper>

看到这里,不禁要疑惑了,查询、插入等语句需要我们的sql语句里有变参怎么办?

我们可以使用占位符#{...}或者字符串替换${...},常用#

<select id="selectById" resultType="top.changtong1819.domain.Student">
     select id,name,email,age from student where id=#{studentId}
</select>

<select id="findById" resultType="top.changtong1819.domain.Student">
     select * from student where id=${studentId}
</select>

创建MyBatis主配置文件

在resources文件夹下创建主配置文件,名称为mybatis.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>
    
 <!--配置 mybatis 环境-->
 <environments default="mysql">
     <!--id:数据源的名称-->
     <environment id="mysql">
         <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
         <transactionManager type="JDBC"/>
             <!--数据源 dataSource:创建数据库 Connection 对象
             type: POOLED 使用数据库的连接池
             -->
             <dataSource type="POOLED">
                 <!--连接数据库的四个要素-->
                 <property name="driver" value="com.mysql.jdbc.Driver"/>
                 <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                 <property name="username" value="root"/>
                 <property name="password" value="123456"/>
             </dataSource>
     </environment>
 </environments>
 <mappers>
     <!--告诉 mybatis 要执行的 sql 语句的位置-->
     <mapper resource="top/changtong1819/dao/StudentDao.xml"/>
 </mappers>
</configuration>

通常情况下,大部代码是固定的,只需要修改数据库连接的信息、映射文件的位置就行了,后面我们使用Spring管理时由于要更换Druid数据库,因此模板更简洁,如下:

<?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="top.changtong1819.demo02.domain"/>
    </typeAliases>
    <mappers>
        <!-- 扫描包下的映射配置文件 -->
        <package name="top.changtong1819.demo02.dao"/>
    </mappers>
</configuration>

使用MyBatis来操作数据库

使用session来执行

@Test
public void testStart() throws IOException {
     //1.mybatis 主配置文件
     String config = "mybatis-config.xml";
     //2.读取配置文件
     InputStream in = Resources.getResourceAsStream(config);
     //3.创建 SqlSessionFactory 对象,目的是获取 SqlSession
     SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
     //4.获取 SqlSession,SqlSession 能执行 sql 语句
     SqlSession session = factory.openSession();
     //5.执行 SqlSession 的 selectList()
     List<Student> studentList = 
    session.selectList("top.changtong1819.dao.StudentDao.selectStudents");//全类名
     //6.循环输出查询结果
     studentList.forEach( student -> System.out.println(student));
     //7.关闭 SqlSession,释放资源
     session.close();
}

使用dao代理来执行(常用)

//只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao
//接口类的class
@Test
public void testStart() throws IOException {
     //1.mybatis 主配置文件
     String config = "mybatis-config.xml";
     //2.读取配置文件
     InputStream in = Resources.getResourceAsStream(config);
     //3.创建 SqlSessionFactory 对象,目的是获取 SqlSession
     SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
     //4.获取 SqlSession,SqlSession 能执行 sql 语句
     SqlSession session = factory.openSession();
     //5.获取代理对象
	 StudentDao dao = session.getMapper(StudentDao.class);
     //6.这个代理对象就像你自己写了完整的Impl类一样,可以执行类中的方法、传参
     //并且你不需要创建Dao接口的实现类
	 int nums1 = dao.insertStudent(student);
	 int nums2 = dao.updateStudent(student);
     //7.关闭 SqlSession,释放资源
     session.close();
}

Spring快速使用

使用Spring需要的坐标

<dependency> 
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId> 
    <version>5.2.5.RELEASE</version>
</dependency>

定义接口与实现类

public interface SomeService { 
    void doSome();
}
public class SomeServiceImpl implements SomeService {
    public SomeServiceImpl() { 
        super(); 
        System.out.println("SomeServiceImpl无参数构造方法");
	}
	@Override 
    public void doSome() { 
        System.out.println("====业务方法doSome()===");
	} 
}

创建Spring配置文件

在resources文件夹创建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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       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-4.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <bean class="">
        <property />
    </bean>
</beans>

使用Spring容器创建对象

public class Test {
	@org.junit.Test
    public void test(){
        String springResource = "applicationContext.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(springResource);
        StudentDao sd = (StudentDao) ac.getBean("studentDao");
    }
}

使用Spring集成MyBatis

需要的Maven坐标以及插件

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.32</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.9</version>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
          <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

定义实体类以及接口,mapper映射文件

Student

public class Student {
    int age;
    int id;
    String name;
    //get、set、toString
}

StudentDao

public interface StudentDao {
    int deleteStudentById(int id);
    int updateStudent(Student student);
    int insertStudent(Student student);
    Student selectStudentById (int id);
    List<Student> selectAllStudents ();
}

在定义完dao接口后就编写同名·mapper映射文件

<?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="top.changtong1819.demo02.dao.StudentDao">
    <insert id="insertStudent">
        insert into Student(name,age,id) values (#{name},#{age},#{id})
    </insert>
    <update id="updateStudent">
        update Student set name=#{name},age=#{age} where id=#{id}
    </update>
    <delete id="deleteStudentById">
        delete from Student where id=#{id}
    </delete>
    <select id="selectStudentById" resultType="Student">
        select name,age,id from Student where id=#{id}
    </select>
    <select id="selectAllStudents" resultType="Student">
        select name,age,id from Student order by id desc
    </select>
</mapper>

正常情况下我们还要定义Service接口及实现类来真正实现某功能,此处省略

定义MyBatis主配置文件与Spring配置文件

在 src 下定义 MyBatis 的主配置文件,命名为mybatis.xml。 这里有两点需要注意:

  • 主配置文件中不再需要数据源的配置了。因为数据源要交给 Spring 容器来管理了。

  • 这里对mapper 映射文件的注册,使用标签,即只需给出mapper映射文件所在的包即可。因为mapper的名称与 Dao 接口名相同,可以使用这种简单注册方式。这种方式的好处是若有多个映射文件,这里的配置也是不用改变的。当然,也可使用原来的 标签方式。

<?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="top.changtong1819.demo02.domain"/>
    </typeAliases>
    <mappers>
        <!-- 扫描包下的映射配置文件 -->
        <package name="top.changtong1819.demo02.dao"/>
    </mappers>
</configuration>

Spring配置文件

我们不使用MyBatis自带的连接池,使用了Druid连接池

所以先定义好Druid连接池的配置

<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.name}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

我们使用读取配置文件的方式来填写数据库信息,在连接池之前添加读取配置文件

<context:property-placeholder location="classpath:jdbc.properties"/>

注册SqlSessionFactory的Bean

<!-- 注册SqlSessionFactory的Bean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    <!-- 指定mybatis主配置文件位置 -->
        <property name="configLocation" value="classpath:mybaties.xml"/>
</bean>

定义Mapper扫描配置器

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!-- 指定其扫描Dao接口包 -->
        <property name="basePackage" value="top.changtong1819.demo02.dao"/>
</bean>

如果使用了Service接口,还可再注册Service,将Mybatis生成的studentDao注入

<bean id="myStudentService" class="top.changtong1819.service.StudentServiceImpl">
        <property name="studentDao" value="studentDao"/>
</bean>

完整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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       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-4.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:property-placeholder location="classpath:jdbc.properties"/>
    <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.name}"/>
    <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybaties.xml"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="top.changtong1819.demo02.dao"/>
    </bean>
</beans>

推荐阅读