Java学习日记13:MyBatis

来源:互联网 发布:网络装修平台有哪些 编辑:程序博客网 时间:2024/05/20 11:21

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字段,是varcharpublic 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.Driverurl=jdbc:mysql://localhost:3306/mybatisusername=rootpassword=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
原创粉丝点击