仅为不断进取后的
自我总结并加深理解和初学码农间交流
大神请自爱!
大神请自爱!
学习的时候总会有很多心得,某些大神总是喜欢自己一个人闷在心中。让想学的菜鸟一直望其项背。没有交流就没有收获,没有对比就没进取,求大神指教,不要再自个儿修炼了。
当我们用Dao层访问数据库的时候,难免有写增删查改的时候有重复代码并且比较死,不够灵活,当表中的属性很多很多的时
候,更加不方便于我们访问。在没有使用框架之前,开始学习的时候第一次写的时候我也是这样的,以findbyId为例子:
代码图:
![图片](https://i-blog.csdnimg.cn/blog_migrate/98cba2394a5d046de53b51b2fc0b4609.png)
第一步优化,很简单。。。
将公共代码提取,如上form.setALL 提取此类中一个静态的方法中 static formMapping()
如此改进之后,其实我们的增删改查操作还是需要在每个DaoImpl中实现,这样的工作还是有些累赘。其实发现,增删改查操作的代码如此类似,只是有三个地方不一样:1.String型的SQL代码不一样 2.还有对于?(问号)的赋值不一样 3.有时需要返回的结果集的映射到bean中也是不一样的(返回结果集封装到Bean中,如返回一个User) 于是第二次优化如图:
为了解决以上三点,创建一个抽象类AbstractDao 在其中写好和具体实现类差不多的非抽象的增删查改的公用方法,将参数改为String型的SQL(select username from User where id=?等)的参数和对问号赋值时的参数。此时对问好赋值的参数就为一个Object[]的对象数组,而不是之前的具体memoid或者替他的什么,这样就可以灵活应对各种类型的参数了。
我们在抽象类中,每个方法中都是同样的代码:
当我们用Dao层访问数据库的时候,难免有写增删查改的时候有重复代码并且比较死,不够灵活,当表中的属性很多很多的时
候,更加不方便于我们访问。在没有使用框架之前,开始学习的时候第一次写的时候我也是这样的,以findbyId为例子:
代码图:
![图片](https://i-blog.csdnimg.cn/blog_migrate/98cba2394a5d046de53b51b2fc0b4609.png)
第一步优化,很简单。。。
将公共代码提取,如上form.setALL 提取此类中一个静态的方法中 static formMapping()
![图片](https://i-blog.csdnimg.cn/blog_migrate/6712d2027af461be011f16498932405f.png)
如此改进之后,其实我们的增删改查操作还是需要在每个DaoImpl中实现,这样的工作还是有些累赘。其实发现,增删改查操作的代码如此类似,只是有三个地方不一样:1.String型的SQL代码不一样 2.还有对于?(问号)的赋值不一样 3.有时需要返回的结果集的映射到bean中也是不一样的(返回结果集封装到Bean中,如返回一个User) 于是第二次优化如图:
![图片](https://i-blog.csdnimg.cn/blog_migrate/b333fabecd99f668f4894dfb4cb1971a.png)
为了解决以上三点,创建一个抽象类AbstractDao 在其中写好和具体实现类差不多的非抽象的增删查改的公用方法,将参数改为String型的SQL(select username from User where id=?等)的参数和对问号赋值时的参数。此时对问好赋值的参数就为一个Object[]的对象数组,而不是之前的具体memoid或者替他的什么,这样就可以灵活应对各种类型的参数了。
我们在抽象类中,每个方法中都是同样的代码:
![图片](https://i-blog.csdnimg.cn/blog_migrate/e6418ed7f35ff7a6a9dcb1ddfeb4c320.png)
重点就是object =rowMapping() 哪个类需要调用此findUser方法时,就需要重写rowMapping行集映射的方法,将返回的数据封装到Bean中。这行代码还体现了java中一个的特性:多态。理解了之后更让人理解到多态的好处。其实这里就包含了一种java23种设计模式中的模板设计模式,用一个抽象类当模板,子类继承调用模板中的方法。 优化到这一步,其实代码已经比第一次高效多了。
但是,问题很快也就暴露出来了。。。》》》》
抽象方法rowMapping只写了一个,实现抽象方法肯定需要具体的子类来实现,因为子类才知道怎么做,如果子类需要调用findUserById,findUsername等两个及以上的操作,需要实现的rowMapping肯定不同,一个返回一个User的信息,一个返回String型的Username,但实现rowMapping也只能实现一个。所以这样的问题还需要解决。。。。。》》》
接下来是第三步优化,既然抽象类不能解决,接口总可以吧。定义一个接口RowMapper,只有rowMapping一个抽象方法,为了不让自己犯晕,方法名为:rowMapper() :
![图片](https://i-blog.csdnimg.cn/blog_migrate/42fad3661fcb087e215b73f1c9c41f1d.png)
在DaoImpl实现的时候,不再继承AbstractDao,抛弃第二次优化的结果,开始学的时候还很郁闷,花了时间弄懂模板设计模式之后,却不合适,需要再改,不过很有帮助的。
我们不再调用父类AbstractDao的增删查改方法,抛弃抽象类不使用,而是重新写一个类叫做MyDaoTemplate 此类中的增删改查的代码和AbstractDao中代码几乎一样,只是去掉抽象方法,并在增删改查的参数上增加一个RowMapper接口。将实现RowMapper的接口的类也传进去,让MyDaoTemplate的方法不止有String型的SQL,对?号赋值的参数数组,还有实现结果集映射抽象类RowMapper的具体实现类。
![图片](https://i-blog.csdnimg.cn/blog_migrate/b04bb35876ba2a6d12dc876813a54c0c.png)
用接口的方式传入具体的结果集映射方法的类也叫做策略设计模式,应对不同的操作用不同的方法,对于策略模式的使用还太少,自己需要更多深入学习。
![图片](https://i-blog.csdnimg.cn/blog_migrate/75e9f5e33ed2f196af3d3c01607ddba1.png)
这三步的优化已经大大减少了码农们的工作量。以后如果需要一个Dao实现的时候直接继承AbstractDao,和实现RowMapper的结果集映射方法即可。再也不用一个一个增删改查的写了,算算多少行吧! ~~~~在实现接口RowMapper的时候,可以使用内部内的方法:
![图片](https://i-blog.csdnimg.cn/blog_migrate/b09b065a73cde85934ce958a6d9468f2.png)
熟悉内部类的同学的同学,一看就懂了,这些都是java的经典啊。
以上优化包含了接口,抽象类,多态,继承,封装,模板设计模式 ,策略设计模式 。设计模式还有很多,具体应用时的学习才是最深刻的。
当我们使用Spring框架中的Template工具类的RowMapper方法的时候,Spring框架也是对JDBC API进行如上第三步优化的封装,对自己代码如此优化之后,面对Spring 框架的部分使用也更加明白了。。。
此篇总结之后更加对框架产生兴趣了。