MyBetis3.2框架技术

1.1    MyBatis介绍

MyBatis 世界上流行最广泛的基于SQ语句的ORM框架,由Clinton Begin 在2002 年创建,其后,捐献给了Apache基金会,成立了iBatis 项目。2010 年5 月,将代码库迁致Google Code,并更名为MyBatis.

1.2 与Hibernate比较

  1. 学习成本:MyBatis简单易学(特别是有SQL语法基础的人),较接近JDBC
  2. 程序灵活性:MyBatis直接使用SQL,灵活性高
  3.  程序执行效律:MyBatis效律高
  4. 可移植性:hibernate较好(与数据库关联在配置中完成,HQL语句与数据库无关)

1.3    适用场合

MyBatis是一个灵活的DAO层解决方案,满足较高的性能要求,可以在很多场合使用,但一般以下场合不建议使用:

  1. 需要支持多种数据库或数据库有移植要求
  2. 完全动态SQL,例如:字段都要动态生成

使用的不是关系数据库

1.4 开发步骤(推荐)

  1. 新建JAVA项目或WEB项目
  2. 部署jar包(包括数据库驱动包):使用MyBatis需要先下载jar包:下载地址http://code.google.com/p/mybatis
  3. 编写主配置文件
  4. 创建数据库及表
  5. 创建实体类及SQL映射文件
  6. 编写数据库接口及实现
  7. 编写测试类及测试

1.5 开发示例

1.5.1  新建项目

新建java项目或web 项目。

1.5.2 导入JAR包

导入mybatis和数据库驱动包、日志包(配置日志配置文件)。

1.5.3  创建myBatis-config.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>
<!--可以设置多个运行环境,满足不同需要,例如 开发、测试、生产环境上有不同一配置 -->
    <environments default="development">
        <environment id="development">
<!--事务管理类型主要有jdbc和managed,前者依赖于数据源获得的连接,后者依赖于容器 -->
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <!-- 如果数据库设置为UTF-8,则URL参数连接需要添加?useUnicode=true&amp;characterEncoding=UTF-8,如下 -->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8" />
                <property name="username" value="***" />
                <property name="password" value="***" />
            </dataSource>
        </environment>
    </environments>
</configuration>

1.5.4  创建数据库及表

drop database if exists mybatis;
create database mybatis CHARACTER SET UTF8;
use mybatis;

create table dept(
    dept_id int primary key auto_increment,
    dept_name varchar(50),
    dept_address varchar(50)
);


insert into dept(dept_name,dept_address) values('研发部一部','广州');
insert into dept(dept_name,dept_address) values('研发部二部','广州');
insert into dept(dept_name,dept_address) values('研发部三部','深圳');
select * from dept;

1.5.5  创建实体类:Dept.java

public class Dept implements Serializable {
    private Integer deptId; //部门编号
    private String deptName;//部门名称
    private String deptAddress;//部门地址
    public Integer getDeptId() {
        return deptId;
    }
    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public String getDeptAddress() {
        return deptAddress;
    }
    public void setDeptAddress(String deptAddress) {
        this.deptAddress = deptAddress;
    }
    @Override
    public String toString() {
        return "Dept [deptId=" + deptId + ", deptName=" + deptName
                + ", deptAddress=" + deptAddress + "]";
    }    
}

1.5.6  创建SQL映射文件及修改主配置文件

SQL映射文件:DeptMapper.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="cn.it.entity.DeptMapper">
    <!--  一般在查询时使用-->
    <resultMap type="cn.it.entity.Dept" id="deptResultMap">
        <id property="deptId" column="dept_id"/>
        <result property="deptName" column="dept_name"/>
        <result property="deptAddress" column="dept_address"/>    
    </resultMap>
    <!-- 定义插入的sql语句,通过命名空间+id方式被定位 -->
    <insert id="insert" parameterType="cn.it.entity.Dept">
        insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress});
    </insert>
</mapper>

修改myBatis-config.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>
    <environments default="development">
    …………        
    </environments>
     
    <mappers>
        <mapper resource="cn/it/entity/DeptMapper.xml" />
    </mappers>
    
