发表于: 2020-11-04 14:34:41

1 1427


今天完成的事情:

Mybatis和Spring整合详解:

为什么需要整合

需要spring来管理数据源信息。

需要spring通过单例方式管理SqlSessionFactory,之前单独使用mybatis需要自己编写SqlSessionFactory代码,现在直接在xml文件中直接注入就行了

使用SqlSessionFactory创建SqlSession。(spring和mybatis整合自动完成)

持久层的mapper都需要由spring进行管理,spring和mybatis整合生成mapper代理对象。

编写两种方式:一种使用mapper代理,一种不使用mapper代理

先编写spring-config文件,首先加载db.properties文件,然后再加载数据源,配置连接池参数。之后设置SqlSessionFactory的bean,在其中需要注入两个参数,一个是SqlMapConfig.xml,另外一个是配置的数据源bean。再配置原始DAO接口,在spring中添加studentDAO的bean配置,将定义的SqlSessionFactory对象当作参数注入进去,这样StudentImpl继承SqlSessionDaoSupport类才会起作用。最后编写启用mapper代理模式bean,目的是指定要扫描的包和将SqlSessionFactory注入。


<?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
      http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!--    加载配置文件-->
   <context:property-placeholder  location="classpath:db.properties" />



<!--  数据源,使用DBCP  -->
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
         destroy-method="close">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
       <property name="maxActive" value="10"/>
       <property name="maxIdle" value="5"/>

   </bean>

<!--  sqlSessionFactory  -->
   <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--    加载MyBatis的配置文件    -->
       <property name="configLocation" value="SqlMapConfig.xml"/>
<!--     数据源   -->
       <property name="dataSource" ref="dataSource"/>
   </bean>

<!--  原始DAO接口  -->
   <bean id="studentDao" class="com.jnshu.Dao.StudentDaoImpl">
       <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
   </bean>

   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 指定扫描的包名
           如果扫描多个包,每个包中间使用半角逗号分隔 -->
       <property name="basePackage" value="com/jnshu/Mapper"/>
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
   </bean>

</beans>


下一步编写mybatis配置文件(SqlMapConfig.xml),设置一下缓存的参数。然后在typeAliases设置实体类的路径,最后在mapper配置中,设置加载mapper映射文件的路径,配置mapper代理借口所在的包名。这个在使用mapper代理后就会注释掉,因为spring有自己的mapper扫描器类,可直接在spring中设置。


缓存起因:有些时候查询数据频率很高,这是很耗费数据库资源的,而且会导致数据库查询效率低。解决方法:将一些变动不大且访问频率较高的数据,防止在一个缓存容器中(很像数据库连接池的概率,也是设置一个容器,存放连接,需要的时候就取出来),查询的时候就直接从这个容器中取出。

mybatis提供一级缓存和二级缓存。

简单了解一些缓存基本概念


配置Studentmapper.xml文件,用于配置SQL映射语句。然后再创建实体类。之后编写DAO层,在同一个文件夹下创建DAO层的实现类

注意查看StudentDaoImpl继承了SqlSessionDaoSupport类,查看SqlSessionDaoSupport类,发现下面有SqlSessionFactory方法和SqlSession方法,这样在StudentDaoImpl类中,就可以直接获取SqlSession对象,进行数据库的增删改查操作。

package com.jnshu.Dao;

import com.jnshu.Pojo.Student;

public interface StudentDao {

public Student findStudentById(int id) throws Exception;
}


package com.jnshu.Dao;

import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.jnshu.Pojo.Student;


public class StudentDaoImpl extends SqlSessionDaoSupport implements StudentDao {
public Student findStudentById(int id){
//继承SqlSessionDaoSupport类,通过this.getSqlSession()得到sqlSession
       SqlSession sqlSession = this.getSqlSession();
       Student student = sqlSession.selectOne("test.findStudentById",id);
       return student;
   }



}

编写测试类StudentServiceTest

运行逻辑:和mybatis是差不多的,就是把mybatis配置文件转成了Spring-config.xml配置文件,然后将SqlSessionFactory采用注入的方法注射到StudentDaoImpl类中,之后也是采用SqlSession对象,进行数据库的增删改查操作。

import com.jnshu.Dao.StudentDao;
import com.jnshu.Pojo.Student;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentServiceTest {
private ApplicationContext applicationContext;
   //在执行测试方法之前首先获取spring配置文件对象
   //注解@before在执行本类所有测试方法之前先调用这个方法
   @Before
   public void setup() throws Exception{
applicationContext = new ClassPathXmlApplicationContext("classpath:Spring-config.xml");

   }


@Test
   public void testFindStudentById() throws Exception {
//通过配置资源对象获取StudentDao对象
       StudentDao studentDao = (StudentDao) applicationContext.getBean("studentDao");
       //调用StudentDao
       Student student = studentDao.findStudentById(1);
       System.out.println(student.getId() + ":" + student.getName());
   }

}


