MyBatis
百度上是这么解释的:
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类—-Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
MyBatis 通过抽像底层的 JDBC 代码,自动化 SQL 结果集产生 Java 对象,Java 对象的数据持久化数据库中的过程,使得对 SQL 的使用变量容易
MyBatis 和 Hibernate 的区别:
- MyBatis 是一个半自动化的 ORM 框架,需要手工匹配提供 POJO、SQL 和映射关系
- Hibernate 是一个全自动化的 ORM 框架,深层次封装,全表映射、对多表关联和复杂SQL 查询支持较差,性能相对较差
为什么选择 MyBatis
- 它消除了大量的 JDBC 冗余代码
- 它有低的学习曲线
- 它能很好地与传统数据库协同工作
- 它可以接受 SQL 语句
- 它性能更好
- 容易与第三方框架集成
一个简单的MyBatis程序:
构建数据库
先构建好一个数据库:mybatis
构建一个学生的表:student
(我用的是 Navicat构建的)
表的内容是id,name,age,email,sex,phonenumber。
导入jar包
mybatis-3.x.x.jar
slf4j-api-1.7.5.jar
slf-log4j12-1.7.5.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.22.jar
新建Student类
package com.pojo;
import org.apache.ibatis.type.Alias;
public class Student
{
private long id;
private String name;
private int age;
private String email;
private String sex;
private PhoneNumber phone;
public long getId() {
return id;
}
public void setId(long id) {
this.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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public PhoneNumber getPhone() {
return phone;
}
public void setPhone(PhoneNumber phone) {
this.phone = phone;
}
}
新建PhoneNumber类
package com.pojo;
//要先在数据库中增加phonenumber字段,是varchar
public class PhoneNumber {//一个电话号码有三段86-29-97669559
private String countryCode;
private String stateCode;
private String number;
public PhoneNumber(){}//空的构造方法
public PhoneNumber(String countryCode,String stateCode,String number)//带三个参数的构造方法,号码的三段
{
this.countryCode=countryCode;
this.stateCode=stateCode;
this.number=number;
}
//86-29-97669559
public PhoneNumber(String number)//只带一个参数的构造方法
{
if(null!=number&&number.matches("\\d+[-]\\d+[-]\\d+"))//正则表达式匹配对应的字符串
{
String []all=number.split("-");//split()方法,根据"-"这个符号拆分字符串,分别存到all[]这个数组中
this.countryCode=all[0];
this.stateCode=all[1];
this.number=all[2];
}
}
@Override
public String toString() //重写toString方法。
{
return this.countryCode+"-"+this.stateCode+"-"+this.number;//例如:86-29-97669559
}
//下面是getter和setter方法。。。
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
新建 StudentMapper接口
package com.mapper;
import com.pojo.Student;
public interface StudentMapper {
public void addStudent(Student stu);
public Student getStudentById(int id);
}
新建 StudentMapper接口的实现(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.mapper.StudentMapper">
<!-- 这里代表这个xml是用来实现StudentMapper类 -->
<select id="getStudentById" resultType="Stu" parameterType="int">
select * from student where id = #{id}
</select>
<!-- 下面加了phone这个字段 -->
<!-- 这里,phone 参数需要传递给#{phone};而 phone 对象是 PhoneNumber 类型。然而,
MyBatis 并不知道该怎样来处理这个类型的对象。
为了让 MyBatis 明白怎样处理这个自定义的 Java 对象类型,如 PhoneNumber,我们可以
创建一个自定义的类型处理器,如下所示:
1. MyBatis 提供了抽象类 BaseTypeHandler<T> ,我们可以继承此类创建自定义类型处理
器。 -->
<insert id="addStudent" parameterType="Stu">
insert into student(name,age,sex,email,phone)
values(#{name},#{age},#{sex},#{email},#{phone,typeHandler=com.type.PhoneTypeHandler})
</insert>
</mapper>
新建 mybatis 配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 这个是Mybatis的配置xml,这是第一步(前提是表要建好,导入好jar包) -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 这里的dtd如果没有提示的话选Window的Preference中,然后在搜索中输入xml
然后选择Catalog,将mybaties压缩包中的org/apache/ibatis/builder/xml/mybatis-3-config.dtd把这个文件拷贝出来,把路径复制到Preference中,
然后PUBLIC ID就是上面的PUBLIC后面的一串 -->
<configuration>
<properties resource="jdbc.properties">
<!-- 这个xml链接到jdbc.properties这个配置文件,是为了给下面的${driver},${url}之类的东西提供值 -->
<property name="password" value="root"/>
<!-- 如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:
·在 properties 元素体内指定的属性首先被读取。
·然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性
指定的路径读取属性文件,并覆盖已读取的同名属性。
·最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,
最低优先级的是 properties 属性中指定的属性。-->
</properties>
<!--typeAliases 因为我遇到的类的全限定名过长,所以我们希望用一个简短的名称去指代它,这个名称
可以 MyBatis 上下文中使用,
·别名在 MyBatis 里分为系统定义别名和自定义别名两类,
·别名不分大小写
·一个 typeAliases 的实例是在解析配置文件时生成的,然后长期保存在 Configuration 对
象中,当我们使用它时,再把它拿出来,没有必要再次实例化
就是用一个简短的名字代替类名 -->
<typeAliases>
<typeAlias type="com.pojo.Student" alias="Stu"/>
<package name="com.pojo"/>
</typeAliases>
<!-- 一旦我们实现了自定义的类型处理器,我们需要在 mybatis-config.xml 中注册它:
注册 PhoneTypeHandler 后, MyBatis 就能够将 Phone 类型的对象值存储到 VARCHAR 类型
的列上。-->
<typeHandlers>
<typeHandler handler="com.type.PhoneTypeHandler"/>
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
username=root
password=mysql
创建PhoneTypeHandler类
package com.type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.pojo.PhoneNumber;
public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> {
//sql-->java将SQL的数据类型转化为Java的 根据列名
@Override
public PhoneNumber getNullableResult(ResultSet rs, String col) throws SQLException {
// TODO Auto-generated method stub
return new PhoneNumber(rs.getString(col));
}
//sql-->java将SQL的数据类型转化为Java的 根据指数
@Override
public PhoneNumber getNullableResult(ResultSet rs, int index) throws SQLException {
// TODO Auto-generated method stub
return new PhoneNumber(rs.getString(index));
}
//存到内存中
@Override
public PhoneNumber getNullableResult(CallableStatement arg0, int arg1) throws SQLException {
// TODO Auto-generated method stub
return null;
}
//java-->sql 将Java数据转化为SQL数据
@Override
public void setNonNullParameter(PreparedStatement ps, int index, PhoneNumber param, JdbcType jdbctype)
throws SQLException {
ps.setString(index, param.toString());
}
}
最后写测试类:
package com.main;
import java.io.InputStream;
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 com.mapper.StudentMapper;
import com.pojo.PhoneNumber;
import com.pojo.Student;
public class Main {
public static void main(String[] args)throws Exception
{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
/*Student stu=new Student();
stu.setAge(22);
stu.setEmail("ttt@qq.com");
stu.setName("xiaoming");
stu.setSex("F");
stu.setPhone(new PhoneNumber("86","29","81127002"));
//得到一个StudentMapper接口的实例
StudentMapper sm=session.getMapper(StudentMapper.class);
sm.addStudent(stu);*/
//得到一个StudentMapper接口的实例
StudentMapper sm=session.getMapper(StudentMapper.class);
Student stu=sm.getStudentById(4);
System.out.println(stu.getId()+"\t"+stu.getName()+"\t"+stu.getPhone());
session.commit();
System.out.println("OK...");
}catch(Exception e)
{
session.rollback();
}
finally {
session.close();
}
}
}
当完成上面的程序以后。MyBatis的最基本用法就算是了解了。
想要用的好还是要多多练习。