栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

dw整合mybatis-plus

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

dw整合mybatis-plus

一 背景介绍

     本文主要是将dw-框架引入mybatis-plus。

二 依赖引入

     这里采用Druid数据库连接池(可更换)


    com.baomidou
    mybatis-plus
    3.3.2


    com.alibaba
    druid
    1.1.8

三 mybatisBundle的加载

        主要通过下面三个类来完成加载:

(1)MapperFactory主要负责Mapper文件的生成并注入HK2容器

(2)MybatisBundle负责与DW交互,让DW启动的时候加载MapperFactory

(3)SqlSessionTemplate主要是SqlSession的代理

详细介绍:

3.1  DW如何加载mybatis

    DW自身有一个扩展点,可以通过实现ConfiguredBundle接口

public class AppInit implements IOCApplicationInitialization {
    private static final Logger LOG = LoggerFactory.getLogger(AppInit.class);

    @Override
    public  void initialize(Bootstrap bootstrap) {
        List> entities = EntityScanner.doScan();
        Objects.requireNonNull(entities, "Entity cant be null");
        LOG.info("Urm contains entity domain total:{}", entities.size());
        HibernateBundle hibernateBundle = new HibernateBundle(
                ImmutableList.>builder().add(entities.toArray(new Class[0])).build(),
                new SessionFactoryFactory()) {
            @Override
            public PooledDataSourceFactory getDataSourceFactory(Configuration configuration) {
                DataSourceConfig config = (DataSourceConfig) configuration;
                return config.getDataSourceFactory("umebn_inventory_basic");
            }
        };
        MybatisBundle mybatisBundle = new MybatisBundle() {
            @Override
            public DataSourceFactory getDataSourceFactory(Configuration configuration) {
                DataSourceConfig config = (DataSourceConfig) configuration;
                return config.getDataSourceFactory("umebn_inventory_basic");
            }
        };
        HibernateHelper.setHibernateBundle(hibernateBundle);
        bootstrap.addBundle(hibernateBundle);
        bootstrap.addBundle(mybatisBundle);
    }
}

3.2 MybtaisBundle实现

这里在run方法里面,会去执行 new MapperFactory().initDataSource(dbConfig),MapperFactory就加载对应的Mapper文件

public abstract class MybatisBundle implements ConfiguredBundle {

    public final void run(T configuration, Environment environment) throws Exception {
        DataSourceFactory dbConfig = getDataSourceFactory(configuration);
        new MapperFactory().initDataSource(dbConfig);
    }

    protected abstract DataSourceFactory getDataSourceFactory(T configuration);

}

3.3 MapperFactory的实现

MapperFactory有个核心的方法initDataSource(),这个方法里面主要做了以下几件事

(1)通过javaAF框架扫描到的database相关配置文件解析到的DataSourceFactory ,将DataSourceFactory 中的数据库相关封装成Properties ,提供给Druid

(2)Druid实现类创建DataSource

(3)通过DataSource创建Configuration (看过mybatis代码应该知道Configuration 在mybatis是一个全局配置类,非常重要)

(4)创建sqlSessionFactory

(5)创建sqlSession 代理(具体看3.4)

(6)将加载好的sqlSession 与sqlSessionFactory加入到HK2容器中

(7)扫描Mapper注解,通过sqlSession 生成Mapper动态代理类,将代理类注入到HK2容器,在Service进行DI的时候就可以直接成功注入。

public class MapperFactory {

    public MapperFactory() {
    }

    private static DataSource dataSource = null;
    private static SqlSessionFactory sqlSessionFactory = null;
    private static Configuration configuration = null;

    public void initDataSource(DataSourceFactory dataSourceFactory) {
        Properties properties = parseDbProperties(dataSourceFactory);
        try {
            if (dataSource == null) {
                dataSource = DruidDataSourceFactory.createDataSource(properties);
                initSqlSessionFactory();
                initMapper();
            }
        } catch (Exception e) {
            log.error("Failed init dataSource", e);
        }
    }

