一、新建工程,添加ibatis、spring和struts的jars;
二、数据库设计.
mysql数据库:
use ibatis; drop table if exists user; create table if not exists user( ID tinyint primary key auto_increment, LOGIN_NAME varchar(10) not null, PASS_WORD varchar(15) not null, QX varchar(10) default 'guest' not null , MEMO text ) type=innodb comment="user info"; insert into user(LOGIN_NAME,PASS_WORD,QX) values('leh','888','admin'); insert into user(LOGIN_NAME,PASS_WORD) values('lek','888'); commit;
数据源的配置
1)、配置文件db.properties (位置:resources/properties/db.properties,这里resources和src是一类文件)
driver=com.mysql.jdbc.Driver url=jdbc\:mysql\://localhost\:3306/ibatis username=root password=54321
2)、注册数据源到spring
!-- spring load dataSource configuration property file --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>properties/database.properties</value> </list> </property> </bean> <!-- dataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </bean>
三、POJO类.
本例是User实例类:
package com.leadtone.ibatis.domain; import java.io.Serializable; public class User implements Serializable{ private int id; private String name; private String password; private String qx; private String memo; public int getId() { return id; } /** *setter和getter方法省略 */
四、pojo类配置文件编写
本例是User.xml:(位置:com.leadtone.sqlmap.User.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="User"> <typeAlias alias="user" type="com.leadtone.ibatis.domain.User"/> <resultMap class="user" id="UserResult"> <result property="id" column="ID"/> <result property="name" column="LOGIN_NAME"/> <result property="password" column="PASS_WORD"/> <result property="qx" column="QX"/> <result property="memo" column="MEMO"/> </resultMap> <!-- query all Users --> <select id="selectAllUsers" resultMap="UserResult"> select * from user </select> <!-- query user by id --> <select id="selectUserById" parameterClass="int" resultMap="UserResult"> select ID,LOGIN_NAME,PASS_WORD,QX,MEMO from user where ID=#id# </select> <!-- query user by user --> <select id="selectUserByUser2" parameterClass="map" resultMap="UserResult"> select ID,LOGIN_NAME,PASS_WORD,QX,MEMO from user <dynamic prepend="where"> <isNotEmpty prepend="and" property="name"> LOGIN_NAME=#name# </isNotEmpty> <isNotEmpty prepend="and" property="password"> PASS_WORD=#password# </isNotEmpty> </dynamic> </select> <select id="selectUserByUser" parameterClass="user" resultMap="UserResult"> select ID,LOGIN_NAME,PASS_WORD,QX,MEMO from user <dynamic prepend="where"> <isNotEmpty prepend="and" property="name"> LOGIN_NAME=#name# </isNotEmpty> <isNotEmpty prepend="and" property="password"> PASS_WORD=#password# </isNotEmpty> </dynamic> </select> <select id="selectUsersByName" parameterClass="String" resultMap="UserResult"> select ID,LOGIN_NAME,PASS_WORD,QX,MEMO from user <dynamic prepend="where"> <isNotEmpty prepend="and" property="value"> sname like '%$value$%' </isNotEmpty> </dynamic> </select> <!-- <insert id="addUser" parameterClass="User"> insert into user(LOGIN_NAME,PASS_WORD,QX,MEMO ) values(#name#,#birth#,#score#) <selectKey keyProperty="id" resultClass="int"> select last_insert_id() </selectKey> </insert> <!-- 注意这里的keyProperty="id" 中的id就是User中的id属性,resultClass就是查询的的返回值 --> --> <update id="updateUser" parameterClass="User"> update user set LOGIN_NAME=#name#,PASS_WORD=#password#,QX=#qx#,memo=#memo# where ID=#id# </update> <delete id="deleteUser" parameterClass="int"> delete from user where ID=#id# </delete> </sqlMap>
【补充:】动态sql:
一般来说,拼接动态sql是在查询时,指定多个查询条件的情况下用的,所以用到parameterClass= (map或具体类),
但对于传递过来的参数就一个时,若如下代码就会出错:
<select id="selectUserById" parameterClass="int" resultMap="UserResult"> select sid,sname,smajor,sbirth,score from users <dynamic prepend="where"> <isNotEmpty prepend="and" property="id"> sid=#id# </isNotEmpty> </dynamic> </select>
会报错误如下:There is no READABLE property named 'id' in class 'java.lang.Integer'
因为你无缘故用了一个莫名其妙的property="id",id对ibatis来说不认识。
这时的解决办法有两种,一个是这里的property="id" 中的id用value来代替,所以下面的sid=#value#,这个value是ibatis内部指定个变量;另一个方法是直接把property="id"删除,不用property这个属性了。
五、ibatis主配置文件编写【主配置文件只剩下sqlMap了,事务和数据源都交给spring进行配置和管理】
本例为sql-map-config.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> <sqlMap resource="com/leadtone/ibatis/sqlmap/User.xml"/> <!-- <sqlMap resource="com/leadtone/ibatis/sqlmap/User1.xml"/> <sqlMap resource="com/leadtone/ibatis/sqlmap/User2.xml"/> <sqlMap resource="com/leadtone/ibatis/sqlmap/Usern.xml"/> --> </sqlMapConfig>
六、dao接口和接口实现
1)、本例为UserDao:
package com.leadtone.ibatis.dao; import java.util.List; import com.leadtone.ibatis.domain.User; public interface IUserDao { public List<User> queryAllUsers(); public User queryUserById(int id); public User queryUserByUser(User user); public List<User> queryUserByName(String name); public void addUser(User user); public void addUserBySequence(User user); public void updateUser(User user); public void deleteUser(int id); }
2)、实现类UserDaoImpl:
package com.leadtone.ibatis.dao.ibatis; import java.util.List; import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; import com.leadtone.ibatis.dao.IUserDao; import com.leadtone.ibatis.domain.User; public class UserDaoImpl extends SqlMapClientDaoSupport implements IUserDao { //注意这里的SqlMapClient接口的声明和下面的static静态代码都不需要了, // 因为这里继承了spring提供的ibatis模板template类SqlMapClientDaoSupport,不是用原生的SqlMapClient //private static SqlMapClient sqlMapClient=null; /* static{ Reader reader=null; try { reader=Resources.getResourceAsReader("com/leadtone/ibatis/sqlmap/SqlMapConfig.xml"); sqlMapClient=SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } */ public void addUser(User user) { getSqlMapClientTemplate().insert("addUser", user); } public User queryUserByUser(User user) { System.out.println("---UserDaoImpl---"); return (User) this.getSqlMapClientTemplate().queryForObject("selectUserByUser", user); } /* * 这里主要演示一个模拟用户登录系统验证的操作,主要用了queryUserByUser(User user)方法 */ }
3)、在spring配置文件中配置这个bean
<!--sqlMapClient -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="sqlmap/sql-map-config.xml"/>
<property name="dataSource" ref="dataSource" />
</bean>
<!-- validate loginUser -->
<!-- dao -->
<bean id="userDao" class="com.leadtone.ibatis.dao.ibatis.UserDaoImpl">
<property name="sqlMapClient" ref="sqlMapClient "></property>
</bean>
七、service接口和接口实现
1)IUserLoginService接口
package com.leadtone.ibatis.service; import com.leadtone.ibatis.domain.User; public interface IUserLoginService { public boolean isLoginUser(User user); }
2)UserLoginSerivceImpl实现类
package com.leadtone.ibatis.service.impl; import com.leadtone.ibatis.dao.IUserDao; import com.leadtone.ibatis.domain.User; import com.leadtone.ibatis.service.IUserLoginService; public class UserLoginServiceImpl implements IUserLoginService { private IUserDao userDao; public IUserDao getUserDao() { return userDao; } public void setUserDao(IUserDao userDao) { this.userDao = userDao; } public boolean isLoginUser(User user) { return null!=userDao.queryUserByUser(user)?true:false; } }
3)在spring中注册这个bean
<!-- service --> <bean id="userLoginService" class="com.leadtone.ibatis.service.impl.UserLoginServiceImpl"> <property name="userDao" ref="userDao"></property> </bean>
八、struts action实现及struts-config.xml配置(牵扯到struts和spring的整合)
1)action:
package com.leadtone.web.struts.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import com.leadtone.ibatis.domain.User; import com.leadtone.ibatis.service.IUserLoginService; import com.leadtone.web.struts.form.LoginForm; public class LoginAction extends Action { private IUserLoginService userLoginService; public IUserLoginService getUserLoginService() { return userLoginService; } public void setUserLoginService(IUserLoginService userLoginService) { this.userLoginService = userLoginService; } public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { LoginForm loginForm = (LoginForm) form; String name=loginForm.getUsername(); String password=loginForm.getPassword(); User user=new User(); user.setName(name); user.setPassword(password); boolean isLogin=false; isLogin = userLoginService.isLoginUser(user); System.out.println(isLogin); if(isLogin){ request.setAttribute("username", name); return mapping.findForward("success"); } else return mapping.findForward("failure"); } }
2)actionForm:
public class LoginForm extends ActionForm { private String username; private String password; private String grade; public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { return null; } public void reset(ActionMapping mapping, HttpServletRequest request) { } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getGrade() { return grade; } public void setGrade(String grade) { this.grade = grade; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
3)xml:
<struts-config> <data-sources /> <form-beans > <form-bean name="loginForm" type="com.leadtone.web.struts.form.LoginForm" /> </form-beans> <global-exceptions /> <global-forwards /> <action-mappings > <action attribute="loginForm" input="/login.jsp" name="loginForm" path="/login" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"> <forward name="failure" path="/failure.jsp" /> <forward name="success" path="/succ.jsp" /> </action> </action-mappings> <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"></controller> <message-resources parameter="com.leadtone.web.struts.ApplicationResources" /> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="classpath:applicationContext.xml" /> </plug-in> </struts-config>
4)页面:
login.jsp
<body > <center> <html:form action="${Pagecontext.request.contextPath}/login" method="post"> <table border="1px" cellspacing="1px" cellpadding="1px" > <tr> <td>username : </td> <td><html:text property="username"/></td> <td><html:errors property="username"/></td> </tr> <tr> <td>password : </td> <td><html:password property="password"/></td> <td><html:errors property="password"/></td> </tr> <tr> <td>grade: </td> <td> <html:select property="grade"> <html:option value="guest">guest</html:option> <html:option value="admin">admin</html:option> </html:select> </td> <td><html:errors property="grade"/></td> </tr> <tr > <td colspan="3" valign="middle" align="center"><html:submit/> <html:cancel/></td> </tr> </table> </html:form> </center> </body>
succ.jsp
<body> welcome ${username}, <br> login successfully! </body>
falure.jsp
<body> sorry,login error<a href="login.jsp">relogin</a> </body>
5)web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
九、spring配置文件的内容【牵扯到ibatis和struts的整合】
<!-- action --> <bean name="/login" class="com.leadtone.web.struts.action.LoginAction" abstract="false" lazy-init="default" autowire="default" dependency-check="default"> <property name="userLoginService" ref="userLoginService"></property> </bean>
十、测试
这里的测试 包括单元测试。例如对dao层、service层、action层编写完成后都要进行junit4单元测试(Jmock或easyMock等)测试,这里就不添加了。
另外补充一点:
就是spring的配置文件中对事物拦截器的配置,也是必须的,这里没有配置,有兴趣的可以搜索一下添加上。