整合Spring-Mybatis

整合Mybatis

步骤

  1. 导入相关jar包
  • junit
  • mybatis
  • mysql数据库
  • spring相关知识
  • aop织入
  • mybatis-spring
    环境搭建:
    mybatis-spring这个依赖包对于spring和mybatis的版本是有要求的
    整合Spring-Mybatis
    导入pom文件依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <artifactId>Spring_Study</artifactId>
       <groupId>org.example</groupId>
       <version>1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>

   <artifactId>Spring_StudyMybatis08</artifactId>

   <dependencies>
       <!--单元测试-->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>
       <!--Spring-webmvc-->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>5.3.6</version>
       </dependency>
       <!--Mysql连接-->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.15</version>
       </dependency>
       <!--Mybatis-->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.4.5</version>
       </dependency>
       <!--SpringJDBC驱动-->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>5.2.4.RELEASE</version>
       </dependency>
       <!--mybatis-spring整合Mybatis和Spring-->
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis-spring</artifactId>
           <version>1.3.1</version>
       </dependency>
   </dependencies>
  <!--解决Mybatis静态资源输出问题-->
   <build>
       <resources>
           <resource>
               <directory>src/main/java</directory>
               <includes>
                   <include>**/*.xml</include>
               </includes>
               <filtering>true</filtering>
           </resource>
       </resources>
   </build>
</project>
  1. 编写配置文件
    mybatis-config.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>

    <!--创建别名-->
    <typeAliases>
        <package name="com.test.pojo"/>
    </typeAliases>

    <!--使用Spring管理-->
    <!--<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            &lt;!&ndash; 配置数据库连接信息 &ndash;&gt;
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://192.168.23.129:3306/BigData" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>-->

    <!--注册接口UserMapper.class-->
    <!--也可以使用Spring进行管理-->
    <!--<mappers>
        <mapper class="com.test.mapper.UserMapper"/>
    </mappers>-->
</configuration>

spring-mybatis.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--Datasource:使用Spring的数据源替换Mybatis的配置  c3p0 dbcp等
        这里使用Spring提供的JDBC:org.springframework.jdbc.datasource.DriverManagerDataSource
    -->

    <bean id="Datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://192.168.23.129:3306/BigData?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

    <!--SQLSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="Datasource"/>
        <!--绑定mybatis的配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--对mybatis中的mapper进行管理,mybatis-config.xml中就不用配置了-->
        <property name="mapperLocations" value="com/test/mapper/*.xml"/>
    </bean>

    <!--方式1-->
    <!--SqlSessionTemplate:就是我们使用的SQLSession(mybatis-spring内置的)-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能使用构造器注入,因为它没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

    <!--注入UserMapperImpl-->
<!--    <bean id="userMapperImpl" class="com.test.mapper.UserMapperImpl">-->
<!--        <property name="sqlsession" ref="sqlSession"/>-->
<!--    </bean>-->

    <!--方式2,相对方式1少了一步操作-->
    <bean id="userMapperImpl" class="com.test.mapper.UserMapperImpl">
        <!--这个参数是直接注入给UserMapperIml.clss的父类SQLSessionDaoSupport.class的-->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>
</beans>
  1. 测试
    User.class
package com.test.pojo;

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private String password;
}

UserMapper.class

package com.test.mapper;

import com.test.pojo.User;

import java.util.List;

public interface UserMapper {
    public List<User> selectUser();
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.UserMapper">
    <select id="selectUser" resultType="User">
        select * from user;
    </select>
</mapper>

初期整合spring和mybatis会多出一个实现类,后面将把他去掉
UserMapperImpl.class

package com.test.mapper;

import com.test.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{

    //方式1
//    private SqlSessionTemplate sqlsession;
//
//    public void setSqlsession(SqlSessionTemplate sqlsession) {
//        this.sqlsession = sqlsession;
//    }
//
//    public List<User> selectUser() {
//        UserMapper mapper = sqlsession.getMapper(UserMapper.class);
//        return mapper.selectUser();
//    }
    //方式2:需要继承一个类SqlSessionDaoSupport他可以直接getSQLSession,在spring.xml文件的配置中直接少了一步
    public List<User> selectUser() {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}

测试类:MyTest.class

import com.test.mapper.UserMapper;
import com.test.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyTest {
    @Test
    public void testselectUser() throws IOException {
        String mybatis = "mybatis-config.xml";
        InputStream resourceAsStream = Resources.getResourceAsStream(mybatis);
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession(true);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();
        for (User u:users) {
            System.out.println(u);
        }
    }

    @Test
    public void test2selectUser(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
        UserMapper userMapperImpl = context.getBean("userMapperImpl",UserMapper.class);
        List<User> users = userMapperImpl.selectUser();
        for (User user:users) {
            System.out.println(user);
        }
    }
}

回忆Mybatis

1.编写实体类

package com.test.pojo;

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private String password;
}

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.test.pojo"/>
    </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://192.168.23.129:3306/BigData" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>

    <!--注册接口UserMapper.class-->
    <mappers>
        <mapper class="com.test.mapper.UserMapper"/>
    </mappers>
</configuration>

3.编写接口

package com.test.mapper;

import com.test.pojo.User;

import java.util.List;

public interface UserMapper {
    public List<User> selectUser();
}

4.编写Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.UserMapper">
    <select id="selectUser" resultType="User">
        select * from user;
    </select>
</mapper>

5.测试

import com.test.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyTest {
    @Test
    public void testselectUser() throws IOException {
        String mybatis = "mybatis-config.xml";
        InputStream resourceAsStream = Resources.getResourceAsStream(mybatis);
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession(true);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();
        for (User u:users) {
            System.out.println(u);
        }
    }
}

声明式事务

事务简介

  • 把一组业务当成一个业务来做,要么都成功,要么都失败
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎
  • 确保数据的完整性和一致性
    事务的ACID原则:
  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能操作同样一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中。

Spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要再代码中,进行事务的管理

为什么需要事务:

  • 如果不配置事务,可能存在数据提交不一致的情况
  • 如果我们不在Spring中配置事务声明,我们需要在代码中手动配置事务
  • 事务在项目开发中十分重要,涉及到数据的完整性和一致性(例如银行转账问题,若网络突然中断,会出现一个人转钱,另一个人却没收到钱的情况)。
    测试代码:
    User.class
package com.test.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor  //有参构造注解
@NoArgsConstructor   //无参构造注解
public class User {
    private int id;
    private String name;
    private String password;
}

UserMapper.class

package com.test.mapper;

import com.test.pojo.User;

import java.util.List;

public interface UserMapper {
    public List<User> selectUser();

    public void addUser(User user);

    public void deleteUser(int id);

    public void updateUser(int id,String name,String password);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.mapper.UserMapper">
    <select id="selectUser" resultType="User">
        select * from user;
    </select>

    <insert id="addUser" parameterType="User">
        insert into user values(#{id},#{name},#{password})
    </insert>

    <delete id="deleteUser" parameterType="int">
        deletes from user where id=#{id}
    </delete>

    <update id="updateUser">
        UPDATE user SET NAME = '#{name}',PASSWORD = '#{password}' WHERE id =#{id}
    </update>
</mapper>

UserMapperImpl.java

package com.test.mapper;

import com.test.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{

    //方式2:需要继承一个类SqlSessionDaoSupport他可以直接getSQLSession,在spring.xml文件的配置中直接少了一步
    public List<User> selectUser() {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //测试事务:先加一个用户,在删一个用户,删除命令故意写错,看报错了会不会添加一个用户
        User user = new User(7,"www","wwww");
        addUser(user);
        deleteUser(7);

        return mapper.selectUser();
    }

    public void addUser(User user) {
        getSqlSession().getMapper(UserMapper.class).addUser(user);
    }

    public void deleteUser(int id) {
        getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    }

    public void updateUser(int id, String name, String password) {
        getSqlSession().getMapper(UserMapper.class).updateUser(id,name,password);
    }

}

配置文件:
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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--导入mybatis和Spring整合的配置文件-->
    <import resource="spring-mybatis.xml"></import>

    <!--配置bean-->
    <bean id="userMapperImpl" class="com.test.mapper.UserMapperImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>
</beans>

mybatis-config.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>

    <!--创建别名-->
    <typeAliases>
        <package name="com.test.pojo"/>
    </typeAliases>

    <!--使用Spring管理-->
    <!--<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            &lt;!&ndash; 配置数据库连接信息 &ndash;&gt;
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://192.168.23.129:3306/BigData" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>-->

    <!--注册接口UserMapper.class-->
    <!--也可以使用Spring进行管理-->
    <!--<mappers>
        <mapper class="com.test.mapper.UserMapper"/>
    </mappers>-->
</configuration>

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

    <!--Datasource:使用Spring的数据源替换Mybatis的配置  c3p0 dbcp等
        这里使用Spring提供的JDBC:org.springframework.jdbc.datasource.DriverManagerDataSource
    -->

    <bean id="Datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://192.168.23.129:3306/BigData?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

    <!--SQLSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="Datasource"/>
        <!--绑定mybatis的配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--对mybatis中的mapper进行管理,mybatis-config.xml中就不用配置了-->
        <property name="mapperLocations" value="com/test/mapper/*.xml"/>
    </bean>

    <!--方式1-->
    <!--SqlSessionTemplate:就是我们使用的SQLSession(mybatis-spring内置的)-->
<!--    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--        &lt;!&ndash;只能使用构造器注入,因为它没有set方法&ndash;&gt;-->
<!--        <constructor-arg index="0" ref="sqlSessionFactory"/>-->
<!--    </bean>-->

    <!--注入UserMapperImpl-->
<!--    <bean id="userMapperImpl" class="com.test.mapper.UserMapperImpl">-->
<!--        <property name="sqlsession" ref="sqlSession"/>-->
<!--    </bean>-->

    <!--方式2,相对方式1少了一步操作-->
<!--    <bean id="userMapperImpl" class="com.test.mapper.UserMapperImpl">-->
<!--        &lt;!&ndash;这个参数是直接注入给UserMapperIml.clss的父类SQLSessionDaoSupport.class的&ndash;&gt;-->
<!--        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>-->
<!--    </bean>-->


    <!--配置事务:先引入约束-->
    <!--配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="Datasource"></property>
    </bean>
    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--配置给特定的方法配置事务
            配置事务的传播新特性:propagation="REQUIRED"(如果没有事务则新建一个事务,Spring默认的)
        -->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/> <!--表示以add打头的方法-->
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="select" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/> <!--表示所有的方法-->
        </tx:attributes>
    </tx:advice>

    <!--配置AOP,织入事务-->
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.test.mapper.*.*(..))"/>
        <!--
        pointcut-ref="txPointCut" :织入对象
        advice-ref="txAdvice" :要织入的东西
        -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"></aop:advisor>
    </aop:config>
</beans>

MyTest.java

import com.test.mapper.UserMapper;
import com.test.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class MyTest {
    @Test
    public void selectUser(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapperImpl = context.getBean("userMapperImpl", UserMapper.class);
        List<User> userList = userMapperImpl.selectUser();
        for (User user:userList) {
            System.out.println(user);
        }
    }



    @Test
    public void operationUser(){
        User user = new User(7,"haha","haha");
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapperImpl = context.getBean("userMapperImpl", UserMapper.class);
        userMapperImpl.updateUser(6,"haha","haha");
    }
}

上一篇:Mybatis---学习总结二


下一篇:spring事务