    private Properties parseDbProperties(DataSourceFactory dataSourceFactory) {
        Properties properties = new Properties();
        properties.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, dataSourceFactory.getDriverClass());
        properties.put(DruidDataSourceFactory.PROP_URL, dataSourceFactory.getUrl());
        properties.put(DruidDataSourceFactory.PROP_USERNAME, dataSourceFactory.getUser());
        properties.put(DruidDataSourceFactory.PROP_PASSWORD, dataSourceFactory.getPassword());
        return properties;
    }

    private void initSqlSessionFactory() {
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource);
        configuration = new MybatisConfiguration(environment);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
        ServiceLocator serviceLocator = ServiceLocatorFactory.getInstance().find(ServiceUtils.DW_HK2);
        if (serviceLocator == null) {
            serviceLocator = ServiceLocatorFactory.getInstance().create(ServiceUtils.DW_HK2);
        }
        ServiceLocatorUtilities.addoneConstant(serviceLocator, sqlSessionFactory, "sqlSessionFactory", SqlSessionFactory.class);
        ServiceLocatorUtilities.addoneConstant(serviceLocator, configuration, "configuration", Configuration.class);
    }

    private void initMapper() {
        Set> classes = mapperScanner();
        ServiceLocator serviceLocator = ServiceLocatorFactory.getInstance().find(ServiceUtils.DW_HK2);
        classes.forEach(configuration::addMapper);
        SqlSession sqlSession = new SqlSessionTemplate(sqlSessionFactory);
        classes.forEach(clazz -> ServiceLocatorUtilities.addoneConstant(serviceLocator, sqlSession.getMapper(clazz), clazz.getName(), clazz));
    }

    private Set> mapperScanner() {
        return ScannerUtils.scanByAnnotation(Mapper.class);
    }

3.4 SqlSessionTemplate的实现(进一步优化)

    这里主要就是实现一个动态代理

package com.zte.ums.ume.bn.inventory.otnresmgnt.uniresmanager.mybatis;


import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.List;
import java.util.Map;

import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;

public class SqlSessionTemplate implements SqlSession {

    private final SqlSessionFactory sqlSessionFactory;

    private final ExecutorType executorType;

    private final SqlSession sqlSessionProxy;


    public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
    }


    public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.executorType = executorType;
        this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
                new Class[]{SqlSession.class}, new SqlSessionInterceptor());
    }

    public SqlSessionFactory getSqlSessionFactory() {
        return this.sqlSessionFactory;
    }

    public ExecutorType getExecutorType() {
        return this.executorType;
    }

    @Override
    public  T selectOne(String statement) {
        return this.sqlSessionProxy.selectOne(statement);
    }

    @Override
    public  T selectOne(String statement, Object parameter) {
        return this.sqlSessionProxy.selectOne(statement, parameter);
    }


    @Override
    public  Map selectMap(String statement, String mapKey) {
        return this.sqlSessionProxy.selectMap(statement, mapKey);
    }

    @Override
    public  Map selectMap(String statement, Object parameter, String mapKey) {
        return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);
    }

    @Override
    public  Map selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
        return this.sqlSessionProxy.selectMap(statement, parameter, mapKey, rowBounds);
    }

    @Override
    public  Cursor selectCursor(String statement) {
        return this.sqlSessionProxy.selectCursor(statement);
    }


    @Override
    public  Cursor selectCursor(String statement, Object parameter) {
        return this.sqlSessionProxy.selectCursor(statement, parameter);
    }

    @Override
    public  Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds) {
        return this.sqlSessionProxy.selectCursor(statement, parameter, rowBounds);
    }

    @Override
    public  List selectList(String statement) {
        return this.sqlSessionProxy.selectList(statement);
    }


    @Override
    public  List selectList(String statement, Object parameter) {
        return this.sqlSessionProxy.selectList(statement, parameter);
    }


    @Override
    public  List selectList(String statement, Object parameter, RowBounds rowBounds) {
        return this.sqlSessionProxy.selectList(statement, parameter, rowBounds);
    }

    @Override
    public void select(String statement, ResultHandler handler) {
        this.sqlSessionProxy.select(statement, handler);
    }


    @Override
    public void select(String statement, Object parameter, ResultHandler handler) {
        this.sqlSessionProxy.select(statement, parameter, handler);
    }

    @Override
    public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
        this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
    }

    @Override
    public int insert(String statement) {
        return this.sqlSessionProxy.insert(statement);
    }

    @Override
    public int insert(String statement, Object parameter) {
        return this.sqlSessionProxy.insert(statement, parameter);
    }


    @Override
    public int update(String statement) {
        return this.sqlSessionProxy.update(statement);
    }


    @Override
    public int update(String statement, Object parameter) {
        return this.sqlSessionProxy.update(statement, parameter);
    }

    @Override
    public int delete(String statement) {
        return this.sqlSessionProxy.delete(statement);
    }

    @Override
    public int delete(String statement, Object parameter) {
        return this.sqlSessionProxy.delete(statement, parameter);
    }

    @Override
    public  T getMapper(Class type) {
        return getConfiguration().getMapper(type, this);
    }

    @Override
    public void commit() {
        throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
    }


    @Override
    public void commit(boolean force) {
        throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
    }

    @Override
    public void rollback() {
        throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
    }

    @Override
    public void rollback(boolean force) {
        throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
    }

    @Override
    public void close() {
        throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
    }

    @Override
    public void clearCache() {
        this.sqlSessionProxy.clearCache();
    }

    @Override
    public Configuration getConfiguration() {
        return this.sqlSessionFactory.getConfiguration();
    }

    @Override
    public Connection getConnection() {
        return this.sqlSessionProxy.getConnection();
    }

    @Override
    public List flushStatements() {
        return this.sqlSessionProxy.flushStatements();
    }

    
    private class SqlSessionInterceptor implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            SqlSession sqlSession = sqlSessionFactory.openSession(executorType, true);
            try {
                Object result = method.invoke(sqlSession, args);
                sqlSession.commit(true);
                return result;
            } catch (Throwable t) {
                Throwable unwrapped = unwrapThrowable(t);
                sqlSession.rollback();
                sqlSession = null;
                throw unwrapped;
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    }

}

