实习期间在做任务的时候需要用到ibatis,公司系统所用框架是经理搭建的,也就是说我只要把ibatis的原理与用法搞定就行了,于是我一边看着系统的代码一边在网上搜索ibaits的demo!下面就把我对ibatis的初步认识写出来,欢迎大牛提出批评与建议!
iBATIS一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2002年发起的开放源代码项目。于2010年6月16号被谷歌托管,改名为MyBatis。是一个基于SQL映射支持Java和·NET的持久层框架。(百度百科-_-!!!),当我看到持久层框架的时候,我想到了hibernate,hibernate的使用我略知一二,难道它跟hibernate的使用有相同之处吗?
下面是ibatis的框架图:
我仔细的分析了下:
从上往下看,是不是可以这样理解,ibatis使用SqlMap.xml和SqlMapConfig.xml这两个配置文件完成对数据库的链接和各种JDBC操作呢?
从左往右看,是不是可以这样理解,可以把各种请求与参数通过javaBean、map、primitive和xml发送,然后再将结果一一的返回给他们呢?
有了猜测,接下来就是验证的时候了,我迫不及待的找了好多demo,通过这些demo我搭建了自己的demo。
首先是数据库部分
接下来就是数据表对应的实体类了BookInfo.java
package com.wxc.bean; public class BookInfo { private int id; private String bookISBN; private String bookName; private String author; private float price; private int typeId; private String publish; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookISBN() { return bookISBN; } public void setBookISBN(String bookISBN) { this.bookISBN = bookISBN; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getTypeId() { return typeId; } public void setTypeId(int typeId) { this.typeId = typeId; } public String getPublish() { return publish; } public void setPublish(String publish) { this.publish = publish; } @Override public String toString() { return "BookInfo:"+this.bookName+","+this.author+","+this.price+","+this.publish; } }
像hibernate一样它也有一个对应的映射文件BookInfo.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap> <!-- 通过typeAlias使得我们在下面使用BookInfo实体类的时候不需要写包名 --> <typeAlias alias="BookInfo" type="com.wxc.bean.BookInfo" /> <!-- 只需要在这里写sql语句参数什么的可以外部传进来 --> <!-- id表示select里的sql语句,resultClass表示返回结果的类型 --> <select id="listBookInfo" resultClass="BookInfo"> select * from bookinfo </select> <!-- parameterClass表示参数的内容 --> <!-- #表示这是一个外部调用的需要传进的参数,可以理解为占位符 --> <select id="listBookInfoByAuthor" parameterClass="String" resultClass="BookInfo"> select * from bookinfo where author = #name# </select> <!-- 修改 --> <update id="update" parameterClass="BookInfo"> update bookinfo set bookISBN=#bookISBN#, bookName=#bookName#, author=#author#, price=#price#, typeId=#typeId#, publish=#publish# where id=#id# </update> <!-- 删除 --> <delete id="delete" parameterClass="int"> delete from bookinfo where id = #id# </delete> <!-- 多条件查询 --> <select id="listByAuthorAndPublis" parameterMap="HashMap"> select * from bookinfo where author=#author# and publish=#publish# </select> </sqlMap>
写到这,是不是感到缺少什么文件啊,比如链接数据库的代码在哪,还有像hibernate还有一个总的配置文件啊,都在哪呢?现在就写数据库的链接代码!
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc\:mysql\://localhost\:3306/book?autoReconnect\=true&useUnicode\=true&characterEncoding\=utf8 jdbc.username=root jdbc.password=root
总的配置文件SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- 引入JDBC的配置文件 --> <properties resource="jdbc.properties" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="${jdbc.driverClassName}" /> <property name="JDBC.ConnectionURL" value="${jdbc.url}" /> <property name="JDBC.Username" value="${jdbc.username}" /> <property name="JDBC.Password" value="${jdbc.password}" /> </dataSource> </transactionManager> <!-- 引入各个类的实体映射文件 --> <sqlMap resource="com/wxc/bean/BookInfo.xml" /> </sqlMapConfig>
到这里还没有什么感觉,还是把dao和impl写出来再说
BookInfogDao.java
package com.wxc.dao; import java.util.List; import com.wxc.bean.BookInfo; public interface BookInfoDao { /** * 获取所有图书信息 */ public List<BookInfo> listBookInfo(); /** * 根据作者获取图书信息 */ public List<BookInfo> bookInfoByAuthor(String name); /** * 修改图书信息 */ public void update(BookInfo bookinfo); /** * 删除图书信息 */ public void delete(int id); /** * 注意这里的参数不是一个而是两个 * 根据作者与出版社获取图书信息 */ public List<BookInfo> listByAuthorAndPublish(String author,String publish); }
BookInfoDaoImpl.java
package com.wxc.impl; import java.io.Reader; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; import com.wxc.bean.BookInfo; import com.wxc.dao.BookInfoDao; public class BookInfoDaoImpl implements BookInfoDao { private static SqlMapClient sqlMapClient = null; //读取配置文件 static{ try { Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml"); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (Exception e) { e.printStackTrace(); } } @SuppressWarnings("unchecked") @Override public List<BookInfo> listBookInfo() { List<BookInfo> list = null; try { //注意第一个参数,是对应xml文件里的查询id list = this.sqlMapClient.queryForList("listBookInfo", null); } catch (Exception e) { e.printStackTrace(); } return list; } @SuppressWarnings("unchecked") @Override public List<BookInfo> bookInfoByAuthor(String name) { List<BookInfo> list = null; try { list = this.sqlMapClient.queryForList("listBookInfoByAuthor", name); } catch (Exception e) { e.printStackTrace(); } return list; } @SuppressWarnings("static-access") @Override public void update(BookInfo bookinfo) { try { this.sqlMapClient.update("update", bookinfo); } catch (SQLException e) { e.printStackTrace(); } } @SuppressWarnings("static-access") @Override public void delete(int id) { try { this.sqlMapClient.delete("delete", id); } catch (SQLException e) { e.printStackTrace(); } } @Override public List<BookInfo> listByAuthorAndPublish(String author, String publish) { Map mp = new HashMap(); mp.put("anthor", author); mp.put("publish", publish); List<BookInfo> list = null; try { list = this.sqlMapClient.queryForList("listByAuthorAndPublis", mp); } catch (SQLException e) { e.printStackTrace(); } return list; } }
到此,所有的文件都敲好了,只需要写一个测试类调用Impl里的方法就行了。这里说几点ibatis独特的地方,注意实体类的映射文件BookInfo.xml里有<select><update>和<delete>这些应该能看明白就是一些SQL操作的前缀,然后内部写的就是一些纯SQL语句,这里把SQL语句放在外部的写法我感觉就是ibaits的核心所在!然后注意parameterClass和resultClass这个就是声明从外部传达的参数属于什么类型,还有将传送出去的数据时什么类型,从上面的文件也能看出点门道!
还有一点,SQL语句引用外部参数的写法是“#params#”,有时候会遇到传来的参数是一个或者是一个类,这样好处理,比如上面的update和delete,有的时候是多条件处理应该怎么办,比如上面的“listByAuthorAndPublis”,这里就需要用到Map了,在dao里(对了,调用xml的查询方法在dao里有queryforlist()和queryforobject()看你需要什么样的操作了,里面的参数queryforlist(arg0,arg1)分别对应的是xml里的id和参数,这一点不能写错)就要事先定义一个map,然后将两个参数put进去,然后xml会根据key获取参数的值,如上面Impl代码里的“listByAuthorAndPublish”方法,这也是我建议大家用的方法,之前看到有的是这样写
xml
<select id="listByAuthorAndPublis" parameterMap="HashMap">
select * from bookinfo where author=#sql#
</select>
然后在java文件里这样写
String sql = author+"and publish"+publish;
也就是把sql语句从中间劈开,这样有的时候也许是通用的,但是也有特殊的时候,我就是被这样的写法坑了一次,所以建议大家还是用Map传递参数
到这里,有没有感到ibatis是一个持久层的框架啊,如果把hibernate比作是自动冲锋枪的话那ibatis数据半自动冲锋枪。sql语句还是需要自己写的!!!
好了,以上就是我对ibatis的初步认识,在以后如果有学到新的更近一层的知识,我会更新的!