工程的结构:
一、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> <!-- 加载数据库属性文件 --> <properties resource="SqlMap.properties" /> <!-- 1、lazyLoadingEnabled:是否延迟加载(只加载必要信息而推迟其他未明确请求数据的技术),默认值是true。 2、cacheModelsEnabled:ibatis的高速缓存,将近期使用过的数据保存到内存中,值为true或false,全局控制sqlMapClient的缓存 3、enhancementEnabled:值true或false,作用用来表示是否使用cglib中那些已经优化的javabean类来提高延迟加载的性能。 4、useStatementNameSpaces:是否使用命名空间(true/false).假如使用在引用的时候需要加上(命名空间+ID) 来访问,默认是false。 5、 errorTracingEnabled:是否启用错误日志,在开发期间建议设为"true" 以方便调试 --> <settings cacheModelsEnabled="true" lazyLoadingEnabled="true" enhancementEnabled="true" errorTracingEnabled="true" useStatementNamespaces="true" /> <transactionManager type="JDBC"><!-- type指定事务管理器:JDBC,JTA,EXTERNAL, --> <dataSource type="SIMPLE"><!-- type值由:SIMPLE,DBCP,JNDI --> <property value="${JDBC.Driver}" name="JDBC.Driver" /> <property value="${JDBC.ConnectionURL}" name="JDBC.ConnectionURL" /> <property value="${JDBC.Username}" name="JDBC.Username" /> <property value="${JDBC.Password}" name="JDBC.Password" /> </dataSource> </transactionManager> <!-- 引入所有的SQL Map配置文件,这里的路径是classpath的相对路径 --> <sqlMap resource="com/wy/pojo/Customer.xml" /> </sqlMapConfig>
二、Customer.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 namespace="cust"> <!-- 类型别名 , 为一个pojo类取一个别名, 以便在下面用时候, 直接用别名引用对象 --> <typeAlias alias="Customer" type="com.wy.pojo.Customer" /> <!-- 数据返回类型,我用的是一张表 , id 与select 标签的id一致, 就可以指定返回是多个pojo,resultMap结果映射到预先定义的resultMap中 --> <resultMap class="Customer" id="getAllCustomer"> <result property="id" column="id" /> <result property="name" column="name" /> <result property="email" column="email" /> <result property="adress" column="adress" /> <result property="phone" column="phone" /> </resultMap> <!-- 根据自己的SQL查询语句, 及传入的参数来决定它的返回类型,resutlClass="返回类型" parameterClass="传入的参数类型" --> <select id="selectAllRecords" resultClass="Customer"> <![CDATA[ select * from customer ]]> </select> <select id="selectOneRecord" parameterClass="java.lang.Integer" resultMap="getAllCustomer"> <![CDATA[ select * from customer where id = #id# ]]> </select> <!-- #id#由方法的传入参数填充 --> <insert id="insertOneRecord" parameterClass="Customer"> <!-- 序列的返回值是int类型,最好对应数据库id列;keyProperty="id"的id是对应的BEAN里面的属性 --> <selectKey resultClass="int" keyProperty="id"> select customerPKSquence.nextVal as id from dual </selectKey> <!-- 屏蔽特殊符 --> <![CDATA[ insert into customer (id,name, email, adress, phone) values (#id#,#name#, #email#, #adress#, #phone#) ]]> </insert> <update id="updateOneRecord" parameterClass="Customer"> <![CDATA[ update customer set name=#name#, email=#email#, adress=#adress#,phone=#phone# where id=#id# ]]> </update> <delete id="deleteOneRecord" parameterClass="java.lang.Integer"> <![CDATA[ delete from customer where id = #id# ]]> </delete> </sqlMap>
扫描二维码关注公众号,回复:
843364 查看本文章
<statement id="statementName" [parameterClass="some.class.Name"] //表示输入的参数类型为Class [resultClass="some.class.Name"] //表示输出的参数类型为Class [parameterMap="nameOfParameterMap"] //表示输入的参数类型为Map [resultMap="nameOfResultMap"] //表示输出的参数类型为Class [cacheModel="nameOfCache"] > select * from t_user where sex = [?|#propertyName#] order by [$simpleDynamic$] </statement>
1、对于参数定义,尽量使用parameterClass,即直接将pojo作为statement的调用参数,如果输入的参数是java.util.map,那么map中的键值将作为输入参数,普通基本类型就是直接输入。
2、对于返回结果而言,尽量也使用resultClass,直接将字段名与pojo相对应。
3、而parameterMap与resultMap实现了pojo到数据库字段的映射配置,parameterMap 使用较少,而resultMap 则大多用于嵌套查询以及存储过程的 。
Customer.java
package com.wy.pojo; public class Customer { private Integer id; private String name; private String email; private String adress; public Customer() { } public Customer(Integer id, String name, String email, String adress, String phone) { super(); this.id = id; this.name = name; this.email = email; this.adress = adress; this.phone = phone; } public String getAdress() { return adress; } public void setAdress(String adress) { this.adress = adress; } private String phone; public String getEmail() { return email; } public Integer getId() { return id; } public String getName() { return name; } public String getPhone() { return phone; } public void setEmail(String email) { this.email = email; } public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } public void setPhone(String phone) { this.phone = phone; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("{"); sb.append("id:" + id + ","); sb.append("name:'" + name + "',"); sb.append("email:'" + email + "',"); sb.append("adress:'" + adress + "',"); sb.append("phone:'" + phone + "'"); sb.append("}"); return sb.toString(); } }
三、CustomerDaoImpl.java
package com.wy.dao.impl; import java.sql.SQLException; import java.util.List; import com.ibatis.sqlmap.client.SqlMapClient; import com.wy.dao.ICustomerDao; import com.wy.pojo.Customer; import com.wy.util.SQLMapClient; public class CustomerDaoImpl implements ICustomerDao { // 查询数据的SQL private static final String SELECT_All_CUSTOMERS = "cust.selectAllRecords"; private static final String SELECT_ONE_CUSTOMER = "cust.selectOneRecord"; //插入数据 private static final String INSERT_ONE_CUSTOMER = "cust.insertOneRecord"; //删除数据 private static final String DELETE_ONE_CUSTOMER = "cust.deleteOneRecord"; //修改 private static final String UPDATE_ONE_CUSTOMER = "cust.updateOneRecord"; private SqlMapClient sqlMapClient = null; public CustomerDaoImpl() { sqlMapClient = SQLMapClient.getSqlMapClient(); } //插入数据 @Override public void add(Customer student) { try { sqlMapClient.insert(INSERT_ONE_CUSTOMER, student); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //删除 @Override public void deleteCustomerById(int id) { try { sqlMapClient.delete(DELETE_ONE_CUSTOMER, id); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //查询所有数据 @SuppressWarnings("unchecked") @Override public List<Customer> queryAllCustomers() { // TODO Auto-generated method stub List<Customer> list = null; try { list = sqlMapClient.queryForList(SELECT_All_CUSTOMERS); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } public Customer queryOneCustomer(Integer id){ Customer customer = null; try { customer = (Customer) sqlMapClient.queryForObject(SELECT_ONE_CUSTOMER,id); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return customer; } //修改 public void update(Customer customer) { try { sqlMapClient.update(UPDATE_ONE_CUSTOMER, customer); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
四、 SQLMapClint.java
package com.wy.util; import java.io.IOException; import java.io.Reader; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; public class SQLMapClient { private static SqlMapClient sqlMapClient = null; static { String resource = "SqlMapConfig.xml"; Reader reader = null; try { //读取ClassPath下的配置文件 reader = Resources.getResourceAsReader(resource); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); } catch (IOException e) { e.printStackTrace(); }finally{ try { reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static SqlMapClient getSqlMapClient() { return sqlMapClient; } }
log4j.properties
#定义输出级别和输出平台 log4j.rootLogger=debug,consoleAppender #设定consoleAppender输出平台 log4j.appender.consoleAppender = org.apache.log4j.ConsoleAppender #输出信息的级别 #log4j.appender.consoleAppender.Threshold = info log4j.appender.consoleAppender.layout = org.apache.log4j.PatternLayout log4j.appender.consoleAppender.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}][%l]:%m%n log4j.appender.consoleAppender.ImmediateFlush = true #sqlMap 配置 log4j.logger.com.ibatis = DEBUG log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner = DEBUG log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = DEBUG log4j.logger.java.sql.Connection = DEBUG log4j.logger.java.sql.Statement = DEBUG log4j.logger.java.sql.PreparedStatement = DEBUG, consoleAppender log4j.logger.java.sql.ResultSet = DEBUG
五、测试 Test.java
package com.wy.test; import java.util.List; import org.apache.log4j.Logger; import com.wy.dao.ICustomerDao; import com.wy.dao.impl.CustomerDaoImpl; import com.wy.pojo.Customer; public class Test { private final static Logger log = Logger.getLogger(Test.class); public static void main(String[] args) { ICustomerDao customerDao = new CustomerDaoImpl(); //插入数据 Customer customers = new Customer(); customers.setName("wy"); customers.setPhone("13900000000"); customers.setEmail("[email protected]"); customers.setAdress("北京"); customerDao.add(customers); //修改数据 Customer cust = customerDao.queryOneCustomer(21); cust.setName("wywy"); customerDao.update(cust); //删除 customerDao.deleteCustomerById(4); //查询所有数据 List<Customer> list = customerDao.queryAllCustomers(); for (Customer customer : list) { log.info("id:" + customer.getId()); log.info("name:" + customer.getName()); log.info("phone:" + customer.getPhone()); log.info("email:" + customer.getEmail()); log.info("address:" + customer.getAdress()); } } }
下面是iBatis的配置关系图
遇到一个莫名其妙的错误:
Exception in thread "main" java.lang.ExceptionInInitializerError at com.wy.dao.impl.CustomerDaoImpl.<init>(CustomerDaoImpl.java:26) at com.wy.test.Test.main(Test.java:16) Caused by: java.lang.RuntimeException: Error occurred. Cause: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:49) at com.ibatis.sqlmap.client.SqlMapClientBuilder.buildSqlMapClient(SqlMapClientBuilder.java:63) at com.wy.util.SQLMapClient.<clinit>(SQLMapClient.java:19) ... 2 more Caused by: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:53) at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:46) ... 4 more Caused by: org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.endEntity(XMLDocumentFragmentScannerImpl.java:902) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.endEntity(XMLDocumentScannerImpl.java:605) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.endEntity(XMLEntityManager.java:1393) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1763) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.scanData(XMLEntityScanner.java:1242) at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanComment(XMLScanner.java:756) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanComment(XMLDocumentFragmentScannerImpl.java:1036) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2945) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:225) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) at com.ibatis.common.xml.NodeletParser.createDocument(NodeletParser.java:157) at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:50) ... 5 more
查了好久原因SqlMapConfig.xml中有一个注释后面没有加空格
<!-- 引入所有的SQL Map配置文件,这里的路径是classpath的相对路径-->引起。
加上空格后问题解决。不知道iBATIS为什么会出现这种问题!