百度百科:
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