【SSM -MyBatis篇02】MyBatis与Spring整合,实现增删查改

MyBatis与Spring整合

  通过与Spring的整合,MyBatis的SessionFactory交由Spring来构建。构建时需要在Spring的配置文件中添加数据库连接的四大属性来配置数据源。
  在单独使用mybatis的情况下,我们通常是通过SqlSessionFactory创建SqlSession,然后通过SqlSession来进行增删查改操作,mybatis整合spring之后,只需要在配置文件中配置sqlSessionFactory,然后使用的时候加载配置文件ApplicationContext,然后直接通过它的getBean()获取bean实例就行。

  SqlSessionFactory是mybatis的核心,当与spring进行整合时,我们使用mybatis-spring提供的SqlSessionFactoryBean 来创建其实例(SqlSessionFactory),SqlSessionFactoryBean实现了FactoryBean 接口。SqlSessionFactoryBean的配置有2种风格:

MyBatis与Spring整合步骤

  1. 导入相关jar包(maven导入依赖)

  2. 在Spring中配置MyBatis工厂

<!-- 在Spring配置文件中 配置数据源 -->
<bean	id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
	<property name="url" value="jdbc:mysql://localhost:3306/springtest?characterEncoding=utf8" />
	<property name="username" value="root" />
	<property name="password" value="123456" />
</bean>

<!-- 配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合 -->  
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
      <property name="dataSource" ref="dataSource" />  
	 <!-- configLocation的属性值为MyBatis的核心配置文件 -->
	 <property	name="configLocation" value="classpath:com/mybatis/mybatis-config.xml"/>
 </bean>

  1. 使用Spring管理MyBatis的数据操作接口
      使用Spring管理MyBatis的数据操作接口的方式有多种。其中,最常用最简洁的一种是基于MapperScannerConfigurer的整合。该方式需要在Spring的配置文件中加入以下内容:
<!--Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配
 	(Spring将指定包中所有被@Mapper注解标注的接口自动装配为MyBatis的映射接口)  --> 
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
     <!-- mybatis-spring组件的扫描器。com.dao只需要接口(接口方法与SQL映射文件中相同)-->
     <property name="basePackage" value="com.dao"/>
     <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
 </bean>


案例实现(spring-mybatis整合对Student学生进行增删查改)

1. 创建javabean 学生类Student

//创建学生类
public class Student {
    
    
    private Integer stuId;       //学生id
    private String stuName;     //学生名
    private String stuClass;    //学生班级
    private float  stuScore;    //学生成绩
	//省略getter/setter、toString方法
}

2. 创建接口StudentMapper

@Repository
public interface StudentMapper {
    
    
//    只要建立接口,具体实现由spring执行(动态代理)

    //通过id获取学生
//    com.xgf.mybatis_spring.dao.StudentMapper.getStudentById完全限定名来找sql语句
    public Student getStudentById(String stuId);

    //增加学生
    public boolean addStudent(Student user);

    //通过查询学生
    public List<Student> getAllStudent();

    //更新学生信息  - 通过student对象的stuId来更新
    boolean updateStudent(Student student);

    //通过id删除学生
    boolean deleteStudent(String stuId);

    //将student的属性名和值封装成map对象  Map<stuid,123>
    List<Map<String, Object>> listStudentMap();
}

3. 创建jdbc连接的属性文件db.properties

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8
jdbc.username = root
jdbc.password = 123456

4. 配置Spring核心配置文件,由Spring管理MyBatis

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:context="http://www.springframework.org/schema/context"
       xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:tx="http://www.springframework.org/schema/tx"
       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.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--1. 引入jdbc的属性文件,在配置中通过占位使用 -->
    <context:property-placeholder location="classpath*:db.properties" />

    <!--2. <context:component-scan>扫描包中注解所标注的类(@Component、@Service、@Controller、@Repository) -->
    <context:component-scan base-package="com.xgf.mybatis_spring"/>

    <!--3. 由spring管理    配置数据源数据库连接(从jdbc属性文件中读取参数) -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
    </bean>

    <!--
        配置mybatis
        创建sqlsessionFactory 管理连接池
        sqlSessionFactory sqlSesion工厂  每个sqlSession  对应一个  Connection
        所有的数据库的增删查改通过sqlSession来完成
        通过connection.preparedStatment() ; 获取结果集ResultSet
    -->
    <!--4. 通过完全限定名匹配查找  创建SqlSessionFactoryBean  -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <!-- 如果完全限定名com.xgf.mybatis_spring.dao与实际名不相同,通过以下配置可以解决找不到问题 -->
        <!-- 如果dao包下面还有目录 value="com/xgf/mybatis_spring/dao/**/*.xml"  -->

        <!--
        &lt;!&ndash;配置要加载的xml,可以指定在某个路径下&ndash;&gt;
        <property name="mapperLocations" value="com/xgf/mybatis_spring/dao/*.xml"/>
        &lt;!&ndash; 配置mybtais中的所有属性 &ndash;&gt;
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true"/>
            </bean>
        </property>-->
    </bean>

    <!-- 5. mybatis提供的一个注解扫描标签(搜索映射器 Mapper 接口),通过自动扫描注解的机制,创建每个dao接口定义的bean  -->
    <mybatis:scan base-package="com.xgf.mybatis_spring.dao"/>

    <!-- 6. 配置事务管理器 完成手动事务管理  由spring管理事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--
        支持注解驱动的事务管理,指定事务管理器。
        配置事务 提供回滚,发生异常数据回滚  需要在类/方法上写注解 @Transactional -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

