Java学习日记13:MyBatis

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的最基本用法就算是了解了。
想要用的好还是要多多练习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值