1. ibatis 框架通过对象和SQL 之间映射来完成持久化工作的。
2. ibatis框架的搭建
(1)所需的架包:ibatis.jar mysql-connector-java-bin.jar
(2)配置数据源: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>
<!-- 数据库连接方面的一些配置 -->
<settings cacheModelsEnabled="true" enhancementEnabled="true"
lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="50"
maxSessions="30" maxTransactions="20" useStatementNamespaces="true" />
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="com.mysql.jdbc.Driver" />
<property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost:3306/ibatis" />
<property name="JDBC.Username" value="root" />
<property name="JDBC.Password" value="kimi19891108" />
</dataSource>
</transactionManager>
<!-- 映射文件的配置,如果有多个映射文件一定要将userStatementNamespaces设置为true -->
<sqlMap resource="com/perhaps_love/bean/Users.xml"/>
</sqlMapConfig>
(3)配置JavaBean和SQL之间的映射:Users.xml
说明; 1. Users.xml最好和User,java放在同一目录,一个实体bean一个配置文件相对应。
2. namespace是ibatis方便查找,且对于开发者来说区分不同JavaBean的dao操作。可以提高可读性:
sqlMapper.insert("User.insert",user);
3. typeAlias 相当于名字较长的类取别名。这样当配置文件的其他地方(如parameterClass)需要用这个类的时候就可以通过引用这个较短的别名来
引用这个类。
4. ibatis 根据一个HashMap里面提供的动态条件进行查询的<dynamic>标签
5. <iterate>标签。
5. <selectKey>标签。
此标签的用途是:当你插入一条数据,但你想立刻就得到插入数据的id,这时用selectKey标签,且将type属性设置为"post",可以完成。
(1) 将数据库的id字段设置为 自动增加
(2) 在insert SQL语句前加:
<selectKey resultClass="Integer" keyProperty="id" type="post">
SELECT LAST_INSERT_ID() <!-- 这是针对MySQL数据库的语句 -->
</selectKey>
(3) type: post 或是 pre 先运行selectKeyt中的语句还是先执行insert语句。通常选取post。
post: 先执行insert语句,后去mysql缓存中读取最后最近插入的id。这样通常取出来的是刚才插入数据的自动生成的主键。
pre : 先执行last_insert_id()函数,由于mysql数据库的缓存id时间较短。很容易使结果为0。
--------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-iabtis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
<typeAlias alias="Users" type="com.lovee.model.User" />
<resultMap class="Users" id="UsersResult">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="password" column="password" />
</resultMap>
<!-- 插入新的user -->
<insert id="insertUser" parameterClass="Users">
INSERT INTO users( name,
password ) VALUES ( #name#,
#password# )
</insert>
<select id="selectUserById" parameterClass="int" resultClass="Users">
SELECT
id,
name,
password
From users
WHERE id=#id#
</select>
<select id="selectAllUsers" resultMap="UsersResult">
SELECT
*
From users
</select>
<select id="getUsersNum" resultClass="int">
SELECT
count(*)
From users
</select>
<select id="checkUser" parameterClass="Users" resultClass="int">
SELECT
count(*)
From users
WHERE
name=#name#
And
password=#password#
</select>
<--
动态查询,用于一些多条件查询。
如将一些参数:name: 2 password:3 放入hashMap中。
ibatis的isPropertyAvailbel 表示如果hashMap中有这个key,则取出值。否则忽略。
ibatis提供了很多像这样的标签 如isNull等。可以好好研究一下。
-->
<select id="getUsersByCondition" parameterClass="java.util.HashMap"
resultMap="UsersResult">
SELECT
*
From users
<dynamic prepend="WHERE">
<isPropertyAvailable property="id" prepend="and">
id=#id#
</isPropertyAvailable>
<isPropertyAvailable property="name" prepend="and">
name=#name:VARCHAR#
</isPropertyAvailable>
<isPropertyAvailable property="password" prepend="and">
password=#password:VARCHAR#
</isPropertyAvailable>
</dynamic>
</select>
<!--
dynamic的是各类的条件是and即都符合,那么这里的iterate是集合中一个条件符合就好。
-->
<select id="batchUsersByIds" parameterClass="java.util.HashMap"
resultMap="UsersResult">
SELECT *
From users
WHERE ID in
<iterate property="ids" open="(" close=")" conjunction=",">
#ids[]#
</iterate>
</select>
</sqlMap>
(4)若项目不用spring等容器框架,新建一个IbatisUtil类,用来辅助Ibatis的一些配置文件的读取。
说明:1. SqlMapConfig.xml配置文件放在src目录下,不然会加载不到配置文件
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class IbatisUtil {
public static SqlMapClient getSqlMapclient()
{
try{
//读取配置文件
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
//获取SqlMapClient
SqlMapClient sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
return sqlMapper;
}catch(Exception e){
System.out.println("加载sqlmap错误:");
e.printStackTrace();
return null;
}
}
}
(5)dao层调用:
package ibatis.dao;
import java.sql.SQLException;
import ibatis.bean.User;
import ibatis.utils.IbatisUtil;
public class UserDao {
//新增一个用户
public void insertUser(User user) throws SQLException
{
IbatisUtil.getSqlMapclient().insert("User.insertUser", user);
}
}
(6)返回结果:
1:insert返回的结果是插入值的id值,但是前提是插入表的id是auto_increment或是Sequence的。
所以insert要注意的是 !并非任何表的insert操作都会返回主键----这是一个陷阱!。
2:update delete返回的是影响的行数。
3. ibatis 和Spring的整合
(1)读取数据源就归spring管理了。
spring数据源配置以及spring一些将要用到的一些的依赖注入:application-datasource.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 建立数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/DocumentFlowSystemWithJBPM"></property>
<property name="username" value="root"></property>
<property name="password" value="kimi19891108"></property>
</bean>
<!--读取ibatis的配置文件,主要是读取JavaBean的xml文件>
<!--sqlMapClient依赖datasource-->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="WEB-INF/SqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<!--sqlMapClientTemplate依赖sqlMapClient -->
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>
</beans>
(2)dao层service层的依赖注入略~
(3)dao层,service层代码
dao层:
package com.perhaps_love.dao;
import java.util.List;
import java.util.Map;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.perhaps_love.bean.User;
public class UserForeDaoImpl extends SqlMapClientDaoSupport implements UserForeDao {
@SuppressWarnings("unchecked")
public List<User> batchUsersByCodition(Map<String, String> map) {
//正因为前面配置中将SqlMapClient注入了SqlMapCLientTemplate,所以可以调用。
return getSqlMapClientTemplate().queryForList("User.batchUsersByCondition", map);
}
}
service层:
package com.perhaps_love.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.perhaps_love.bean.User;
import com.perhaps_love.dao.UserForeDao;
public class UserForeServiceImpl implements UserForeService {
private UserForeDao userForeDao;
private static Logger log = Logger.getLogger(UserForeServiceImpl.class);
public User login(String work_no, String password) {
if (null == work_no || null == password) {
log.error("Parameter error");
return null;
}
// 封装参数
Map<String, String> map = new HashMap<String, String>();
map.put("work_no", work_no);
map.put("password", password);
/**
* 验证用户,若正确返回一个size为1的list 根据list的size返回
*/
List<User> list = userForeDao.batchUsersByCodition(map);
if (1 == list.size()) {
return list.get(0);
} else {
return null;
}
}
public UserForeDao getUserForeDao() {
return userForeDao;
}
public void setUserForeDao(UserForeDao userForeDao) {
this.userForeDao = userForeDao;
}
}