非spring框架下Mybatis的基本使用

本文分享了在非Spring框架环境中使用Mybatis进行数据库操作的心得,包括配置SqlSessionFactory、初始化SqlSessionFactory的步骤。通过动态代理简化SqlSession的使用,避免频繁的打开和关闭操作。文中提到了Java的动态代理机制,选择了反射实现,以减少项目依赖。同时指出,这种方式无法进行数据库事务操作,但可以借鉴Spring的事务管理思路。
部署运行你感兴趣的模型镜像

目录

前言

一、基于这次小项目的经历分享下非spring框架下mybatis使用的一些心得

二、使用步骤

1.配置SqlSessionFactory

2.初始化SqlSessionFactory

3. 代理SqlSession相关方法


前言

需求: 安装在客户端上非常轻量级的服务,需要有数据库持久化数据。开发语言为Java,客户端界面开发为JavaFX,数据库为SQLite,持久化框架为mybatis

整体架构的选择思路是,在保证完成功能的前提下,尽量轻量化,最少引入第三方插件。


一、基于这次小项目的经历分享下非spring框架下mybatis使用的一些心得

二、使用步骤

1.配置SqlSessionFactory

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

这里选择用XML文件的方式进行配置:

创建mybatis-config.xml

<configuration>
		<!-- 数据库配置放在db.properties中-->
    <properties resource="db.properties">
    </properties>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true" />
<!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="org.zc.config.MyBatisDruidPoolAdapter">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
                <property name="validationQuery" value="${validationQuery}"/>
            </dataSource>
        </environment>
        <environment id="production">
            <transactionManager type="JDBC"/>
            <dataSource type="org.zc.config.MyBatisDruidPoolAdapter">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/DemoDao.xml"/>
    </mappers>
</configuration>

2.初始化SqlSessionFactory

Mybatis官方说明中SqlSessionFactory的生命周期是:在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例

public static SqlSessionFactory sqlSessionFactory;

    static {
        initFactory();
    }

    private static void initFactory() {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        if(sqlSessionFactory == null) {
            initFactory();
        }
        return sqlSessionFactory;
    }

3. 代理SqlSession相关方法

SqlSession的生命周期是:每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。

如果按照官方说明每次调用sqlsession的方法要先获取sqlsession,使用完还需要关闭,使用就非常繁琐,这边使用动态代理简化操作。

提下JAVA的动态代理,JAVA的动态代理实现方式有两种:反射和cglib动态代理。Spring中的AOP的动态代理两种实现方式都有用到。

反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效。JDK的反射的动态代理生成也必须基于统一的接口,局限性大点。

由于我这个项目尽量精简依赖,毫不犹豫使用反射动态代理。

代理类:

public class MapperInterceptor<T> implements InvocationHandler {

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        try ( SqlSession session = DatabaseConfig.getSqlSessionFactory().openSession(true)){
            System.out.println("----------------代理开始---------------");
            System.out.println("--------------------代理方法为:------------------" + method);
            Class<?> c = method.getDeclaringClass();
            T dao = (T) session.getMapper(c);
            return method.invoke(dao, objects);
        }
    }
}

public class DaoMapperProxy {

    public static <T> T getProxyInstance(Class clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class<?>[]{clazz}, new MapperInterceptor<T>());
    }
}

DAO层:

@Mapper
public interface DemoDao {
    List<TLog> listLog();

    List<TLog> listLogById(Integer id);
}

Service层:

public class DemoService {

    public List<TLog> getLogs() {
        DemoDao demoDao = DaoMapperProxy.getProxyInstance(DemoDao.class);
        return demoDao.listLog();
    }
}

测试类:

public class DemoTest {

    @Test
    public void test1() {
        DemoService demoService = new DemoService();
        List<TLog> l = demoService.getLogs();
        System.out.println("-----------输入为-----------");
        System.out.println(l);
    }
}

输出:


 DatabaseConfig.getSqlSessionFactory().openSession(true)中的true是开启mysql事务的自动提交功能,这样无需手动提交。但是问题也显而易见,无法进行数据库事务操作,spring中通过@Transactional的标签基于AOP来实现service级别的事务管理。我们也可以参考spring的思路实现,本文不展开了,下期再实现。

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值