Ibatis的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd ">
<sqlMapConfig>
<settings
cacheModelsEnabled="true"
errorTracingEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="512"
maxSessions="384"
maxTransactions="256"
useStatementNamespaces="true"/>
<transactionManager type="JDBC"><!-- 定义事务管理器(JDBC/JTA,EXTERNAL) -->
<dataSource type="SIMPLE"><!-- 指定数据源的链接类型(SIMPLE,DBCP,JNDI) -->
<property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
<property name="JDBC.ConnectionURL" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="JDBC.Username" value="root"/>
<property name="JDBC.Password" value=""/>
</dataSource>
</transactionManager>
<!-- 添加的数据操作表文件 -->
<sqlMap resource="MyIbatis.xml" />
</sqlMapConfig>
映射关系的配置文件
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="TestBean">
<typeAlias alias="TestBean" type="TestBean" />
<resultMap id="TestBean" class="TestBean">
<result property="id" column="ID"/>
<result property="value" column="VALUE"/>
</resultMap>
<select id="QueryAll" parameterClass="string" resultClass="TestBean">
select *
from MyIbatis
</select>
<insert id="Add" parameterClass="TestBean">
insert into MyIbatis (
id,
value
) values (
#id#,
#value#
)
<selectKey resultClass = "int" keyProperty = "id" >
SELECT LAST_INSERT_ID()
</selectKey >
</insert>
</sqlMap>
使用Ibatis
一、创建一个空的java工程,引入ibatis和mysql驱动的jar包
二、编写java bean
public class TestBean {
private String id;
private String value;
public TestBean() {}
public TestBean(String id,String value) {
this.id = id;
this.value = value;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
三、初始化数据库,准备些数据
四、编写ibatis的配置文件和映射文件,如上所示
五、编写client程序,测试结果
import java.io.IOException;
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;
public class MyIbatis {
private SqlMapClient sqlMap;
MyIbatis() throws IOException {
String resource = "myProperty.xml";
Reader reader = Resources.getResourceAsReader(resource);
this. sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
}
public List<TestBean> QueryAll() throws SQLException {
return sqlMap.queryForList("TestBean.QueryAll");
}
public int Add(TestBean testBean) throws SQLException {
return (Integer) sqlMap.insert("TestBean.Add", testBean);
}
public static void main(String[] args) throws IOException, SQLException {
MyIbatis myIbatis = new MyIbatis();
List<TestBean> res = myIbatis.QueryAll();
System.out.println(res.get(0).getValue());
System.out.println(myIbatis.Add(new TestBean("12","456")));
}
}
Ibtatis备忘
命名空间:在配置文件中将命名空间使能置为true,以后使用statement的时候需要加上命名空间关键字
<settings
cacheModelsEnabled="true"
errorTracingEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="512"
maxSessions="384"
maxTransactions="256"
useStatementNamespaces="true"/>
<sqlMap namespace="TestBean">
public List<TestBean> QueryAll() throws SQLException {
return sqlMap.queryForList("TestBean.QueryAll");
}
结果集映射
结果集映射正如下所示:
<resultMap id="Result" class="TestBean">
<result property="id" column="ID"/>
<result property="value" column="VALUE"/>
</resultMap>
对比下采用结果集映射的前后:
//映射前
<select id="QueryAll" parameterClass="string" resultClass="TestBean">
select *
from MyIbatis
</select>
//映射后
<select id="QueryAll" parameterClass="string" resultMap="Result">
select *
from MyIbatis
</select>
貌似除了写法上不同也没什么区别,我总结有两个不同:一是为了结果集的继承;二是为了查询注入,先看下继承,查询注入下面有总结
<resultMap id="TestBeanExt" class="TestBean" extends="TestBean.TestBean">
<result property="ext" column="EXT"/>
</resultMap>
获取主键
插入语句之后配置:主要是针对自增主键的表而言,这类表在插入时不需要主键,而是在插入过程自动获取一个自增的主键。
<selectKey resultClass = "int" keyProperty = "id" >
SELECT LAST_INSERT_ID()
</selectKey >
STATEMENT入参
一、调用方法:parameterClass="类别名"
二、参数类型:可以为iBatis内置支持的类型,比如int、string;可以为map类型的参数;复杂对象的参数,比如“java.Util.HashMap”,"com.test.TestBean"
三、map是最强大的入参方式,任何入参方式都可以转换为这种入参方式,因为iBatis仅接受一个入参,当几个参数分布在不同对象中的时候,将这些对象的属性(或者对象本身put)到map中,然后一次传递给sql语句是非常有效。可以自己写一个将对象或者对象集合转换为map的工具。
四、参数的引用:iBatis内置支持的类型,使用#value#来引用,直接表示其值;map类型的参数,使用#keyName#来引用,keyName为键名;复杂对象的参数,使用#propertyName#来引用,propertyName类属性的名字。
五、模糊查询是针对字符串而言的,如果遇到两个单引号要包含一个参数,则不能再用#来引用变量了,而应该改为$,比如:'%$varName$%',当然,也可以使用 '%' || #varname# || '%' 来绕过此问题。
STATEMENT出参
一、参数类型:resultClass,reslutMap
二、调用方法:如本文中例子,有两种方法可以实现返回类型:reslutClass="TestBean"或者resultMap="Result"
三、二者区别:只不过一个用到了结果集映射的功能了而已,结果集有什么优点,它便有什么优点;值得注意的是,如果采用了resultClass的话,如果查询结果有些列不对应时,可以在sql中使用as重命名达到一致的效果
查询结果集分组
查询结果集排序有两种方式:一是在结果集映射上定义<resultMap groupBy="id">,另一种就是在SQL语句中分组。建议在SQL语句中分组,以获得更大的可控制性。
SQL片段
可以通过<sql>...</sql>定义SQL片段,然后<include refid="sql_xxx"/>来在各种语句中引用,达到复用目的。
动态SQL
<dynamic prepend="where">
<isNotEmpty prepend="and" property="***">
***
</isNotEmpty>
</dynamic>
prepend表示链接关键字,可以为任何字符串,当为sql关键字时,iBatis自动判断是否应该添加该关键字。该语法也很简单,关键是要会用心思考组织动态SQL。 这里面有一点要注意:区别<isNotEmpty>和<isNotNull>区别,当既不为null又非空时<isNotEmpty>返回true,当不为null时<isNotNull>返回真,我们一般采用isNotEmpty,因为空并无意义啊,当然要看具体环境了。
查询注入
查询注入是在一个查询中嵌入另外一个查询,这样做的目的是为了实现实体对象之间的关联关联关系(一对一、一对多、多对多)分单项双向。查询注入的实现就是在实体属性为另外一个实体或者实体集合的时候,引入一个相关的查询来实现,例如,客户和订单的映射关系:
public class Customer {
private Long id;
private String name;
private String address;
private String postcode;
private String sex;
private List<Orders> orderlist = new ArrayList<Orders>();
<resultMap id="result" class="customer">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="address" column="address"/>
<result property="postcode" column="postcode"/>
<result property="sex" column="sex"/>
<result property="orderlist" column="id" select="orders.findByCustomerId "/>
</resultMap>
<select id="findByCustomerId" resultMap="result_base" parameterClass="long">
select * from orders where customerId = #value#
</select>
在这个映射中,为了查询客户的时候,能查询到相关的订单,可以在映射orderlist 属性的时候,将其指向另外一个查询orders.findByCustomerId ,这个查询是以Customer的id 为参数来查询的。
分页查询
iBatis 的分页有两种方式:
第一种方式:结果集筛选分页。先执行部分页的SQL查询语句,然后得到一个 ResultSet,然后根据分页范围选择有效的记录填充到对象中,最终以集合的形式返回。对于10w条一下的记录的表,不存在性能问题,如果存在,你可以选择第二中方式。
第二种方式:SQL分页,通过组装分页类型的SQL来实现分页。这个关键在于分页参数的传递和分页SQL的构建。可以用map分装入参,连同分页参数一块传递进来。limit关键字可以实现分页查询。
高速缓存
ibatis提供了高速缓存的功能,只需要操作配置文件就可以实现缓存查询结果的目的,摘录网上一段总结:
http://wenku.baidu.com/view/0b93f5d8ad51f01dc281f1f2.html
http://www.iteye.com/topic/894922
Ibatis和Spring的集成
一、bean的定义,其实这就是一份ibatis的配置文件,只不过由spring代为解析和管理,就跟webx2的service框架变换为webx3的纯spring框架一样
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://10.20.159.103:3306/aliHome?characterEncoding=utf-8</value>
</property>
<property name="username">
<value>team1</value>
</property>
<property name="password">
<value>team1</value>
</property>
</bean>
<!-- ======================================================================== -->
<!-- TransactionManager定义。 -->
<!-- ======================================================================== -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>
<!-- ======================================================================== -->
<!-- iBatis SQL map定义。 -->
<!-- ======================================================================== -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/aliHome/dal/sqlmap-config.xml" />
</bean>
<!-- ======================================================================== -->
<!-- 用纯JDBC实现DAO的相关设置(可选)。 -->
<!-- ======================================================================== -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
二、sqlmap-config配置
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="sqlmap/Admin.xml"/>
<sqlMap resource="sqlmap/PageContent.xml"/>
<sqlMap resource="sqlmap/SubPage.xml"/>
<sqlMap resource="sqlmap/Message.xml"/>
<sqlMap resource="sqlmap/Image.xml"/>
<sqlMap resource="sqlmap/Vedio.xml"/>
</sqlMapConfig>
三、sqlmap的配置
不介绍了
四、dao的配置
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://toolkit.alibaba-inc.com/dtd/spring/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="adminDao" class="com.alibaba.aliHome.dal.dao.impl.AdminDaoImpl" />
<bean id="subPageDao" class="com.alibaba.aliHome.dal.dao.impl.SubPageDaoImpl" />
<bean id="pageContentDao" class="com.alibaba.aliHome.dal.dao.impl.PageContentDaoImpl" />
<bean id="messageDao" class="com.alibaba.aliHome.dal.dao.impl.MessageDaoImpl" />
<bean id="imgDao" class="com.alibaba.aliHome.dal.dao.impl.ImageDaoImpl" />
<bean id="vedioDao" class="com.alibaba.aliHome.dal.dao.impl.VedioDaoImpl" />
</beans>
上面的配置中没有把sqlMapClient的依赖配置进来是由于byName的原因。
五、下面就可以编写代码了
TODO