Mybatis初探

最近在学习Mybatis的使用,在此把自己的学习笔记记录下来。
   Mybatis版本:mybatis-3.2.3
   数据库: mysql 5.1
   环境: eclipse4.2
   需要了解的知识:能熟练使用SQL(结构化查询)语言,与 Hibernate, Toplink 等持久化框架不同,ibatis 是一个 “半自动化”的 ORM 实现。ibatis 没有对数据库结构提供了较为完整的封装,而是提供了一个从 POJO 到数据库表的全套映射机制。这使得在开发 ibatis 的时候,需要手动的编写 sql 来提过数据库与类对象之间的映射,这在给开发提供了很大的灵活性的同时,大大增加了开发的工作量。因为更接近底层,所以它更快。
   需要用到的jar包:

141515886.png

   接下来做个小例子吧(建议你先了解一下mybatis的基本配置信息,推荐个http://mybatis.github.io/mybatis-3/zh/index.html):
 (1) 首先,创建两个对象Person和Address,一个Person只能有一个Address,而一个Address可以拥有多个Person对象。也就是Address (1)――>(n)Person(一对多关系)
Person对象的代码如下:

public class Person {
    private Integer id;//用户id
    private String name;//用户名称
    private Address address;//一个Person只能有一个Address
    public Person() {
        super();
    }
//构造方法,便于测试
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}

Address对象:

import java.util.List;
public class Address {
    private Integer id;//住址的id
    private String address;//住址描述
    private List<Person> persons;//一个住址可以有多个Person的关系体现
    public Address(){}
    public Address(String add , List<Person> p){
        this.address = add;
        this.persons = p;
    }
        public Address(String add){
        this.address = add;
    }
        public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public List<Person> getPersons() {
        return persons;
    }
    public void setPersons(List<Person> persons) {
        this.persons = persons;
    }
}

(2)*然后非常重要的一步是在数据库中建表,你的表得手动建立,不能像Hibernate那样可以自动生成。所以你得要弄清表关系以及表结构。
  Person与Address的关系为一对多,所以可以由Person表通过引入外键:Address的id来体现他们之间的关系。所以,Person和Address对应的建表SQL语句如下:

CREATE TABLE test.`address` (                          
           `address_id` int(10) NOT NULL auto_increment,   
           `address` varchar(20) NOT NULL unique,
           PRIMARY KEY  (`address_id`)                     
         ) ENGINE=InnoDB DEFAULT CHARSET=gbk ;              
CREATE TABLE test.`person` (                               
          `person_id` int(10) NOT NULL auto_increment,        
          `person_name` varchar(20) NOT NULL unique,
      `address_id` int(10),
          PRIMARY KEY  (`person_id`)                          
        ) ENGINE=InnoDB DEFAULT CHARSET=gbk  ;
  alter table test.`person` add foreign key (address_id) references test.`address`(address_id);

(3)编写jdbc.properties配置文件,配置数据库连接所需要的元素,采用这种方式可以使你切换数据库或修改数据库连接选项的时候更加方便。
jdbc.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver
 jdbc.url=jdbc:mysql://127.0.0.1:3306/test
 jdbc.username=root
 jdbc.password=521521

(4)配置mybatis.xml文件
mybatis.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部的配置文件 -->
    <properties resource="jdbc.properties"/>
    <settings>
        <!-- 对在此配置文件下的所有cache 进行全 局性开/关设置。 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 全局性设置懒加载。如果设为‘关’, 则所有相关联的都会被初始化加载。 -->
        <setting name="lazyLoadingEnabled" value="true" />
        <!-- 当设置为‘开’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 -->
        <setting name="aggressiveLazyLoading" value="true" />
        <!-- 允许和不允许单条语句返回多个数据集(取决于驱动需求) -->
        <setting name="multipleResultSetsEnabled" value="true" />
        <!-- 使用列标签代替列名称。不用的驱动器有不同的作法。 -->
        <setting name="useColumnLabel" value="true" />
        <!-- 允许JDBC生成主键。需要驱动器支持.如果设为了true,这个设置将强制使用被生成的主键, 有一些驱动器不兼容不过仍然可以执行。 -->
        <setting name="useGeneratedKeys" value="false" />
        <!-- 指定MyBatis是否并且如何来自动映射数据表字段与对象的属性。PARTIAL将只自动映射简单的,NONE没有嵌套的结果。 FULL将自动映射所有复杂的结果。 -->
        <setting name="autoMappingBehavior" value="PARTIAL" />
        <!-- 配置和设定执行器,SIMPLE执行器执行其它语句。REUSE执行器可能重复使用preparedstatements语句,BATCH执行器可以重复执行语句和批量更新。 -->
        <setting name="defaultExecutorType" value="SIMPLE" />
        <!-- 设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时. 正整数 -->
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
    <!-- 类型别名,可以让你在配置时省去累赘的包名而直接使用别名 -->
    <typeAliases>
        <typeAlias type="com.mybatis.domain.Person" alias="Person"/>
        <typeAlias type="com.mybatis.domain.Address" alias="Address"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
        <!-- 配置事物管理器的类型 -->
            <transactionManager type="JDBC"/>
        <!--  配置数据源 -->
            <dataSource type="POOLED">
                 <!-- 此处便是引用jdbc.properties中的配置信息 -->
                <property name="driver" value="${jdbc.driverClassName}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
<!-- 引入实体的映射文件 -->
    <mappers>
        <mapper resource="com/mybatis/domain/AddressMapper.xml"/>
        <mapper resource="com/mybatis/domain/PersonMapper.xml"/>
    </mappers>
</configuration>

(5)那么接下来是最重要的实体的映射文件的配置。获取你可以参考以下内容帮你更快的了解各项配置的详细信息:
http://www.ibm.com/developerworks/cn/opensource/os-cn-ibatis/
AddressMapper.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.mybatis.domain.AddressMapper">
    <!-- mybatis最强大的元素,是时候让你们见识一下了 -->
    <!-- 注意type="Address" 本来它应该是这样: type="com.mybatis.domain.Address"
    但是由于你在mybatis.xml文件中给它起了个绰号,所以用起来也更亲切更方便 -->
    <resultMap type="Address" id="AddressMapper" >
    <!-- 映射实体中的id属性 ,当然,在创建表的时候我们设置了让其自动增长  -->
        <id property="id" column="address_id"/>
        <result property="address" column="address" />
        <!-- 映射实体类中的集合属性,ofType="Person"表示集合中元素的类型  -->
        <collection property="persons" ofType="Person">
            <id property="id" column="person_id" />
            <result property="name" column="person_name" />
            <!-- 映射复合类型的属性请用association,绝对童叟无欺 -->
            <association property="address" column="address_id"
                resultMap="AddressMapper" />
        </collection>
    </resultMap>
    <!-- 插入语句,原汁原味的SQL语句,但注意#{xxx}中xxx必须是parameterType="Address"里Address中的属性,否则报错。 -->
    <!-- id="xxx"是给你的语句起个响亮的名字,让别人很容易的找到你并区别你和其他人  -->
    <insert id="addAddress" parameterType="Address">
        insert into
        address(address) values(#{address})
    </insert>
    <!-- 特别注意,select语句是有返回值的,返回结果需要你来给他设置一个格式化工厂,生产出合格的符合需求的产品 -->
    <select id="getAddressById" parameterType="int" resultMap="AddressMapper">
        select * from address where address_id=#{id}
    </select>
</mapper>

PersonMapper.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.mybatis.domain.PersonMapper">
    <resultMap type="Person" id="PersonMapper">
        <id property="id" column="person_id" />
        <result property="name" column="person_name" />
        <association property="address" column="address_id"
            javaType="Address" resultMap="com.mybatis.domain.AddressMapper.AddressMapper"/>
    </resultMap>
    <!-- 通过id查找用户信息,这是一个连表查询,传入的参数是:parameterType="integer" 类型,结果映射: PersonMapper-->
    <select id="getPersonById" parameterType="integer" resultMap="PersonMapper">
        select  
            p.person_id,
            p.person_name,
            p.address_id,
            a.address
        from  
            person p,address a
        where  
            p.address_id = a.address_id
        and   
            p.person_id=#{id}
    </select>
    <!-- 查询所有的用户信息 -->
    <select id="getAllPerson" resultMap="PersonMapper">
        select
            p.person_id,
            p.person_name,
            p.address_id,
            a.address
        from
            person p,address a
        where
            p.address_id = a.address_id
    </select>
    <!-- 插入记录 -->
    <insert id="addPerson" parameterType="Person">
        insert into person(person_name,address_id) values(#{name},#{address.id})
    </insert>
</mapper>

(6)剩下的就是测试了,测试代码如下:
先编写一个工具类,用于创建SqlSessionFactory(每 一 个 MyBatis 的 应 用 程 序 都 以 一 个 SqlSessionFactory 对 象 的 实 例 为 核 心 。):
MybatisSqlSessionFactoryUtil

package com.mybatis.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisSqlSessionFactoryUtil {
    public static SqlSessionFactory sqlSessionFactory;
    static {
        String resource  = "mybatis.xml";
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println(resource+" file read error!");
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }
    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

测试代码如下:

package com.mybatis.util;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.mybatis.domain.Address;
import com.mybatis.domain.Person;
import com.mybatis.domain.User;
public class PersonAddressTest {
    public static void main(String[] args) {
        //获得sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = MybatisSqlSessionFactoryUtil
                .getSqlSessionFactory();
        //开启sqlSession
        SqlSession session = sqlSessionFactory.openSession();
        //插入address记录
        for(int i=0;i<20;i++){
        Address a = new Address("甘井子区"+i+"号");
        session.insert("com.mybatis.domain.AddressMapper.addAddress",a);
    }
        //插入person记录
        for(int i = 0;i<10;i++){
        Address address = session.selectOne("com.mybatis.domain.AddressMapper.getAddressById", i);
        Person p = new Person();
        p.setName("user"+i);
        p.setAddress(address);
        session.insert("com.mybatis.domain.PersonMapper.addPerson", p);
    }
        //根据id获取记录
        Person p = session.selectOne("com.mybatis.domain.PersonMapper.getPersonById",10);
        Address add = p.getAddress();
        System.out.println("User "+p.getName()+"'s address is "+add.getAddress());
        //获取所有的记录
        List<Person> persons = new ArrayList<Person>();
        persons = session.selectList("com.mybatis.domain.PersonMapper.getAllPerson");
        for(int i = 0;i<persons.size();i++){
            Person p1 = persons.get(i);
            Address a1 = p1.getAddress();
            System.out.println(p1.getId()+"  |  "+p1.getName()+"  |  "+a1.getAddress()+"  |  "+a1.getId());
        }
        System.out.println("ok");
        //提交事物
        session.commit();
        //关闭session
        session.close();
    }
}

(7)结果:

141346957.png

数据库中:

141417515.png

141419183.png



本人系初学,如有什么错误及不当的地方,请各位大神批评指正,愿与君共勉!(当然你也可以喷我,那只是你不了解我而已,等你了解我了,你会忍不住打我的!)
声明:请随意转载,请不要注明出处!

你可能感兴趣的:(mybatis,实例,mapping,一对多关联映射)