5. 编写测试类,测试增删查改功能

//测试类 测试spring-mybatis整合 进行增删查改
public class TestStudent {
    
    

    private static ApplicationContext applicationContext = null;
    private static StudentMapper studentMapper = null;

    //静态代码块 只加载一次
    static {
    
    
        //加载配置文件
        applicationContext = new ClassPathXmlApplicationContext("com/xgf/mybatis_spring/config/applicationContext.xml");
        //通过类获取bean的两种方式
        // 1.类名首字母小写
//        studentMapper = (StudentMapper) applicationContext.getBean("studentMapper");
        // 2.类.class
        studentMapper = (StudentMapper) applicationContext.getBean(StudentMapper.class);
    }

    //测试getStudentById()方法 通过id查询
    @Test
    public void test01(){
    
    
        System.out.println("===查找id为2017401300的student:===");
        Student std1 = studentMapper.getStudentById("2017401300");
        System.out.println(std1);
    }

    //测试添加
    @Test
    public void test02(){
    
    
        /*设置了user的id为自动增长所以不需要设置id*/
        Student addStd = new Student(null,"save student","测试student添加",98);
        boolean flag = studentMapper.addStudent(addStd);
        System.out.println("是否添加成功:" + flag);
    }

    //测试查询所有student信息,通过三种遍历list方式输出
    @Test
    public void test03(){
    
    
        //3种遍历list输出方法
//      3.1、for循环遍历
        System.out.println("    ===查找所有student对象===");
        List<Student> studentList = studentMapper.getAllStudent();

        for (Student student : studentList) {
    
    
            System.out.println(student);
        }

//      3.2、通过流stream方式遍历
        System.out.println("\n   ===通过流stream方式遍历-->输出student对象集合===   ");
        //@FunctionalInterface 函数式接口
        studentList.stream().forEach(new Consumer<Student>(){
    
    
            //接收对象 对Student对象的处理
            @Override
            public void accept(Student student) {
    
    
                System.out.println(student);
            }
        });

//      3.3、通过函数式接口方式遍历  函数式接口只有一个方法被调用
        //  (函数式接口方法声明)->{方法代码}
        System.out.println("\n   ===函数式接口方法遍历输出  ===   ");
        studentList.stream().forEach(student->{
    
    
            System.out.println(student);
        });

    }

    //更新student--通过student对象的stuId来更新
    @Test
    public void test04(){
    
    
        System.out.println("   === 假设更新id为2020211236  ===");
        Student updateStudent = studentMapper.getStudentById("2020211236");
        System.out.println("更新前: " + updateStudent);

        boolean flag = studentMapper.updateStudent(new Student(2020211236,"更新studentName","2020软件1班",96));
        if(flag == true){
    
    
            System.out.println("更新后:" + studentMapper.getStudentById("2020211236"));
        }else {
    
    
            System.out.println("更新失败,学生id不存在");
        }

    }

    //测试删除
    @Test
    public void test05(){
    
    
        boolean flag = studentMapper.deleteStudent("2020211240");
        if(flag){
    
    
            System.out.println("删除成功");
        }else{
    
    
            System.out.println("删除失败,指定id的学生不存在");
        }

    }

    //测试将student的属性名和值封装成map键值对的形式输出
    @Test
    public void test06(){
    
    

//     返回Map  每一个Map中,key=user对象的属性名,value=user对象的属性值,一个Map封装了一个user对象
        List<Map<String,Object>> listStudentMap = studentMapper.listStudentMap();

        System.out.println(listStudentMap);

//      1、普通for循环方式输出map
        for(Map<String,Object> map: listStudentMap){
    
    
//            循环map输出Entry
            for(Map.Entry<String,Object> entry: map.entrySet()){
    
    
                String key = entry.getKey();
                Object value = entry.getValue();
                System.out.println("key : "+key+"\t value : "+value);
            }
        }

//      2、函数式接口 输出map
        listStudentMap.stream().forEach((Map<String, Object> userMap)->{
    
    
//            循环输出map的key和value
            userMap.forEach((String key, Object value)->{
    
    
                System.out.println(key+" : "+value);
            });
        });
    }

}

猜你喜欢

转载自blog.csdn.net/qq_40542534/article/details/108795227
今日推荐