四 案例演示:

(1)实体类

@TableName("demo")
public class Demo {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

(2)Rest接口

@Path("/xuyu")
@Contract
public interface DemoApi {

    @POST
    @Path("/add")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    @UnitOfWork
    @io.swagger.annotations.ApiOperation(value = "", notes = "新增或修改基础信息", tags = {"OtnResMgntTopo",})
    @io.swagger.annotations.ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "successful operation")})
    Integer addOrUpdateBasicInfo(@ApiParam(value = "待新增或修改的基本信息", required = true) Demo demo
            , @Context HttpServletRequest servletRequest)
            throws Exception;


    @GET
    @Path("/find/{id}")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    @UnitOfWork
    @io.swagger.annotations.ApiOperation(value = "", notes = "新增或修改基础信息", tags = {"OtnResMgntTopo"})
    @io.swagger.annotations.ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "successful operation")})
    Demo find(@PathParam(value = "id") String id
            , @Context HttpServletRequest servletRequest)
            throws Exception;

    @POST
    @Path("/delete/{id}")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    @UnitOfWork
    @io.swagger.annotations.ApiOperation(value = "", notes = "新增或修改基础信息", tags = {"OtnResMgntTopo"})
    @io.swagger.annotations.ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "successful operation")})
    Integer delete(@PathParam(value = "id") String id
            , @Context HttpServletRequest servletRequest)
            throws Exception;

    @POST
    @Path("/select/{name}")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    @UnitOfWork
    @io.swagger.annotations.ApiOperation(value = "", notes = "新增或修改基础信息", tags = {"OtnResMgntTopo"})
    @io.swagger.annotations.ApiResponses(value = {
            @io.swagger.annotations.ApiResponse(code = 200, message = "successful operation")})
    List selectByName(@PathParam(value = "name") String name
            , @Context HttpServletRequest servletRequest)
            throws Exception;


}

(3)定义Mapper接口

    ​这里findDemoByName是通过xml映射得到的,xml文件如下,注意namspace的写法要与接口全路径保持一致

这里额外补充:mybatis-plus自身提高了一些基础的功能在baseMapper里面,如果需要额外功能就需要自己写XML文件,以及通过注解,这三种方式

@Mapper
public interface DemoMapper extends baseMapper {

    List findDemoByName(String name);

}





    

(4)Rest接口实现

@Service
public class DemoImpl implements DemoApi {

    @Inject
    private DemoMapper demoMapper;

    @Override
    public Integer addOrUpdateBasicInfo(Demo demo, HttpServletRequest servletRequest) throws Exception {
        return demoMapper.insert(demo);
    }

    @Override
    public Demo find(String id, HttpServletRequest servletRequest) throws Exception {
        return demoMapper.selectById(id);
    }

    @Override
    public Integer delete(String id, HttpServletRequest servletRequest) throws Exception {
        return demoMapper.deleteById(id);
    }

    @Override
    public List selectByName(String name, HttpServletRequest servletRequest) throws Exception {
        return demoMapper.findDemoByName(name);
    }

}

(5)接口访问与数据库

增删改查OK

六 后续改进:
(1)关于动态代理生成sqlSession那块,以及自动提交还需要改进

(2)关于mapper.xml文件的管理,需要统一起来,可以在application.yml进行配置

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/713140.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号