</configuration>

1.5.7  编写数据库操作

包括操作接口及实现,接口略,实现类为:DeptDaoImpl.java

public class DeptDaoImpl {
    /**
     * 用于插入数据到dept表。
     * @param dept 部门信息
     * @return 表示受影响的行数
     */
    public int insert(Dept dept){
        /*
         * 1.读取配置信息
         * 2.构建session工厂
         * 3.创建session
         * 4.启动事务(可选)
         * 5.数据处理
         * 6.提交事务、回滚事务(可选)
         * 7.关闭session  
         */        
        int i=0;
        SqlSession session=null;
        String config="myBatis-config.xml";
       Reader reader = null;
        try {
            reader=Resources.getResourceAsReader(config);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
            session=sqlSessionFactory.openSession();
            //事务默认自动启动
            //SQL映射文件定义的命名空间+SQL语句的ID定位SQL语句,例如下的:cn.it.entity.DeptMapper.insert
            i=session.insert("cn.it.entity.DeptMapper.insert",dept);
            session.commit();        
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
        }finally{
//关闭reader对象,这里略
            session.close();
        }        
        return i;
    }
}

1.5.8  编写测试类

需要导入junit包

public class DeptTest {
    private static DeptDaoImpl deptDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        deptDaoImpl=new DeptDaoImpl();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        deptDaoImpl=null;
    }

    @Test
    public void testInsert() {
        Dept dept=new Dept();
        dept.setDeptName("市场部");
        dept.setDeptAddress("深圳");
        int i=deptDaoImpl.insert(dept);
        System.out.println("受影响行数:"+i);
    }

}

2.基本的CRUD操作

2.1         准备工作(继续使用前面的库表和代码)

2.2         别名与自定义别名

2.2.1  内置别名

对常用的 java 类型,已经内置了一些别名支持。这些别名都是不区分大小写的。(详细参看用户手机)

2.2.2  自定义别名

在myBatis的主配置文件给cn.it.entity.Dept类创建别名Dept,后继的DeptMapper.xml配置文件中可以使用别名

<!-- 通过别名简化对类的使用 -->
<typeAliases>
        <typeAlias type="cn.it.entity.Dept" alias="Dept" />
</typeAliases>

2.3  MyBatisUtil工具类

public class MyBatisUtil {

   
    private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
    private static SqlSessionFactory sessionFactory;
    
    private static String CONFIG_FILE_LOCATION = "myBatis-config.xml";

