最近项目中使用myBatis(iBatis),所以目前对所遇的一些问题及有些模糊的地方在这里标注一下。
首先mybaits是一个“半自动化”的ORM框架。
需要使用的jar包:mybatis-3.0.2.jar(mybatis核心包),mybatis-spring-1.0.0.jar(与spring结合jar包)这些jar可以去官网下载。
配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- 对在此配置文件下的所有cache进行全局性开/关设置 true|false true --> <setting name="cacheEnabled" value="true"/> <!-- 全局性设置懒加载。如果设为‘关',则所有相关联的都会被初始化加载。 --> <setting name="lazyLoadingEnabled" value="false"/> <!-- 当设置为‘开’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 --> <setting name="aggressiveLazyLoading" value="true"/> <!-- 允许和不允许单条语句返回多个数据集(取决于驱动需求) --> <setting name="multipleResultSetsEnabled" value="true"/> <!-- 使用列标签代替列名称。不用的驱动器有不同的作法。 --> <setting name="useColumnLabel" value="true"/> <!-- 允许JDBC生成主键。需要驱动器支持.如果设为了true,这个设置将强制使用被生成的主键, 有一些驱动器不兼容不过仍然可以执行。 --> <setting name="useGeneratedKeys" value="true"/> <!-- 指定MyBatis是否并且如何来自动映射数据表字段与对象的属性。PARTIAL将只自动映射简单的,NONE没有嵌套的结果。 FULL将自动映射所有复杂的结果。 --> <setting name="autoMappingBehavior" value="PARTIAL"/> <!-- 配置和设定执行器,SIMPLE执行器执行其它语句。REUSE执行器可能重复使用preparedstatements语句,BATCH执行器可以重复执行语句和批量更新。 --> <setting name="defaultExecutorType" value="SIMPLE"/> <!-- 设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时. 正整数 --> <setting name="defaultStatementTimeout" value="25000"/> </settings> <!-- 类型别名 --> <typeAliases> <typeAlias type="com.igit.storage.client.model.ClientRelation" alias="ClientRelation"/> </typeAliases> <!-- 分页查询拦截器 <plugins> <plugin interceptor="com.igit.storage.util.DiclectStatementHandlerInterceptor"></plugin> <plugin interceptor="com.igit.storage.util.DiclectResultSetHandlerInterceptor"></plugin> </plugins> --> <!-- 加载映射文件 --> <mappers> <mapper resource="com/igit/storage/client/model/ClientRelation.xml"/> </mappers> </configuration>
映射文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 定义命名空间 --> <mapper namespace="com.igit.storage.client.model.ClientRelation"> <resultMap type="ClientRelation" id="relationResult"><!-- 对象应用关联查询 --> <association property="client" column="clientId" javaType="Client" select="com.igit.storage.client.model.Client.selectById"> </association> </resultMap> <insert id="insert" parameterType="ClientRelation" useGeneratedKeys="true" keyProperty="id"> insert into S_ClientRelation(relation,clientId) values(#{relation},#{client.clientId}) </insert> <delete id="delete" parameterType="long" flushCache="true"> delete from S_ClientRelation where relation=#{value} </delete> <!-- flushCache="true" 清空缓存 --> <delete id="remove" parameterType="long" flushCache="true"> delete from S_ClientRelation where id=#{id} </delete> <!-- 批量删除多个,参数是数组 key为array map--> <delete id="removeMore" parameterType="map" flushCache="true"> delete from S_ClientRelation where id in <foreach collection="array" index="index" item="ids" open="(" separator="," close=")"> #{ids} </foreach> </delete>
<select id="selectById" resultMap="relationResult" parameterType="long"> select * from S_ClientRelation where id=#{value} </select> <select id="selectByRelation" resultMap="relationResult" parameterType="long"> select * from S_ClientRelation where relation=#{value} </select> <select id="selectByPage" resultMap="relationResult"> select * from S_ClientRelation </select> <select id="selectByCount" resultType="long"> select count(*) from S_ClientRelation </select> <select id="selectMaxRelation" resultType="long"> select max(relation) from s_clientRelation </select> </mapper>
修改application.xml文件
<!-- 因为Hibernate的TransactionManager可以向下兼容JdbcTransactionManager,所以 mybatis事务处理仍和hibernate共用--> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory" /> </property> </bean>
<!-- 用注解来实现事务管理 --> <tx:annotation-driven transaction-manager="transactionManager"/> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" /> </tx:attributes> </tx:advice>
<!-- mybatis sqlSessionFactory 注入datasource和配置文件--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatisconfig.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- 定义mybatis操作模板类似hibernateTemplate --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
代码实现
package com.igit.storage.client.service.imp; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.RowBounds; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.util.Assert; import org.springside.core.dao.Page; import com.igit.exception.BusinessException; import com.igit.storage.client.model.Client; import com.igit.storage.client.model.ClientRelation; import com.igit.storage.client.service.ClientRelationService; public class ClientRelationServiceImp implements ClientRelationService { private SqlSessionTemplate sqlSessionTemplate; /** * 新增关联客户 */ public void addRelationByClients(Long relation, List<Client> clients) { //判断该关联id是否存在 if(!isValidRelation(relation)){ throw new BusinessException("该关联关系不存在!"); } //新增关联客户 for(Client client : clients){ ClientRelation cr = new ClientRelation(); cr.setRelation(relation); cr.setClient(client); Assert.notNull(client, "客户不能为Null"); sqlSessionTemplate.insert(ClientRelation.class.getName()+".insert", cr); } } /** * 取消关联客户 */ public void cancelRelation(Long relation) { sqlSessionTemplate.delete(ClientRelation.class.getName()+".delete", relation); } /** * 创建关联客户 */ public void createRelation(List<Client> clients) { // 客户是否可以创建关联 if(clients.size()<=1){ throw new BusinessException("无法创建关联,关联客户不能低于2个!"); } ClientRelation cr = new ClientRelation(); cr.setRelation(getMaxRelation()); //创建关联客户 for(Client client : clients){ cr.setClient(client); Assert.notNull(client, "客户不能为Null"); sqlSessionTemplate.insert(ClientRelation.class.getName()+".insert", cr); } } /** * 获取最大关联ID * @return */ private Long getMaxRelation(){ Long relation = 1L; Long maxRelation = (Long) sqlSessionTemplate.selectOne(ClientRelation.class.getName()+".selectMaxRelation"); if(maxRelation==null){ return relation; } return maxRelation+1; } /** * 分页获取关联客户 */ public Page getClientRelationByPage(int startIndex, int pageSize) { List<ClientRelation> list = sqlSessionTemplate.selectList(ClientRelation.class.getName()+".selectByPage", new RowBounds(startIndex,pageSize)); Long totalCount = (Long) sqlSessionTemplate.selectOne(ClientRelation.class.getName()+".selectByCount"); return new Page(list,totalCount,pageSize,startIndex); } /** * 获取没有关联的客户列表 */ public Page getNoRelationClients(int startIndex,int pageSize) { List<Client> list = sqlSessionTemplate.selectList(Client.class.getName()+".selectSingleClient", new RowBounds(startIndex,pageSize)); Long totalCount = (Long) sqlSessionTemplate.selectOne(Client.class.getName()+".selectSingleCount"); return new Page(list,totalCount,pageSize,startIndex); } /** * 删除关联客户 */ public void removeRelationByClients(Long relation, List<Client> clients) { //1.该客户是否可以从关联中移除 List<ClientRelation> list = getRelationClients(relation); if((list.size()-clients.size())<=1){ throw new BusinessException("不允许删除,关联客户至少存在2个!"); } //2.移除客户 for(Client c : clients){ Map<String,Long> params = new HashMap<String,Long>(); params.put("relation", relation); params.put("clientId", c.getClientId()); sqlSessionTemplate.delete(ClientRelation.class.getName()+".remove", params); } } private boolean isValidRelation(Long relation) { List<ClientRelation> list = getRelationClients(relation); if(list.size()<=1){ return false; } return true; } private List<ClientRelation> getRelationClients(Long relation) { List<ClientRelation> list = sqlSessionTemplate.selectList(ClientRelation.class.getName()+".selectByRelation", relation); return list; } public SqlSessionTemplate getSqlSessionTemplate() { return sqlSessionTemplate; } public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { this.sqlSessionTemplate = sqlSessionTemplate; } }
单元测试请看上一篇文章