弃用*******springboot引入mybatis配置&乐观锁

 

乐观锁(Optimistic Lock):
数据库中,通过加版本的方式实现乐观锁
每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。
比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。
实现方案:
一般是在数据表中加上一个版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读到的version值与当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功


基于事务,可能导致锁表时间过长等性能问题
InnoDB在Mysql5.5版本之后成为默认存储引擎。InnoDB是一种事务性的存储引擎, 也就是说InnoDB是支持事务的ACID特性的。InnoDB的设计更适合处理大量的小事务。InnoDB支持行级锁,行级锁可以更大限度的支持并发,行级锁是由存储引擎实现的。
FOR UPDATE在读取行上设置一个排他锁。阻止其他session读取或者写入行数据 for update 来防止死锁和重复插入

  

生成sqlSessionFactory时装配dao层操作  
使用@Mapper实现springboot去xml配置化,默认自动关闭连接 高级使用,可选择衍生工具 tk.mybatis

使用Mapper注解时:
@Configuration
@MapperScan(basePackages = "cn.com.xmh.oneIbatiaMapper.mapper", sqlSessionFactoryRef = "sqlSessionFactoryBeanOrder")
1,只有一个数据源会话工厂时可不使用该扫描  为了匹配dao层接口和数据库会话工厂
2,使用MapperScan注解则不需要每个数据库操作实体都加 @Mapper
   @MapperScan(basePackages = "cn.com.myBatisXml")
3,使用Mapper注解则无需xml配置sql语句

springboot引入xml配置  
1,mybatis.config-location= classpath:mybatis-config.xml  
2, @Bean(name = "sqlSessionFactoryBean")
    @ConfigurationProperties(prefix = "mybatis") 组装数据库会话工厂 引入xml配置
    public SqlSessionFactoryBean 
3, 使用
  1)session.selectList("queryAll",map); 可以从session工厂直接使用 缺点:方法不可重名
  2)<mapper namespace="cn.com.myBatisXml.MyDaoMapperTest">  可以从 注入的@Mapper实体 使用
     namespace 好处:数据库操作的方法可以重名
     MyDaoMapperTest 方法的sql可用 @Select写,也可在xml中写
  3)org.mybatis.spring.annotation.MapperScan @MapperScan(basePackages = "cn.com.myBatisXml")
     使用该注解整体扫描dao层mapper实体 不需要每个实体都加 @Mapper

数据源
2, @Bean("dataSourceOrder")
@ConfigurationProperties(prefix = "mysql.one")  加载数据库配置,生成DataSource实体
    public DataSource
3,SqlSessionFactoryBean 根据dataSource实体 组装数据库会话工厂

 

直接使用 @Mapper 解析sql

<repositories>
<repository>
    <id>xmhs</id>
    <url>https://mvnrepository.com</url>
</repository>
</repositories>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.11</version>
</dependency>
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
</dependency>


@Mapper
public interface TestMapper { //如果要返回对象,对象属性必须与表保持一致
    @Select("SELECT login_name,user_name from web_user_info where login_name = 'dev000001' and del_ = 1 ")
    public Object queryxmh();
}

@Configuration
public class DataSourceConfigerXmh {
    @Bean
    @ConfigurationProperties(prefix = "mysql.one")
    public DataSource dataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }
    @Bean //(name = "sqlSessionFactoryBeanOrder")
    public SqlSessionFactoryBean sqlSessionFactoryBeanTemplateInsurance() {
        SqlSessionFactoryBean sqlSessionFactoryBeanOrder = new SqlSessionFactoryBean();
        sqlSessionFactoryBeanOrder.setDataSource(dataSource());
        return sqlSessionFactoryBeanOrder;
    }
}


@Mapper MapperScannerRegistrar
Configuration配置 MybatisAutoConfiguration AutoConfiguredMapperScannerRegistrar


@Mapper 是对单个接口类的注解。单个操作。
@MapperScan 是对整个包下的所有的接口类的注解。是批量的操作。使用 @MapperScan 后,接口类 就不需要使用 @Mapper 注解

  

 

引入多个配置文件
spring.profiles.include=redisKey
application-rediskey.properties

 

springboot引入mybatis配置文件