    static {
        try {
            buildSessionFactory();
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }
    private MyBatisUtil() {
    }
    
    /**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws Exception
     */
    public static SqlSession getSession() throws Exception {
        SqlSession session = (SqlSession) threadLocal.get();

        if (session == null) {
            if (sessionFactory == null) {
                buildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession()
                    : null;
            threadLocal.set(session);
        }

        return session;
    }

    /**
     *  build  session factory
     *
     */
    public static void buildSessionFactory() {
        Reader reader=null;
        try {
            reader=Resources.getResourceAsReader(CONFIG_FILE_LOCATION);
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }finally{
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     *  Close the single  session instance.
     *
     */
    public static void closeSession(){
        SqlSession session = (SqlSession) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

    /**
     *  return session factory
     *
     */
    public static SqlSessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

2.3         CRUD操作

2.3.1  新增操作

配置文件DeptMapper.xml使用别名, DeptDaoImpl.java新增方法使用工具类。

修改配置文件DeptMapper.xml(使用别名):

<!--parameterType="Dept"不写时,也能自动根据代码传递的参数Dept自动匹配 内容-->
<insert id="insert" parameterType="Dept">
        insert into dept(dept_name)    values(#{deptName});
</insert>

修改DeptDaoImpl.java新增方法(使用MyBatisUtil.java工具类):

/**
     * @param dept 部门信息
     * @return 保存信息后受影响的行数
     */
    public int saveDept(Dept dept) {
        int i = 0;
        try {
            session = MyBatisUtil.getSession();
            i = session.insert("cn.it.entity.DeptMapper.insertDept", dept);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
        } finally {
            try {
                MyBatisUtil.closeSession();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }            
        }

        return i;
}

2.3.2  修改操作

修改配置文件deptMapper.xml,添加

<update id="update" parameterType="Dept">
            update dept set dept_name=#{deptName} ,dept_address=#{deptAddress} where dept_id=#{deptId} 
</update>

修改DeptDaoImpl.java,添加update方法:

public int  update(Dept dept){
        SqlSession session = null;
        int i=0;

        try {
            session=MyBatisUtil.getSession();
            //方法的第一个参数为DeptMapper.xml文件的命名空间+id
             i=session.update("cn.it.entity.DeptMapper.update",dept);
            System.out.println("受影响行数:"+i);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
            
        }finally{
                MyBatisUtil.closeSession();
        }    
        return i;
}

2.3.3  删除操作

修改配置文件deptMapper.xml,添加

<delete id="delete" parameterType="Dept">
        delete from dept  where dept_id=#{deptId}
</delete>

修改DeptDaoImpl.java,添加delete方法:

public int delete(Dept dept){
        int i = 0;
        try {
            session=MyBatisUtil.getSession();
            //方法的第一个参数为DeptMapper.xml文件的命名空间+id
            i=session.delete("cn.it.entity.DeptMapper.delete",dept);
            //System.out.println("受影响行数:"+i);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
            
        }finally{
            MyBatisUtil.closeSession();
        }        
        return i;
}

2.3.4  查询操作(返回单条记录)

配置deptMapper.xml文件的resultMap元素及SQL查询语句

<!-- 表字段和实体属性命名一致时可以不配置 -->
    <resultMap id="deptResultMap" type="Dept">
        <id property="deptId" column="dept_id"/>
        <result property="deptName" column="dept_name"/>
        <result property="deptAddress" column="dept_address"/>    
    </resultMap>
<!—省略其它的配置信息 -->
    <!—返回单条记录,表字段和对应实体属性命名一致时可以不使用resultMap属性配置,直接使用resultType="返回的全类名或别名",建议使用前者;查询结果为所有字段时,也可以用*表示  -->
    <select id="selectOne" parameterType="int" resultMap="deptResultMap"  >
        select dept_id, dept_name from dept where dept_id=#{deptId}    
</select>

修改DeptDaoImpl.java,添加selectOne方法:

public Dept selectOne(int deptId){
        Dept dept=null;
        try {
            session=MyBatisUtil.getSession();
            dept=(Dept)session.selectOne("cn.it.entity.DeptMapper.selectOne",deptId);
            System.out.println("dept:"+dept);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return dept;
} 

2.3.5  查询操作(返回多条记录)

修改配置文件deptMapper.xml,添加

 

<!-- 返回多条记录,返回结果配置的不是集合类型,而是集合元素的类型;参数也可以通过Map等方式封装  -->
    <select id="selectList" parameterType="Map"  resultMap="deptResultMap">
        select * from dept where dept_name like #{deptName}
</select>

修改DeptDaoImpl.java,添加selectList方法:

public List<Dept> selectList(Map map){
        List<Dept> depts=null;
        try {
            session=MyBatisUtil.getSession();
            depts=session.selectList("cn.it.entity.DeptMapper.selectList",map);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return depts;
}

测试类代码:

@Test
    public void testSelectList() {
        Map map=new HashMap();
        map.put("deptName", "%研%");
        List<Dept> depts=deptDaoImpl.selectList(map);
        for(Dept dept:depts){
            System.out.println("dept:"+dept);
        }
}

3.动态SQL操作

3.1    准备工作

创建表及库,实体类,配置文件(参考上章节内容),以下为建表和库的SQL:

drop database if exists mybatis;
create database mybatis CHARACTER SET UTF8;
use mybatis;

create table dept(
    dept_id int primary key auto_increment,
    dept_name varchar(50),
    dept_address varchar(50)
);


insert into dept(dept_name,dept_address) values('研发部一部','广州');
insert into dept(dept_name,dept_address) values('研发部二部','广州');
insert into dept(dept_name,dept_address) values('研发部三部','深圳');
select * from dept;

3.2  IF语句

修改配置文件deptMapper.xml,添加

<!-- 动态IF条件 -->
    <select id="selectListUseIf" parameterType="Dept"  resultMap="deptResultMap">
        select * from dept where 1=1 
        <if test="deptId!=null">
            and dept_id=#{deptId} 
        </if>
        <if test="deptName!=null">
            and dept_name=#{deptName} 
        </if>
        <if test="deptAddress!=null">
            and dept_address=#{deptAddress}
        </if>
</select>

修改DeptDaoImpl.java,添加selectListUseIf方法:

//根据参数使用配置文件的IF语句自动填充查询的过滤条件
    public List<Dept> selectListUseIf(Dept dept){
        List<Dept> depts=null;
        try {
            session=MyBatisUtil.getSession();
            depts=session.selectList("cn.it.entity.DeptMapper.selectListUseIf",dept);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return depts;
}

3.3  WHERE语句

修改配置文件deptMapper.xml,添加

<!-- 动态Where条件 ,一般也需要与if结合使用,与纯if比较,省略了where 1=1-->
    <select id="selectListUseWhere" parameterType="Dept"  resultMap="deptResultMap">
        select * from dept
        <where>
            <if test="deptId!=null">
                and dept_id=#{deptId}
            </if>
            <if test="deptName!=null">
                and dept_name=#{deptName}
            </if>
            <if test="deptAddress!=null">
                and dept_address=#{deptAddress}
            </if>
        </where>
</select>

3.4  choose(when,otherwise)语句

修改配置文件deptMapper.xml,添加

<!-- 动态choose条件 ,如下配置,可以完成没有选择条件时,查找不出任何数据 -->
    <select id="selectListUseChoose" parameterType="Dept" resultMap="deptResultMap">
        select * from dept where 1=1
        <choose>
            <when test="deptId!=null">and dept_id=#{deptId}</when>
            <when test="deptName!=null">and dept_name=#{deptName}</when>
            <when test="deptAddress!=null">and dept_address=#{deptAddress}</when>
            <otherwise>and !1 = 1</otherwise>
        </choose>
</select>

3.5  SET语句

修改配置文件deptMapper.xml,添加

<!--动态set语句可以用来更新数据 -->
    <update id="updateUseSet" parameterType="Dept">
        update dept
        <set>
            <if test="deptName!=null">dept_name=#{deptName},</if>
            <if test="deptAddress!=null">dept_address=#{deptAddress},</if>
        </set>
        where dept_id=#{deptId}
</update>

3.6  ForEach语句

修改配置文件deptMapper.xml,添加

< <!-- 定义根据多个部门ID查询部门相关部门信息的SQL语句 ,resultMap的值是指集合里元素的类型,parameterType不用指定 -->
<select id="selectListUseForeach" parameterType="Integer[]" resultMap="deptResultMap">
        select * from dept where dept_id in
        <!-- collection="array或list",array用来对应参数为数组,list对应参数为 集合 -->
        <foreach collection="array" item="deptId" open="(" separator="," close=")">
            #{deptId}
        </foreach>
</select>

3.7  include语句

修改配置文件deptMapper.xml,添加

<!-- 使用include语句动态插入表的字段及对应的值 -->
    <sql id="key">
        <!--suffixOverrides="," 可以忽略最后“,”号 -->
        <trim suffixOverrides=",">

            <if test="deptName!=null">
                dept_name,
            </if>
            <if test="deptAddress!=null">
                dept_address,
            </if>
        </trim>
    </sql>
    <sql id="value">
        <trim suffixOverrides="," >
                <if test="deptName!=null">
                #{deptName},
            </if>
            <if test="deptAddress!=null">
                #{deptAddress},
            </if>
        </trim>
    </sql>
    
    <insert id="insertUseInclude" parameterType="Dept">
        insert into dept(
        <include refid="key" />
        ) values(
        <include refid="value"/>
        )
</insert>

 

posted @ 2017-04-07 11:35  黑夜中晚霞  阅读(357)  评论(0编辑  收藏  举报