zoukankan      html  css  js  c++  java
  • 【Mybatis + Spring】 Mybatis

    环境搭建 EvBuild


    软件环境准备

    -  MySQL 5.0 +

    -  IDEA 2018 +

    -  JDK1.8 +

    依赖包相关

    -  Junit单元测试

    -  JDBC驱动

    -  Mybatis 组件

    -  Spring组件

    -  AopWeaver切面织入包

    -  Mybatis-Spring【MS专用整合包】

    -  Lombok

    -  Log4J 日志输出


    官方文档:

    http://mybatis.org/spring/zh/index.html

    什么是 MyBatis-Spring?

    MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。

    它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,

    以及将 Mybatis 的异常转换为 Spring 的 DataAccessException

    最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。

    使用须知:

    使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis 这两个框架和有关它们的术语。

    这很重要——因为本手册中不会提供二者的基本内容,安装和配置教程。

    MyBatis-Spring 需要以下版本:

    MyBatis-SpringMyBatisSpring 框架Spring BatchJava
    2.0 3.5+ 5.0+ 4.0+ Java 8+
    1.3 3.4+ 3.2.2+ 2.1+ Java 6+

    工程创建

    在前面的Spring工程基础上创建新模块

    开始配置Maven依赖

    <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.5</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.20</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>

    资源过滤问题

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
    
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
        </build>

    回顾原生Mybatis开发步骤:

    1、编写实体类

    2、Mybatis-Config.xml核心配置文件

    3、Dao接口,或者说Mapper接口

    4、编写Mapper.xml映射器配置、注册映射器

    5、测试

    实体类POJO

    package cn.dai.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Integer user_id;
        private String user_name;
        private String user_password;
    }

    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>
    
        <settings>
            <setting name="logImpl" value="LOG4J"/>
        </settings>
    
        <typeAliases>
            <package name="cn.dai.pojo"/>
        </typeAliases>
    
        <environments default="dev1">
    
            <environment id="dev1">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql:///mybatis?serverTimezone=GMT"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper resource="mappers/UserMapper.xml"/>
        </mappers>
    </configuration>

    Mapper.xml

    很多人不喜欢映射器文件和接口放在一起,并且Maven也确实存在资源过滤问题

    这样,我们可以放在资源目录下,新建一个mappers目录,统一放在这里面

    编写映射器UserMapper.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="cn.dai.mapper.UserMapper">
    
        <select id="getAllUserList" resultType="user">
            SELECT * FROM user;
        </select>
        
    </mapper>

    在核心配置中这样注册映射器

    <mappers>
      <mapper resource="mappers/UserMapper.xml"/>
    </mappers>

    MybatisUtil.java

    我们自己配置的会话获取工具类

    public class MybatisUtil {
        private static SqlSessionFactory sqlSessionFactory;
        
        static {
            String mybatis_config = "Mybatis-Config.xml";
    
            try {
                InputStream inputStream = Resources.getResourceAsStream(mybatis_config);
    
                SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    
                sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
                
                sqlSessionFactoryBuilder = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSession getSqlSession(boolean closeTransaction) {
            return sqlSessionFactory.openSession(closeTransaction);
        }
    }

    配置LOG4J日志输出【可选】

    如果不要配置,把Mybatis-Config.xml的Settings删除

    编写log4j.properties

    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    log4j.rootLogger=DEBUG,console,file
    
    #控制台输出的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.Threshold=DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
    
    #文件输出的相关设置
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File=./log/l4j.log
    log4j.appender.file.MaxFileSize=10mb
    log4j.appender.file.Threshold=DEBUG
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
    
    #日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG

    在测试类加入日志实例

    org.apache.log4j.Logger;
    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(MybatisTest.class);

    测试Mybatis环境搭建是否正常

    public class MybatisTest {
    
        private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(MybatisTest.class);
    
        @Test
        public void sqlTest(){
            SqlSession sqlSession = MybatisUtil.getSqlSession(true);
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> allUserList = mapper.getAllUserList();
    
            for (User user:allUserList){
                logger.info(user);
            }
    
            sqlSession.close();
        }
    }

    开始整合 Start Integration

    现在我们把对象交给Spring管理,

    再也不需要我们自己编写的MybatisUtil会话获取工具类了

    编写Spring的Bean容器配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
    
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:c="http://www.springframework.org/schema/c"
    
           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://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
    "
    >
        <context:annotation-config />
        <context:component-scan base-package="cn.dai" />
        <aop:aspectj-autoproxy proxy-target-class="false"/>
    
    
    </beans>

    快速上手

    要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:

    一个 SqlSessionFactory 和至少一个数据映射器类。

    在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean来创建 SqlSessionFactory

    要配置这个工厂 bean,只需要把下面代码放在 Spring 的 XML 配置文件中:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
    </bean>

    或者使用纯JavaConfig的注解方式

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
      SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
      factoryBean.setDataSource(dataSource());
      return factoryBean.getObject();
    }

    注意:SqlSessionFactory 需要一个 DataSource(数据源)。

    这可以是任意的 DataSource,只需要和配置其它 Spring 数据库连接一样配置它就可以了。

    【在狂神的是XML配置,上面的会话工厂Bean需要引用一个数据源实例,它采用的是Spring提供的数据源】

    <!-- 我们所学过的连接池【数据源】有C3P0、DRUID、HIKARI、DBCP、 -->
        <!-- 这里使用Spring提供的连接池-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
            <property name="url" value="jdbc:mysql:///mybatis?serverTimezone=GMT" />
            <property name="username" value="root" />
            <property name="password" value="123456" />
        </bean>

    可以看看这个数据源类的源码是怎样的?

    源码:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.springframework.jdbc.datasource;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    import org.springframework.util.Assert;
    import org.springframework.util.ClassUtils;
    
    public class DriverManagerDataSource extends AbstractDriverBasedDataSource {
        public DriverManagerDataSource() {
        }
    
        public DriverManagerDataSource(String url) {
            this.setUrl(url);
        }
    
        public DriverManagerDataSource(String url, String username, String password) {
            this.setUrl(url);
            this.setUsername(username);
            this.setPassword(password);
        }
    
        public DriverManagerDataSource(String url, Properties conProps) {
            this.setUrl(url);
            this.setConnectionProperties(conProps);
        }
    
        public void setDriverClassName(String driverClassName) {
            Assert.hasText(driverClassName, "Property 'driverClassName' must not be empty");
            String driverClassNameToUse = driverClassName.trim();
    
            try {
                Class.forName(driverClassNameToUse, true, ClassUtils.getDefaultClassLoader());
            } catch (ClassNotFoundException var4) {
                throw new IllegalStateException("Could not load JDBC driver class [" + driverClassNameToUse + "]", var4);
            }
    
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Loaded JDBC driver: " + driverClassNameToUse);
            }
    
        }
    
        protected Connection getConnectionFromDriver(Properties props) throws SQLException {
            String url = this.getUrl();
            Assert.state(url != null, "'url' not set");
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Creating new JDBC DriverManager Connection to [" + url + "]");
            }
    
            return this.getConnectionFromDriverManager(url, props);
        }
    
        protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException {
            return DriverManager.getConnection(url, props);
        }
    }

    所以,在Mybatis-Config.xml的环境配置就可以舍弃了

    Mybatis-Config.xml可以删除的部分

    <environments default="dev1">
    
            <environment id="dev1">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql:///mybatis?serverTimezone=GMT"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>

    连接参数的读取就可以让Spring的ApplicationContext读取了

    接着,Mybatis-Config.xml这个核心配置文件又

    可以让会话工厂实例的configuration属性读取

    <!-- SQL会话工厂 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configuration" value="classpath:Mybatis-Config.xml" />
        </bean>

    其实这个会话工厂实例Bean的设置完全涵盖了核心配置

    【狂神推荐 别名 & 设置 留给 Mybatis-Config.xml 核心配置,其他部分完全Spring容器接管】

    注意映射器的配置只能保存一个,在Spring写了就不能再在Mybatis-Config.xml保留

    <!-- SQL会话工厂 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 数据源 连接池-->
            <property name="dataSource" ref="dataSource" />
            <!-- 核心配置地址 -->
            <property name="configLocation" value="classpath:Mybatis-Config.xml" />
            <!-- 配置映射器位置-->
            <property name="mapperLocations" value="classpath:mappers/UserMapper.xml"/>
        </bean>

    然后是SqlSession的Bean注册

        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
            <!-- 只允许构造器注入 没有setSqlSession方法 -->
            <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
        </bean>

    但是在Mapper包,我们就需要多写一个实现类

    public class UserMapperImpl implements UserMapper{
        
        // 现在使用SqlSessionTemplate完成
        SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public List<User> getAllUserList() {
            return sqlSession.getMapper(UserMapper.class).getAllUserList();
        }
    }

    Bean注册

    <bean id="userMapperImpl" class="cn.dai.mapper.UserMapperImpl">
            <property name="sqlSession" ref="sqlSessionTemplate" />
        </bean>

    测试

    import cn.dai.mapper.UserMapper;
    import cn.dai.pojo.User;
    import org.apache.log4j.Logger;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    public class MybatisSpringIntegration {
    
        private static Logger logger = Logger.getLogger(MybatisSpringIntegration.class);
    
        @Test
        public void msTest(){
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Canned.xml");
            UserMapper userMapper = applicationContext.getBean("userMapperImpl", UserMapper.class);
    
            List<User> allUserList = userMapper.getAllUserList();
    
            for (User user:allUserList){
                logger.info(user);
            }
    
        }
    }

    整合总结:

    1、数据库数据准备

    2、实体类编写,暂不需要Bean注册

    3、编写Mybatis-Config.xml配置,也可以让Spring全权Bean化处理

    4、编写Mapper接口,SQL的抽象方法

    5、编写Mapper.xml映射器配置,可以放在接口包,也可以是资源目录

    6、Mapper的注册交给Mybatis-Config.xml或者是Bean处理

    7、LOG4J日志输出配置【可选】

    8、配置Spring容器类

    9、配置数据源【DataSource 连接池】Bean化

    10、配置SQL会话工厂【SqlSessionFactory】Bean化

    11、SQL会话工厂可以完全配置Mybatis-Config.xml【可选,自己看情况设置】

    12、配置SQL会话模板【SqlSessionTemplate】Bean化

    13、编写XXXmapper实现类,同时配置Bean

    14、测试,或者实际使用,从ApplicationContext获取即可


    第二种整合方式: 

    只是在上面的基础上有一点改动

    官方在我们编写实现类要组合SqlSessionTemplate的这个步骤上封装了

    我们只需要继承SqlSessionDaoSupport类即可

    public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
    
        public List<User> getAllUserList() {
            return this.getSqlSession().getMapper(UserMapper.class).getAllUserList();
        }
    }

    在Bean的配置上,只需要注入SQL会话工厂即可

    <bean id="userMapperImpl2" class="cn.dai.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

    测试

        @Test
        public void msTest2(){
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Canned.xml");
            UserMapper userMapper = applicationContext.getBean("userMapperImpl2", UserMapper.class);
            List<User> allUserList = userMapper.getAllUserList();
            for (User user:allUserList){
                logger.info(user);
            }
        }

    关于Spring的声明式事务

    约束声明

    xmlns:tx="http://www.springframework.org/schema/tx"
    
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd

    事务配置

    <!--https://blog.csdn.net/jiadajing267/article/details/81056057-->
        <!-- 配置声明式事务 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    
        <!-- 2. 配置事务属性 -->
        <!--<tx:advice>元素声明事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 根据方法名指定事务的属性 -->
                <tx:method name="*"/>
                <!--propagation配置事务传播行为-->
                <tx:method name="purchase" propagation="REQUIRES_NEW"/>
                <!--isolation配置事务的隔离级别-->
                <tx:method name="update*" isolation="SERIALIZABLE"/>
                <!--rollback-for配置事务遇到异常必须回滚,no-rollback-for配置事务遇到异常必须不能回滚-->
                <tx:method name="add*" rollback-for="java.io.IOException" no-rollback-for="com.dmsd.spring.tx.BookStockException"/>
                <!--read-only配置事务只读属性-->
                <tx:method name="find*" read-only="true"/>
                <!--timeout配置事务的超时属性-->
                <tx:method name="get*" timeout="3"/>
            </tx:attributes>
        </tx:advice>
    
        <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
        <aop:config>
            <aop:pointcut expression="execution(* cn.dai.mapper.UserMapper.*.*(..))"
                          id="txPointCut"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
        </aop:config>
  • 相关阅读:
    datagrid与webAPI的数据交互(ef mvc )
    ASP.Net MVC数据传递
    dagride实现模糊查询
    MVC三层架构搭建
    web实现下拉列表多选加搜索
    php入门
    mysql实现简单的增删改查,放入xmapp自带数据库中
    ghithub中PHPOffice/PHPWord的学习
    移动端一像素问题
    点击按钮返回顶部
  • 原文地址:https://www.cnblogs.com/mindzone/p/12830677.html
Copyright © 2011-2022 走看看