使用mapper代理,不用编写实现类,因为mapper配置文件中的namespace直接和mapper接口绑定了:

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="com.jnshu.Mapper.StudentQueryMapper">
<!--  根据ID查询用户  -->
       <select id="findStudentById" parameterType="int" resultType="com.jnshu.Pojo.Student">
     SELECT * FROM Student WHERE id=#{id}
</select>

<!--  新增用户  -->
   <insert id="insertStudent" parameterType="com.jnshu.Pojo.Student">
       insert into Student(id,name,gender,birthday)
value (#{id},#{name},#{gender},#{birthday})
</insert>

<!--  删除用户  -->
   <delete id="deleteStudent" parameterType="java.lang.Integer">
       delete from Student where id=#{id}
</delete>

   <!-- 修改用户-->
   <update id="updateStudent" parameterType="com.jnshu.Pojo.Student">
       update student set name = #{name},gender = #{gender},birthday = #{birthday} where id = #{id}
</update>



</mapper>

mapper接口:

package com.jnshu.Mapper;

import com.jnshu.Pojo.Student;

public interface StudentQueryMapper {
//根据Id查询用户信息
   public Student findStudentById(int id) throws Exception;

   //添加用户
   public void insertStudent(Student student) throws Exception;

   //删除用户
   public void deleteStudent(int id) throws Exception;

   //修改用户
   public void updateStudent(Student student) throws Exception;
}

测试类:

运行逻辑和上面的基本没差

import com.jnshu.Mapper.StudentQueryMapper;
import com.jnshu.Pojo.Student;
import org.junit.Before;
import org.junit.Test;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.text.SimpleDateFormat;


public class StudentMapperTest {
private ApplicationContext applicationContext;

   //在执行测试方法之前首先获Spring配置文件对象
   //注解Before是在执行本类所有测试方法之前先调用这个方法
   @Before
   public void setup() throws Exception{
applicationContext = new ClassPathXmlApplicationContext("classpath:Spring-config.xml");
   }

//根据id查找用户
   @Test
   public void testFindStudentById() throws Exception{
//通过配置资源对象获取studentDao对象
       StudentQueryMapper studentQueryMapper = (StudentQueryMapper)applicationContext.getBean("studentQueryMapper");
       //调用studentDao的方法
       Student student=studentQueryMapper.findStudentById(1);
       //输出用户信息
       System.out.println(student.getId()+":"+student.getName());
   }

//添加用户
   @Test
   public void testInsertStudent() throws Exception{
//通过配置资源对象获取studentDao对象
       StudentQueryMapper studentQueryMapper = (StudentQueryMapper)applicationContext.getBean("studentQueryMapper");
       //调用studentDao的方法
       Student student = new Student();
       student.setName("任逍遥");
       student.setGender(1);
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
       student.setBirthday(sdf.parse("1995-08-15"));
       studentQueryMapper.insertStudent(student);
       //输出用户信息
       System.out.println(student.getId());
   }

//删除用户
   @Test
   public void deleteStudent() throws Exception{
//通过配置资源对象获取studentDao对象
       StudentQueryMapper studentQueryMapper = (StudentQueryMapper)applicationContext.getBean("studentQueryMapper");
       //调用studentDao的方法
       Student student = new Student();
       studentQueryMapper.deleteStudent(3);
       //输出用户信息
       System.out.println("删除" + student.getId() + "的数据");

   }

//更新用户
   @Test
   public void updateStudent() throws Exception{
//通过配置资源对象获取studentDao对象
       StudentQueryMapper studentQueryMapper = (StudentQueryMapper)applicationContext.getBean("studentQueryMapper");
       //调用studentDao的方法
       Student student = new Student();
       student.setId(1);
       student.setName("孙悟空");
       student.setGender(1);
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
       student.setBirthday(sdf.parse("2008-01-10"));
       studentQueryMapper.updateStudent(student);
       //输出用户信息
       System.out.println(student);
   }

}




明天计划的事情:

完成剩下的步骤


遇到的问题:

配置原始DAO接口,在spring中添加studentDAO的bean配置,将定义的SqlSessionFactory对象当作参数注入进去,这样StudentImpl继承SqlSessionDaoSupport类才会起作用。

不知道为什么这样才会起作用?

spring-config这个DAO接口注释,运行程序就会报错

org.springframework.beans.factory.No这样的Bean定义异常:没有名为'studentDao'的Bean


第二个问题:为什么接口SqlSessionFactory中有各种SqlSession方法,还需要另外编写接口?

我的解答,为了规范代码,且让我们自己编写一遍,才会知道源代码的意义。

一种编写mybatis的方法,没有另外编写接口.

另外一种编写mybatis的方式,有接口,且使用mapper代理



收获:

基本懂了Mybatis和Spring的运行逻辑



返回列表 返回列表
评论

    分享到