百度百科:
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。
iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)
前面使用的是jdbcTemplate,不夠方便,現在我們把他和mybatis整合
需要的jar
一個用來和spring無縫對接,一個是mybatis的核心包
首先需要增加配置文件
<!-- myBatis文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自動掃描映射文件 -->
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bbs.dao.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
這一段是固定格式的哈, dataSource是我們的數據源也就是連接數據庫用的,之前設置過來的
使用mybatis一般我們需要兩個文件,一個就是mapper映射接口,一個就是xml,里面寫的sql
說白了就是mybaits把xml中的sql,處理后,可以通過mapper中的接口調用
注意,接口名字就是xml中的id
所以說到這也可以明白了,上面的自動掃描映射文件的xml就是我們寫sql的地方
下面的就是mapper接口對應的包,它里面寫的都是mapper接口
所以你要用的話,copy過去,修改一下這兩個位置就好了
還有就是要知道,對照eclipse的話,創建項目后src就是這個classpath的哈
具體的請仔細學習mybaits
配置文件可以單獨配置,也可以直接寫道ApplicationContext,xml的,現在我們就是寫在一起的
然后就是在項目里面把文件新建一下
新建一個包,com.bbs.dao.mapper 里面新建兩個接口
src下面新建一個文件夾,mapper,里面新建兩個配置文件
如下圖所示
配置文件設置好了之后,文件也都創建好了
就是要寫sql以及接口了
sql自然是要按照人家的規則來寫了
UserMapper.xml
<?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.bbs.dao.mapper.UserMapper"> <select id="getMatchCount" parameterType="com.bbs.domain.User" resultType="java.lang.Integer"> SELECT count(*) FROM t_user WHERE user_name=#{userName} and password=#{password} </select> <select id="findUserByUserName" parameterType="com.bbs.domain.User" resultType="com.bbs.domain.User"> SELECT t_user.user_id as userId, t_user.user_name as userName, t_user.credits as credits, t_user.password as password, t_user.last_ip as lastIp, t_user.last_visit as lastVisit FROM t_user WHERE user_name=#{userName} </select> <update id="updateLoginInfo" parameterType="com.bbs.domain.User"> UPDATE t_user <set> <if test="lastVisit !=null"> last_visit = #{lastVisit}, </if> <if test="lastIp !=null and lastIp !=''"> last_ip = #{lastIp}, </if> <if test="credits !=null and credits !=''"> credits = #{credits}, </if> </set> where user_id=#{userId} </update> <insert id="insertUser" parameterType="com.bbs.domain.User"> insert into t_user( user_name, credits, password, last_ip, last_visit ) values( #{userName}, #{credits}, #{password}, #{lastIp}, #{lastVisit} ) </insert> <update id="updateUserInfo" parameterType="com.bbs.domain.User"> UPDATE t_user <set> <if test="lastVisit !=null"> last_visit = #{lastVisit}, </if> <if test="lastIp !=null and lastIp !=''"> last_ip = #{lastIp}, </if> <if test="credits !=null and credits !=''"> credits = #{credits}, </if> </set> where user_id=#{userId} </update> </mapper>
LoginLogMapper.xml
<?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.bbs.dao.mapper.LoginLogMapper"> <insert id="insertLoginLog" parameterType="com.bbs.domain.LoginLog"> insert into t_login_log( user_id, ip, login_datetime ) values( #{userId}, #{ip}, #{loginDate} ) </insert> </mapper>
說到這,說點常見的問題
1,數據庫中的字段名字和java代碼中的名字,要注意,如果不一樣記得select的時候要as一下為代碼中的,不然人家怎么知道如何映射
2,insert,update的時候,前面的是數據庫的,后面的是java代碼的
3.使用if判斷入參條件的時候要小心
比如此處的lastVisit是數據庫中datetime格式的,java代碼中是Date(util)類型的,使用if的時候這個lastvisit就不能跟下面lastIp似得有一個什么and lastIp!='',因為是一個時間對象嘛,比較的時候當做字符串了,你要是用了就會報錯,
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
..........
就是sql嘛,注釋也都沒寫,畢竟是簡單的例子
接着是跟xml映射的接口
UserMapper.java
package com.bbs.dao.mapper; import com.bbs.domain.User; public interface UserMapper { public Integer getMatchCount(User user); public User findUserByUserName(User user); public void updateLoginInfo(User user); public void insertUser(User user); public void updateUserInfo(User user); }
LoginLogMapper.java
package com.bbs.dao.mapper; import com.bbs.domain.LoginLog; public interface LoginLogMapper { public void insertLoginLog(LoginLog loginLog); }
這樣子就可以通過mapper接口執行sql了
之前的時候我們的接口寫的不怎么規范,我們現在規范一下
把原來的userService.java拆分下
拆解成
UserService.java
LoginLogService.java
這兩個接口
實際使用的時候,使用他們的實現類
面向接口的編程嘛,好處自行百度
UserService.java
package com.bbs.service; import com.bbs.domain.User; public interface UserService { public Boolean hasMatchUser(User user); public User findUserByUserName(User user); public void loginSucess(User user); public void insertUser(User user); public void UpdateUser(User user); }
UserServiceImpl.java
package com.bbs.service; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.bbs.dao.mapper.UserMapper; import com.bbs.domain.LoginLog; import com.bbs.domain.User; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private LoginLogService loginLogService; @Override public Boolean hasMatchUser(User user) { Integer matchCount = userMapper.getMatchCount(user); if(matchCount > 0){ return true; }else{ return false; } } @Override public User findUserByUserName(User user) { return userMapper.findUserByUserName(user); } @Override public void loginSucess(User user) { user.setCredits(5+user.getCredits()); user.setLastVisit(new Date()); LoginLog loginLog = new LoginLog(); loginLog.setUserId(user.getUserId()); loginLog.setIp(user.getLastIp()); loginLog.setLoginDate(new Date()); userMapper.updateLoginInfo(user); loginLogService.insertLoginLog(loginLog); } @Override public void insertUser(User user) { userMapper.insertUser(user); } @Override public void UpdateUser(User user) { userMapper.updateUserInfo(user); } }
LoginLogService.java
package com.bbs.service; import com.bbs.domain.LoginLog; public interface LoginLogService { public void insertLoginLog(LoginLog loginLog); }
LoginLogServiceImpl.java
package com.bbs.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.bbs.dao.mapper.LoginLogMapper; import com.bbs.domain.LoginLog; @Service public class LoginLogServiceImpl implements LoginLogService { @Autowired private LoginLogMapper loginLogMapper; @Override public void insertLoginLog(LoginLog loginLog) { loginLogMapper.insertLoginLog(loginLog); } }
這樣子接口和他的實現類都寫好了
要注意到,@service 和@Autowired哈
那么到現在為止,項目的邏輯就是這樣子的了
spring+mybaits
配置文件中配置了數據庫等信息,配置了需要自動掃描的一些包,要掃描包中的注解嘛,重要的還整合了mybatis
通過mybatis來操作數據庫,mapper來直接調用
改造成了面向接口的編程
通過userService和LoginLogService來調用,實際上執行的還是實現類嘛
實現類通過組合調用mapper提供的接口,來操作數據庫,來操作數據
項目的改造完成了
測試也要修改一下了..
package test.bbs.service; import static org.junit.Assert.*; import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.bbs.domain.User; import com.bbs.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/applicationContext.xml"}) public class TestUserService { @Autowired private UserService userService; @Test public void hasMAtchUser(){ User user1 = new User(); User user2 = new User(); user1.setUserName("admin"); user1.setPassword("123456"); user2.setUserName("admin"); user2.setPassword("11111"); boolean b1 = userService.hasMatchUser(user1); //boolean b2 = userService.hasMatchUser(user2); assertTrue(b1); //assertTrue(b2); } @Test public void findUserByUserName(){ User user = new User(); user.setUserName("admin"); User user1 = userService.findUserByUserName(user); System.out.println(user1.getUserName()); assertEquals(user1.getUserName(),"admin"); } @Test public void loginSucess(){ User user = new User(); user.setUserName("admin"); user= userService.findUserByUserName(user); userService.loginSucess(user); } @Test public void insertUser(){ User user = new User(); user.setUserName("user1"); user.setPassword("123456"); user.setCredits(0); user.setLastIp("255.255.255.255"); user.setLastVisit(new Date(0) ); userService.insertUser(user); } @Test public void updateUserInfo(){ User user = new User(); user.setUserId(2); user.setLastVisit(new Date() ); user.setCredits(5+user.getCredits()); userService.UpdateUser(user); } }
目測都執行成功了哈
以上就是spring+mybatis的一個基本項目(后台)
spring原理 實踐解析-簡單的helloworld
spring原理案例-基本項目搭建 01 spring framework 下載 官網下載spring jar包
spring原理案例-基本項目搭建 02 spring jar包詳解 spring jar包的用途
spring原理案例-基本項目搭建 03 創建工程運行測試 spring ioc原理實例示例
springmvc整合mybatis完整項目示例
springmvc 項目完整示例01 需求與數據庫表設計 簡單的springmvc應用實例 web項目
springmvc 項目完整示例02 項目創建-eclipse創建動態web項目 配置文件 junit單元測試
springmvc 項目完整示例04 整合mybatis mybatis所需要的jar包 mybatis配置文件 sql語句 mybatis應用
springmvc 項目完整示例05 日志 --log4j整合 配置 log4j屬性設置 log4j 配置文件 log4j應用
springmvc 項目完整示例06 日志–log4j 參數詳細解析 log4j如何配置
springmvc 項目完整示例07 設置配置整合springmvc springmvc所需jar包springmvc web.xml文件配置
springmvc 項目完整示例08 前台頁面以及知識點總結
maven項目整合springmvc整合mybatis