今天开始学习Mybatis,环境搭建一步步遇到问题,一点点解决,还可以,在学到CRUD的时候,发现对于SqlSession每次都需要创建一个,最后释放,很是麻烦,于是想一想该怎么优化代码,同时可以满足开闭原则呢?OK话不多说,let's think about it;
对于Mybatis的使用,从最开始最基本的类有三个,参考官方文档,如下:
整个过程实际上就是:由建造者建造工厂>由工厂生产Session【建造者模式-》工厂模式】
(建造者)->(工厂)->(对象)
通过建造者模式构建的工厂建造者构建工厂,工厂创建实例。
OK,最主要的需要谈一谈CRUD代码,对于在Mapper中写方法名,在xml中写实现这些没必要在这里讨论了,很简单,对于调用的时候,我发现每次都是这几个步骤,是不是很恶心啊?每次都要写重复的代码:
//开启 SqlSession sqlSession=MybatisUtils.getSqlSessionFactory(); try { UserMapper mapper = sqlSession.getMapper(UserMapper.class); //业务代码 User user=new User(0,"小库","23"); int insertCount = mapper.addUser(user); sqlSession.commit(); } catch (Exception e){ e.printStackTrace(); } finally { //释放 sqlSession.close(); }
于是思考一下,对于这种首先创建链接,然后个人操作,最后关闭这个流程不就是模板方法模式的设计思想吗?
同时考虑一下我构建一个SqlTemplate的话,这个类中可以执行很多其他的方法,因此最好不要定义成静态的,因为我们只需要Session不同就可以啦,所以呢,只要一个SqlTemplate即可,OK,那就把它构建成单例模式吧
ok,let's write code;
首先定义个接口,代表我们自己需要执行的逻辑代码:
public interface SqlOperate<T> { void Operate(T mapper); }
然后嘞,就是最重要的SqlTemplate了(其中的MybatisUtils是官网有示例,自己写的一个工具类,这个想必大家都知道,只不过这是我自己起的名字)
public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; //放在静态代码块,编译器加载 static { try { //第一步,获取sqlSessionFactory工厂对象 //通过SqlSessionFactoryBuilder工厂建造者构建工厂 String resource = "mybatis-config.xml"; InputStream inputStream = null; inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。 // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 public static SqlSession getSqlSessionFactory() { return sqlSessionFactory.openSession(); } }
/** * 宁新杰:创建sql模板,完成封装 * 使用了单例+模板 */ public class SqlTemplate { private SqlTemplate(){}; private static class InnerClass { private static SqlTemplate sqlTemplate = new SqlTemplate(); } public static SqlTemplate getInstance(){ return InnerClass.sqlTemplate; } public void run(Class mapperClass, SqlOperate sqlOperate) { SqlSession sqlSession = MybatisUtils.getSqlSessionFactory(); try { Object mapper = sqlSession.getMapper(mapperClass); sqlOperate.Operate(mapper); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } } }
OK,,调用呢?
SqlTemplate.getInstance().run(UserMapper.class, new SqlOperate<UserMapper>() { @Override public void Operate(UserMapper mapper) { mapper.deleteById(new User(4)); } });
是不是非常简洁啊!perfect!
哦,对了,提醒大家一下,构建泛型的时候,如果不太熟练,首先使用具体的类来构建,比如这里的我实际上是使用具体的【UserMapper 】来构建的,构建好了之后,再替换的泛型的。
OK啦,每天进步一点点,继续加油!逐梦~~~