Mybatis简介
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
Mybatis是面向sql的持久层框架,封装了jdbc访问数据库的过程,开发过程,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多
Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要经验和能力都很强才行。
sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。
JDBC存在问题
频繁创建和打开、关闭数据库连接,太消耗资源
Sql语句存在硬编码,不利于维护
Sql参数设置硬编码,不利于维护
结果集获取与遍历复杂,存在硬编码,不利于维护,期望能够查询后返回一个java对象
初始案例
创建数据库
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `orders`
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '下单用户id',
`number` varchar(32) NOT NULL COMMENT '订单号',
`createtime` datetime NOT NULL COMMENT '创建订单时间',
`note` varchar(100) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `FK_orders_1` (`user_id`),
CONSTRAINT `FK_order_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `order` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
INSERT INTO `order` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
INSERT INTO `order` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('26', '王五', null, null, null);
导入依赖jar包
创建 pojo对象
配置SqlMapConfig.xml
配置log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
配置sql查询的映射文件user.xml
编写测试代码
import cn.zjut.mybatis.pojo.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.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class MybatisTest {
@Test
public void testGetUserById() throws IOException {
//创建核心配置文件输入流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流创建 SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行查询 参数一:sql id 参数二:入参
User user = sqlSession.selectOne("user.getUserById",1);
System.out.println(user);
//释放资源
sqlSession.close();
}
}
抽取SqlSessionFactory工具类
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtil {
private static SqlSessionFactory sqlSessionFactory;
/**
* 静态代码块
*/
static{
try {
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取关联核心配置文件的输入流
InputStream inputStream;
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过核心配置文件输入流创建SqlSessionFactory对象
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取SqlSessionFactory对象
* @return SqlSessionFactory
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
模糊查询
sql配置
测试代码
@Test
public void testGetUserByUserName(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//List list = sqlSession.selectList("user.getUserByUserName", "%张%");
List list = sqlSession.selectList("user.getUserByUserName", "张");
for (User user : list) {
System.out.println(user);
}
}
增添 一条记录
sql配置
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`)
VALUES
(#{username},
#{birthday},
#{sex},
#{address})
测试代码
@Test
public void testInsertUser(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsername("张无名");
user.setSex("1");
user.setAddress("杭州西湖");
user.setBirthday(new Date());
sqlSession.insert("user.insertUser", user);
//提交事务
sqlSession.commit();
sqlSession.close();
}
插入数据设置主键返回
方式一sql配置
SELECT LAST_INSERT_ID()
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`)
VALUES
(#{username},
#{birthday},
#{sex},
#{address})
方式二sql配置
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`)
VALUES
(#{username},
#{birthday},
#{sex},
#{address})
返回UUID
给用户表添加uuid2列,对应pojo添加uuid2字段
sql配置
SELECT UUID()
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`,
`uuid2`)
VALUES
(#{username},
#{birthday},
#{sex},
#{address},
#{uuid2})
修改数据
sql配置
UPDATE
`user`
SET
username = #{username}
WHERE `id` = #{id}
测试代码
@Test
public void testUpdateUser(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(30);
user.setUsername("张角");
sqlSession.update("user.updateUser", user);
sqlSession.commit();
sqlSession.close();
}
删除数据
sql配置
DELETE
FROM `user`
WHERE `id` = #{id}
测试代码
@Test
public void testDeleteUser(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("user.deleteUser",30);
sqlSession.commit();
sqlSession.close();
}
Mybatis架构图
Mybatis Dao开发方式
传统Dao开发方式
创建UserDao接口
import cn.zjut.mybatis.pojo.User;
import java.util.List;
public interface UserDao {
User getUserById(Integer id);
List getUserByUserName(String userName);
void insertUser(User user);
}
创建UserDaoImpl接口实现类
import cn.zjut.mybatis.dao.UserDao;
import cn.zjut.mybatis.pojo.User;
import cn.zjut.mybatis.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class UserDaoImpl implements UserDao {
@Override
public User getUserById(Integer id) {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("user.getUserById", id);
sqlSession.close();
return user;
}
@Override
public List getUserByUserName(String userName) {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("user.getUserByUserName", userName);
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("user.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
创建UserDaoTest测试类
import cn.zjut.mybatis.dao.UserDao;
import cn.zjut.mybatis.dao.impl.UserDaoImpl;
import cn.zjut.mybatis.pojo.User;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserDaoTest {
@Test
public void testGetUserById() {
UserDao userDao = new UserDaoImpl();
User user = userDao.getUserById(28);
System.out.println(user);
}
@Test
public void testGetUserByUserName() {
UserDao userDao = new UserDaoImpl();
List list = userDao.getUserByUserName("张");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testInsertUser() {
UserDao userDao = new UserDaoImpl();
User user = new User();
user.setUsername("张飞6");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("杭州滨江");
userDao.insertUser(user);
}
}
接口动态代理方式开发Dao
创建映射文件UserMapper.xml
INSERT INTO `user`
(`username`,
`birthday`,
`sex`,
`address`)
VALUES
(#{username},
#{birthday},
#{sex},
#{address})
在核心配置文件中加载映射文件
按照动态代理开发规则创建UserMapper接口
import cn.zjut.mybatis.pojo.User;
import java.util.List;
public interface UserMapper {
User getUserById(Integer id);
List getUserByUserName(String userName);
void insertUser(User user);
}
创建UserMapperTest测试类
import cn.zjut.mybatis.mapper.UserMapper;
import cn.zjut.mybatis.pojo.User;
import cn.zjut.mybatis.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class UserMapperTest {
@Test
public void testGetUserById() {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口代理实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(28);
System.out.println(user);
sqlSession.close();
}
@Test
public void testGetUserByUserName() {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口代理实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List list = userMapper.getUserByUserName("张");
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testInsertUser() {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口代理实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("赵子龙");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("杭州富阳");
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
}
SqlMapConf.xml配置
配置内容顺序如下
properties
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234
typeAliases
Mybatis支持的别名
别名 映射类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map
mappers