文章大纲
一、mybatis介绍
二、mybatis代码实战
三、项目源码下载
四、参考文章
一、mybatis介绍
1. mybatis是什么?
mybatis是一个持久层的框架,是apache下的顶级项目。mybatis托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)。
mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)
2. mybatis框架图解
二、mybatis代码实战
1. 创建maven的javaweb项目
文章重点在于讲解Spring mvc功能,因此创建项目方式不进行深入讲解,创建后的项目目录如下:
2. 创建数据库表
表名为:mybatis,表结构如下:
3. springmvc、mybatis基本配置
3.1 pom.xml添加maven相关依赖
4.0.0
mabatis_demo
mabatis_demo
0.0.1-SNAPSHOT
war
UTF-8
4.2.5.RELEASE
3.2.8
5.1.29
com.google.code.gson
gson
2.8.2
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
1.2.2
mysql
mysql-connector-java
${mysql-driver.version}
org.apache.openejb
javaee-api
5.0-1
provided
javax.servlet
jstl
1.2
provided
javax.servlet.jsp
jsp-api
2.1
provided
com.github.pagehelper
pagehelper
4.1.4
junit
junit
3.8.1
test
c3p0
c3p0
0.9.1.2
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.6
commons-beanutils
commons-beanutils
1.7.0
commons-codec
commons-codec
1.7
org.apache.commons
commons-io
1.3.2
commons-collections
commons-collections
3.2
commons-net
commons-net
3.0
org.apache.commons
commons-math3
3.2
commons-validator
commons-validator
1.4.0
commons-httpclient
commons-httpclient
3.1
commons-dbcp
commons-dbcp
1.4
commons-logging
commons-logging-api
1.1
commons-pool
commons-pool
1.6
org.springframework
spring-core
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-oxm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-aop
${spring.version}
org.springframework
spring-test
${spring.version}
org.apache.httpcomponents
httpclient
4.5.2
dom4j
dom4j
1.6.1
org.apache.shiro
shiro-core
1.3.2
org.apache.httpcomponents
httpmime
4.5.2
com.thoughtworks.xstream
xstream
1.4.9
ch.qos.logback
logback-classic
1.1.7
ch.qos.logback
logback-core
1.1.7
javax.validation
validation-api
1.1.0.Final
org.hibernate
hibernate-validator
5.4.0.Final
junit
junit
4.10
org.apache.maven.plugins
maven-compiler-plugin
1.8
src/main/java
**/*.xml
true
温馨提示:build中需要添加resources相关代码,否则项目编译后,mapper相关的xml不会保存到target中,导入操作mybatis失败。
3.2 web.xml添加相关配置
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
spring
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/applicationContext.xml
1
spring
/
index.jsp
温馨提示:
我们可能会在其他的项目中看到ssm(Spring、Spring mvc、mybatis)的配置文件都在同一个xml文件中,但是这样不好管理,在该文章中,我们的spring文件夹中的配置文件采用解耦方式进行配置,在web.xml中进行总的配置加载,再分别加载持久层、应用层、逻辑层,正常配置后的文件结构如下:
3.3 resources中添加logback.xml配置日志文件
//这里为此项目的日志文件夹名
//这里为日志的存储地址
${APP_Name}
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} [%file:%line] - %msg%n
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n
INFO
ACCEPT
DENY
${log.dir}/${APP_Name}/info/info.%d{yyyy-MM-dd}-%i.log
30
10MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n
DEBUG
ACCEPT
DENY
${log.dir}/${APP_Name}/debug/debug.%d{yyyy-MM-dd}-%i.log
30
10MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n
ERROR
${log.dir}/${APP_Name}/error/error.%d{yyyy-MM-dd}-%i.log
30
10MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n
DEBUG
${log.dir}/${APP_Name}/monitor/monitor.%d{yyyy-MM-dd}-%i.log
30
10MB
//上线时 这个需注释掉,debug级别的日志
3.4 resources中新建properties文件夹,并添加db.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=147258qq
新建后项目结构如下:
3.5 resources文件夹中新建spring文件夹,并创建相关依赖文件
新建applicationContext.xml
新建applicationContext-dao.xml
新建applicationContext-service.xml
新建applicationContext-web.xml
配置完成后项目结构如下:
4. 实现基本的增删改查
4.1 创建在com.wxc.vo包下创建测试的实体类
创建MsgVo.java
package com.wxc.vo;
/**
* 用于将数据返回给前端
*/
public class MsgVo {
private String code;
private String msg;
public MsgVo(String code, String msg) {
this.code = code;
this.msg = msg;
}
public MsgVo() {
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public void setCode(String code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
创建User.java
package com.wxc.vo;
public class User {
private int id;
private String name;
private String sex;
public User() {
}
public User(int id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
4.2 com.wxc.service包下创建TestMybatisService.java用于操作数据库的业务处理
package com.wxc.service;
import com.wxc.vo.User;
import com.wxc.vo.User_;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* 测试mybatis的基本使用
*/
@Service(value = "/testMybatisService")
public class TestMybatisService {
// 需要向dao实现类中注入SqlSessionFactory
// 这里通过构造方法注入
private SqlSessionFactory sqlSessionFactory;
//初始化SqlSessionFactory
private void initSqlSessionFactory() throws IOException {
// mybatis配置文件
String resource = "spring/applicationContext-dao.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
/**
* 新增用户
* @param user
* @return
*/
public int insertUser(User user) throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(user.toString());
//执行插入操作
int n = sqlSession.insert("com.wxc.mapper.UserMapper.insertUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
return n;
}
/**
* 删除用户
* @param id
* @return
*/
public int deleteUser(int id) throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
int n = sqlSession.delete("com.wxc.mapper.UserMapper.deleteUser", id);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
return n;
}
/**
* 修改用户
* @param user
* @return
*/
public int updateUser(User user) throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
int n = sqlSession.update("com.wxc.mapper.UserMapper.updateUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
return n;
}
/**
* 查询用户
* @return
*/
public User selectUser() throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
User user = sqlSession.selectOne("com.wxc.mapper.UserMapper.selectUser");
// 释放资源
sqlSession.close();
return user;
}
/**
* 查询用户 测试resultMap使用
* @return
*/
public List selectUser_() throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
List user = sqlSession.selectList("com.wxc.mapper.UserMapper.selectUser_");
// 释放资源
sqlSession.close();
return user;
}
}
4.3 在com.wxc.mapper包中创建相应sql操作
创建UserMapper.java
package com.wxc.mapper;
import com.wxc.vo.User;
import com.wxc.vo.User_;
import java.util.List;
/**
* Description: mapper接口,相当 于dao接口,用户管理
*/
public interface UserMapper {
//插入用户
public int insertUser(User user);
//删除用户
public int deleteUser(int id);
//查询用户
public User selecttUser();
//修改用户
public int updateUser(User user);
}
创建UserMapper.xml
insert into user(id, name) values(#{id}, #{name})
delete from user where id=#{id}
update user set name=#{name} where id=#{id}
com.wxc.controller中创建TestMybatisController.java用于测试访问
package com.wxc.controller;
import com.wxc.service.TestMybatisService;
import com.wxc.vo.MsgVo;
import com.wxc.vo.User;
import com.wxc.vo.User_;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.List;
/**
* 测试mybatis的基本使用
*/
@Controller
@RequestMapping(value = "/testMybatisController")
public class TestMybatisController {
@Autowired
private TestMybatisService testMybatisService;
/**
* 新增用户
* @return
*/
@RequestMapping(value = "/insertUser")
@ResponseBody
public MsgVo insertUser(User user) throws IOException {
System.out.println(user.toString());
int n = testMybatisService.insertUser(user);
MsgVo vo = new MsgVo(n+"", "成功");
return vo;
}
/**
* 删除用户
* @return
*/
@RequestMapping(value = "/deleteUser")
@ResponseBody
public MsgVo deleteUser(int id) throws IOException {
System.out.println(id+"");
int n = testMybatisService.deleteUser(id);
MsgVo vo = new MsgVo(n+"", "成功");
return vo;
}
/**
* 修改用户
* @return
*/
@RequestMapping(value = "/updateUser")
@ResponseBody
public MsgVo updateUser(User user) throws IOException {
int n = testMybatisService.updateUser(user);
MsgVo vo = new MsgVo(n+"", "成功");
return vo;
}
/**
* 查询用户
* @return
*/
@RequestMapping(value = "/selectUser")
@ResponseBody
public User selectUser() throws IOException {
User user = testMybatisService.selectUser();
return user;
}
4.4 运行项目后访问结果如下:
调用新增用户接口
5. 输入与输出映射
5.1 输入与输出介绍
(1)resultType:使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
(2)resultMap:如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系
5.2 resultMap代码演示
com.wxc.vo中新建实体类User_.java
package com.wxc.vo;
public class User_ {
private int id_;
private String name_;
private String sex_;
public User_(int id_, String name_, String sex_) {
this.id_ = id_;
this.name_ = name_;
this.sex_ = sex_;
}
public User_() {
}
public void setId_(int id_) {
this.id_ = id_;
}
public void setName_(String name_) {
this.name_ = name_;
}
public void setSex_(String sex_) {
this.sex_ = sex_;
}
public int getId_() {
return id_;
}
public String getName_() {
return name_;
}
public String getSex_() {
return sex_;
}
}
com.wxc.mapper的UserMapper.java中新增以下方法
//查询用户
public List selecttUser_();
com.wxc.mapper的UserMapper.xml中新增以下代码
com.wxc.service的TestMybatisService.java添加以下方法:
/**
* 查询用户 测试resultMap使用
* @return
*/
public List selectUser_() throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
List user = sqlSession.selectList("com.wxc.mapper.UserMapper.selectUser_");
// 释放资源
sqlSession.close();
return user;
}
com.wxc.controller的TestMybatisController.java添加以下方法
/**
* 查询用户 测试resultMap使用
* @return
*/
@RequestMapping(value = "/selectUser_")
@ResponseBody
public List selectUser_() throws IOException {
List user_ = testMybatisService.selectUser_();
return user_;
}
运行项目后访问情况如下:
6. 动态sql实现
6.1 什么是动态sql
mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
6.2 动态sql实现方式
(1)if-else
(2)sql片段
(3)foreach
6.3 代码演示(包含if-else、sql片段、foreach)
com.wxc.vo中新建实体类User2.java
package com.wxc.vo;
import java.util.List;
public class User2 extends User {
private List ids;
public User2(List ids) {
this.ids = ids;
}
public User2(int id, String name, String sex, List ids) {
super(id, name, sex);
this.ids = ids;
}
public User2()
{
}
public List getIds() {
return ids;
}
public void setIds(List ids) {
this.ids = ids;
}
@Override
public String toString() {
return "User2{" +
"ids=" + ids +
'}';
}
}
com.wxc.mapper包下新建SeniorUserMapper.java
package com.wxc.mapper;
import com.wxc.vo.User;
import com.wxc.vo.User2;
import java.util.List;
/**
* 测试高级的
*/
public interface SeniorUserMapper {
//查询用户
public List selectUser(User user);
//修改用户
public int updateUser(User2 user2);
}
com.wxc.mapper包下新建SeniorUserMapper.xml
sex = #{sex}
update user set name=#{name} where
id = #{id}
com.wxc.service包下新建TestSeniorMybatisService.java
package com.wxc.service;
import com.wxc.vo.User;
import com.wxc.vo.User2;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* 测试mybatis高级使用
*/
@Service(value = "/testSeniorMybatisService")
public class TestSeniorMybatisService {
// 需要向dao实现类中注入SqlSessionFactory
// 这里通过构造方法注入
private SqlSessionFactory sqlSessionFactory;
//初始化SqlSessionFactory
private void initSqlSessionFactory() throws IOException {
// mybatis配置文件
String resource = "spring/applicationContext-dao.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
/**
* 查询用户
* @return
*/
public List selectUser(User user) throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println("sex的值为:"+user);
//执行插入操作
List user2 = sqlSession.selectList("com.wxc.mapper.SeniorUserMapper.selectUser", user);
// 释放资源
sqlSession.close();
return user2;
}
/**
* 批量修改用户
* @return
*/
public int updateUser(User2 user) throws IOException {
initSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println("sex的值为:"+user);
//执行插入操作
int n = sqlSession.update("com.wxc.mapper.SeniorUserMapper.updateUser", user);
// 释放资源
sqlSession.close();
return n;
}
}
com.wxc.controller包下新建TestSeniorMybatisController.java
package com.wxc.controller;
import com.wxc.service.TestSeniorMybatisService;
import com.wxc.vo.User;
import com.wxc.vo.User2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.List;
/**
* 测试mybatis高级使用
*/
@Controller
@RequestMapping(value = "/testSeniorMybatisController")
public class TestSeniorMybatisController {
@Autowired
private TestSeniorMybatisService testSeniorMybatisService;
/**
* 查询用户
* @return
*/
@RequestMapping(value = "/selectUser")
@ResponseBody
public String selectUser(User user) throws IOException {
List user2 = testSeniorMybatisService.selectUser(user);
return user2.toString();
}
@RequestMapping(value = "/updateUser")
@ResponseBody
public String updateUser(User2 user2) throws IOException {
int n = testSeniorMybatisService.updateUser(user2);
return n+"";
}
}
7. 查询缓存
7.1 什么是查询缓存
mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供一级缓存,和二级缓存。
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
为什么要用缓存?
如果缓存中有数据就不用从数据库中获取,大大提高系统性能。
7.2 一级缓存
一级缓存工作原理
第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。
得到用户信息,将用户信息存储到一级缓存中。
如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
7.3 二级缓存
二级缓存工作原理
首先开启mybatis的二级缓存。
sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。
如果SqlSession3去执行相同 mapper下sql,执行commit提交,清空该 mapper下的二级缓存区域的数据。
sqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。
二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域。
UserMapper有一个二级缓存区域(按namespace分) ,其它mapper也有自己的二级缓存区域(按namespace分)。
每一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同 的二级缓存区域中。
7.4 开启二级缓存
mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存。
在核心配置文件SqlMapConfig.xml中加入
8. mybatis与hibernate区别
hibernate
hibernate是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。
对sql语句进行优化、修改比较困难的。
应用场景:
适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。
mybatis
mybatis专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
应用场景:
适用与需求变化较多的项目,比如:互联网项目。
企业进行技术选型,以低成本 高回报作为技术选型的原则,根据项目组的技术力量进行选择。
三、项目源码下载
链接:https://pan.baidu.com/s/1LIHtfQQ_i3MSviNGa-mcDg
提取码:qmja
四、参考文章
http://yun.itheima.com/course/289.html