版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50640383
1. 什么是MyBatis?
MyBatis 的前身是
iBATIS ,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。。MyBatis 3 是 iBATIS 的全新设计,支持
注解和Mapper。
MyBatis 是一个简化和实现了
Java数据持久化层(persistence layer)的
开源框架。
MyBatis 是支持
普通 SQL查询,
存储过程和
高级映射的优秀
持久层框架。MyBatis 消除了几乎所有的
JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的
XML或注解 用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis 流行的主要原因在于它的简单性和易使用性。在 Java应用程序中,数据持久化层涉及到的工作有:将从数
据库查询到的数据生成所需要的 Java对象;将 Java对象中的数据通过 SQL 持久化到数据库中。
MyBatis 通过抽象底层的 JDBC 代码,自动化 SQL 结果集产生 Java 对象、Java 对象的数据持久化数据库中的过程
使得对 SQL 的使用变得容易。
2. 为什么选择MyBatis?
当前有很多基于Java的持久化框架,而 MyBatis 流行起来有以下几个原因:
- 消除大量的 JDBC 冗余代码
- 很低的学习成本,容易上手
- 能很好地与传统数据库协同工作
- 支持普通SQL 语句查询
- 对Spring 和 Guice 框架的集成提供支持
- 提供了与第三方缓存类库的集成支持
- 有更好的性能
2.1 消除大量的 JDBC 冗余代码
Java通过JDBC API来操作关系型数据库,但是JDBC是一个非常底层的API,我们需要书写大量的代码来完成对数据库的操作。
下面我们使用JDBC API来操作数据库,对表Student实现简单的select和insert操作。
Studnet表:
/*
Navicat MySQL Data Transfer
Source Server : MySQL
Source Server Version : 50624
Source Host : localhost:3306
Source Database : test
Target Server Type : MYSQL
Target Server Version : 50624
File Encoding : 65001
Date: 2016-02-06 11:22:28
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`ID` int(11) NOT NULL,
`name` varchar(20) NOT NULL,
`age` int(11) DEFAULT NULL,
`school` varchar(20) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', 'yoona', '24', '西安电子科技大学');
对应的Studnet JavaBean定义如下:
package com.sjf.bean;
/**
* 学生实体类
* @author sjf0115
*
*/
public class Student {
private int ID;
private String name;
private int age;
private String school;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString() {
return "name:" + name + " age:" + age + " school:" + school;
}
}
下面StudnetService实现了对Student表的Select和Insert操作:
package com.sjf.service;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.sjf.bean.Student;
/**
* 学生服务类
* @author sjf0115
*
*/
public class StudnetService {
/**
* 根据ID获取学生信息
* @param ID
* @return
*/
public Student getStudentByID(int ID){
Student stu = null;
Connection conn = null;
try {
// 获取数据库连接
conn = getDataBaseConnection();
String sql = "select * from Student where ID = ?";
// 创建PreparedStatement
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// 设置参数
preparedStatement.setInt(1, ID);
// 返回结果集
ResultSet rs = preparedStatement.executeQuery();
// 从数据库中取出数据生成Java对象
if(rs.next()){
stu = new Student();
stu.setID(ID);
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
stu.setSchool(rs.getString("school"));
}//if
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
finally {
if(conn != null){
try {
conn.close();
} catch (SQLException e) {}
}//if
}
return stu;
}
/**
* 创建一个学生实体
* @param student
*/
public void CreateStudent(Student student){
Connection conn = null;
try {
// 获取数据库连接
conn = getDataBaseConnection();
String sql = "insert into Student (ID,name,age,school) values(?,?,?,?)";
// 创建PreparedStatement
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// 设置参数
preparedStatement.setInt(1, student.getID());
preparedStatement.setString(2, student.getName());
preparedStatement.setInt(3, student.getAge());
preparedStatement.setString(4, student.getSchool());
// 执行
preparedStatement.executeUpdate();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
finally {
if(conn != null){
try {
conn.close();
} catch (SQLException e) {}
}//if
}
}
/**
* 获取数据库连接
* @return 数据库连接
* @throws ClassNotFoundException
* @throws SQLException
*/
protected Connection getDataBaseConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
return conn;
}
}
测试代码:
package com.sjf.test;
import com.sjf.bean.Student;
import com.sjf.service.StudnetService;
public class Test {
public static void main(String[] args){
StudnetService studnetService = new StudnetService();
Student student = new Student();
student.setID(3);
student.setName("sunny");
student.setAge(20);
student.setSchool("xidian");
studnetService.CreateStudent(student);
student = studnetService.getStudentByID(3);
System.out.println(student.toString());
}
}
运行结果:
name:sunny age:20 school:xidian
StudentService中每个方法中都有大量的重复代码:创建一个连接,创建一个statement对象,设置输入参数,关闭资源。
MyBatis抽象了上述这些相同的任务,如准备需要被执行的SQL statement对象并且将java对象作为输入数据传递给statement对象的任务,进而开发人员可以专注于真正重要的方面。另外,MyBatis自动化了将输入的Java对象中的属性设置成查询参数,从SQL结果集上生成Java对象这两个过程。下一节我们通过MyBatis来实现上述过程,可以看出有什么区别。
2.2 良好的性能
MyBatis 支持数据库连接池,消除了为每一个请求创建一个数据库连接的开销。
MyBatis 提供了内建的缓存机制,在 SqlSession 级别提供了对 SQL 查询结果的缓存。即:如果你调用了相同的
select查询,MyBatis 会将放在缓存的结果返回,而不会去再查询数据库。
MyBatis 框架并没有大量地使用代理机制 ,因此对于其他的过度地使用代理的ORM 框架而言,MyBatis 可以获得更
好的性能。
2.3 支持SQL
成熟的ORM框架(如Hibernate)鼓励使用实体对象(Entity Objects)以及在底层自动产生SQL语句。但是这种SQL生成策略,使我们不能够充分利用数据库的一些特有特性。Hibernate允许执行本地SQL,但是这样会打破持久层和数据独立的原则。
MyBatis框架
接受SQL语句,而不是将其对开发人员隐藏起来。由于MyBatis不会产生任何的SQL语句,所以开发人员需要做好这方面的准备。这样我们既可以充分
利用数据库特有的特性并且可以
自定义SQL查询语句。同时MyBatis对
存储过程提供了支持。
2.4 很好的与传统数据库协同工作
有时我们可能需要用不正规形式与传统数据库协同工作,使用成熟的 ORM 框架 (如 Hibernate )有可能、但是很难跟
传统数据库很好地协同工作,因为他们尝试将 Java对象静态地映射到数据库的表上 。
而 MyBatis 是将查询的结果与 Java 对象映射起来,这使得 MyBatis 可以很好地与传统数据库协同工作。你可以根
据面相对象的模型创建 Java 域对象,执行传统数据库的查询,然后将结果映射到对应的 Java对象上。
参考:《Java Persistence with MyBatis 3》
下载:
点击打开链接