pom.xml
<build>
            <resources>
                <resource>
                    <directory>${project.basedir}/src/main/resources</directory>
                    <!--<includes>-->
                        <!--<include>**/*.xml</include>-->
                        <!--<include>*.properties</include>-->
                    <!--</includes>-->
                    <!--<filtering>true</filtering>-->
                </resource>

application.properties
#mybatis.typeAliasesPackage: cn.com.entity
#mybatis.mapper-locations= classpath:MyMappers/*.xml  #此方案未通过
mybatis.config-location= classpath:mybatis-config
#restart.include.companycommonlibs=tk/mybatis.*
mysql.one.url=jdbc:mysql://127.0.0.1/xmh
mysql.one.userName=root
mysql.one.password=admin
mysql.one.initialSize= 5
mysql.one.minIdle= 5
mysql.one.maxActive= 20
mysql.one.maxWait= 6000
mysql.one.validationQuery= select 1 from dual
mysql.one.drever-class-name= com.mysql.jdbc.Driver


mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>
    <settings>
        <!-- 全局映射器启用缓存 -->
        <setting name="cacheEnabled" value="false"/>
        <!-- 查询时,关闭关联对象即时加载以提高性能 -->
        <setting name="lazyLoadingEnabled" value="false"/>
        <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!-- 允许使用列标签代替列名 -->
        <setting name="useColumnLabel" value="true"/>
        <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
        <setting name="useGeneratedKeys" value="true"/>
        <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
        <setting name="autoMappingBehavior" value="FULL"/>
        <!-- 对于批量更新操作缓存SQL以提高性能 -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!-- 数据库超过25000秒仍未响应则超时 -->
        <setting name="defaultStatementTimeout" value="25000"/>
        <!--驼峰命名-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
    </settings>
    <!--<plugins>-->
        <!--<plugin interceptor="com.github.pagehelper.PageInterceptor">-->
            <!--<property name="dialect" value="com.github.pagehelper.PageHelper"/>-->
            <!--<!– 该参数默认为false –>-->
            <!--<!– 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 –>-->
            <!--<!– 和startPage中的pageNum效果一样–>-->
            <!--<property name="offsetAsPageNum" value="true"/>-->
            <!--<!– 该参数默认为false –>-->
            <!--<!– 设置为true时,使用RowBounds分页会进行count查询 –>-->
            <!--<property name="rowBoundsWithCount" value="true"/>-->
            <!--<!– 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 –>-->
            <!--<!– (相当于没有执行分页查询,但是返回结果仍然是Page类型)–>-->
            <!--<property name="pageSizeZero" value="true"/>-->
            <!--<!– 3.3.0版本可用 - 分页参数合理化,默认false禁用 –>-->
            <!--<!– 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 –>-->
            <!--<!– 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 –>-->
            <!--<property name="reasonable" value="false"/>-->
            <!--<!– 3.5.0版本可用 - 为了支持startPage(Object params)方法 –>-->
            <!--<!– 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 –>-->
            <!--<!– 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 –>-->
            <!--<!– 不理解该含义的前提下,不要随便复制该配置 –>-->
            <!--<property name="params" value="pageNum=start;pageSize=limit;"/>-->
            <!--<!– always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page –>-->
            <!--<property name="returnPageInfo" value="check"/>-->
        <!--</plugin>-->
    <!--</plugins>-->

    <typeAliases>
        <package name="cn.com.entity"/>
    </typeAliases>
    <mappers>
        <mapper resource="MyMappers/myDaoTestMapper.xml"></mapper>
    </mappers>

</configuration>


@Configuration
public class DataBaseConfigurationOrder {
//    @Bean
//    public WallFilter wallFilterOrder(){
//        WallFilter wallFilter=new WallFilter();
//        wallFilter.setConfig(wallConfigOrder());
//        return wallFilter;
//    }
//    @Bean
//    public WallConfig wallConfigOrder(){
//        WallConfig config =new WallConfig();
//        config.setMultiStatementAllow(true);//允许一次执行多条语句
//        config.setNoneBaseStatementAllow(true);//允许非基本语句的其他语句
//        return config;
//    }

    /**
     * Slave alpha data source.
     *
     * @return the data source
     */
    @Bean("dataSourceOrder")
    @ConfigurationProperties(prefix = "mysql.one")
    public DataSource dataSourceOrder() {
        DruidDataSource druidDataSource = new DruidDataSource();
        List<Filter> filterList=new ArrayList<>();
//        filterList.add(wallFilterOrder());
//        druidDataSource.setProxyFilters(filterList);
//        druidDataSource.setPassword(basePasswordProvider.getPassword(baseName));
        System.out.println("***********************DataBaseConfigurationOrder*dataSourceOrder******************************");
        return druidDataSource;
    }

    @Bean(name = "sqlSessionFactoryBeanOrder")
    @ConfigurationProperties(prefix = "mybatis")
    public SqlSessionFactoryBean sqlSessionFactoryBeanOrder() {
        System.out.println("***********************DataBaseConfigurationOrder*sqlSessionFactoryBeanOrder******************************");
        SqlSessionFactoryBean sqlSessionFactoryBeanOrder = new SqlSessionFactoryBean();

//        PathMatchingResourcePatternResolver re = new PathMatchingResourcePatternResolver();
//        String pa = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+"MyMappers/*.xml";
//        try {
//            sqlSessionFactoryBeanOrder.setMapperLocations(re.getResources(pa));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        sqlSessionFactoryBeanOrder.setDataSource(dataSourceOrder());
        return sqlSessionFactoryBeanOrder;
    }

    /**
     * 注入 DataSourceTransactionManager 用于事务管理
     */
    @Bean(name = "transactionManagerOrder")
    public PlatformTransactionManager transactionManagerOrder() {
        return new DataSourceTransactionManager(dataSourceOrder());
    }
}



@Repository("myDaoTest")
public class MyDaoTest {
    @Autowired
    @Qualifier(value = "sqlSessionFactoryBeanOrder")
    private SqlSessionFactory factory;

    public List<TUser> query(){
        SqlSession session = factory.openSession();
        try{
            Map map = new HashMap<String,String>();
            map.put("id","1");
            return  session.selectList("query",map);
        }finally{
            session.close();
        }
    }
}

1、mybatis.mapper-locations在SpringBoot配置文件中使用,作用是扫描Mapper接口对应的XML文件,如果全程使用@Mapper注解,可以不使用该配置。
2、@MapperScan会扫描Mapper接口类,并生成对应的实现类。

 

1,数据源没有配置事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

 

 

  

 

posted @ 2020-08-09 19:04  XUMT111  阅读(872)  评论(0)    收藏  举报