目录
一、基于这次小项目的经历分享下非spring框架下mybatis使用的一些心得
前言
需求: 安装在客户端上非常轻量级的服务,需要有数据库持久化数据。开发语言为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的思路实现,本文不展开了,下期再实现。
本文分享了在非Spring框架环境中使用Mybatis进行数据库操作的心得,包括配置SqlSessionFactory、初始化SqlSessionFactory的步骤。通过动态代理简化SqlSession的使用,避免频繁的打开和关闭操作。文中提到了Java的动态代理机制,选择了反射实现,以减少项目依赖。同时指出,这种方式无法进行数据库事务操作,但可以借鉴Spring的事务管理思路。
3638





