学习Mybatis框架(一)

什么是Mybatis?

mybatis是一款优秀的持久层框架,她支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解来配置和映射原生信息,将接口和java的POJOs(Plain Old Java Objects,普通的java对象)映射成数据库中的记录。

一、 对原生态jdbc程序中问题总结

JDBC:java database connectivity 是SUN公司提供的一套操作数据库的标准规范。
JDBC与数据库驱动的关系:接口与实现的关系
这里写图片描述

1.开发一个JDBC程序流程

实现查询数据库中的数据显示在java的控制台上

1、创建数据库表,并向表中添加测试数据
2、创建java project项目,添加数据库驱动(*.jar)
3、实现JDBC操作

  1. 加载数据库驱动
  2. 创建数据库链接
  3. 获取操作数据库sql语句的PreparedStatement对象
  4. 执行sql语句,并返回结果集ResultSet对象
  5. 处理结果
  6. 关闭资源
    这里写图片描述
2.JDBC常用的类和接口详解

1、java.sql.Drivermanager类 : 创建连接

a.与数据库建立连接
getConnection(String url, String user, String password) : 建立到给定数据库 URL 的连接
jdbc:mysql://localhost:3306/day06
协议 子协议 IP :端口号 数据库

2、java.sql.Connection接口:一个连接
接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
prepareStatement()//创建操作sql语句的对象
说明:
PreparedStatement:预编译对象, 是Statement对象的子类。
特点:性能要高,会把sql语句先编译,sql语句中的参数会发生变化,过滤掉用户输入的关键字。

3、java.sql.Statement接口: 操作sql语句,并返回相应结果的对象(小货车)
接口的实现在数据库驱动中。用于执行静态 SQL 语句并返回它所生成结果的对象。

4、java.sql.ResultSet接口: 结果集(客户端存表数据的对象)
这里写图片描述
提供一个游标,默认游标指向结果集第一行之前。
调用一次next(),游标向下移动一行。
提供一些get方法。

封装数据的方法
Object getObject(int columnIndex); 根据序号取值,索引从1开始
Object getObject(String ColomnName); 根据列名取值。

将结果集中的数据封装到javaBean中
java的数据类型与数据库中的类型的关系(自己查询)

3.jdbc程序中问题总结

  1. 数据库连接,使用就创建,不适用就立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能
    解决方法:在SqlMapConfig.xml中使用数据库连接池管理数据库连接
  2. 将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护;
    解决方法:将sql语句配置在xml文件,与java代码分离,从而避免sql变化时对java代码的重新编译
  3. 向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
    解决方法:将sql语句及占位符号和参数全部配置在xml中。
  4. 从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
    解决方法: MyBatis将结果集自动映射成java对象,通过statement中的resultType定义输出结果的类型。

二、 Mybatis框架原理

这里写图片描述
下面作简要概述:

  1. 1) SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句,此文件需要在SqlMapConfig.xml中加载。

  2. 2) 通过mybatis环境等配置信息构造SqlSessionFactory(即会话工厂)。

  3. 3)由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

  4. 4) mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

  5. 5) MappedStatement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的id。

  6. 6) MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是JDBC编程中对preparedStatement设置参数。

  7. 7) MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于JDBC编程中对结果的解析处理过程。

三、 Mybatis入门程序

3.0 mybatis下载
mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
大家可从该地址下载mybatis最新框架。 本人下载的是mybatis-3.2.7,其目录结构为:
这里写图片描述
这里写图片描述
3.1 开发需求

  1. 根据用户id(主键)查询用户信息
  2. 根据用户名称模糊查询用户信息
  3. 添加用户
  4. 删除 用户
  5. 更新用户

3.2 配置环境
lib下加入的jar包:依赖包,mybatis核心包,mysql的驱动包

3.3 创建日志记录文件 log4j.properties
可在mybatis1222工程下新建一个config源码包,并在该源码包下创建一个日志记录文件——log4j.properties

# Global logging configuration
#在开发环境下日志级别设置成DEBUG,生产环境设置成Info或者error
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3.4 创建 SqlMapConfig.xml 文件
我们同样可在config源码包下创建该文件

<?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>
    <!-- 和spring整合后environments配置将废除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>
</configuration>

SqlMapConfig.xml是mybatis的核心配置文件,以上文件的配置内容为数据源、事务管理。
注意:等后面mybatis和Spring两个框架整合之后,environments的配置将被废除。
3.5 工程结构
这里写图片描述
3.6 根据用户id(主键)查询用户信息

3.6.1 创建pojo类( User.java )
我们可在src目录下新建一个名为cn.itheima.mybatis.pojo的包,并在该包下创建一个pojo类——User.java
这里写图片描述

//User.java
package cn.itcast.mybatis.pojo;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable{
//属性名和数据库表的字段对应
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    //用户创建的订单信息
    private List<Orders>orderList;

    public int getId() {
        return id; 
    }
    public void setId(int id) {
        this.id = id;  
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    public List<Orders> getOrderList() {
        return orderList;
    }
    public void setOrderList(List<Orders> orderList) {
        this.orderList = orderList;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
                + address + "]";
    }
}

3.6.2 映射文件( User.xml )
User.xml (原始ibatis命名)
mapper代理开发映射文件名称叫XXXMapper.xml,比如:UserMapper.xml、ItemsMapper.xml

在classpath下的sqlmap目录下创建sql映射文件user.xml ,在映射文件中配置sql语句。
这里写图片描述
//根据用户id(主键)查询用户信息 代码如下
这里写图片描述
完整代码如下:

<!--User.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">

<!-- 通过namespace命名空间,对sql进行分类化管理,理解sql隔离 -->
<!-- 在映射文件中配置sql语句 -->

<mapper namespace="test">

<!--1、根据用户id(主键)查询用户信息
id:标识映射文件中的sql,将sql语句封装到preparedStatement对象中,所以将id成为statement的id
#{}:表示占位符
#{id}:id表示输入参数,参数名称就是id,如果输入参数是简单类型,则#{}中参数名可以任意,可以value或者其他名称
resultType:指定sql输出结果所映射的java对象类型,select指定resultType表示单条记录映射的java对象
-->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.pojo.User">
SELECT*FROM USER WHERE id=#{id}
</select>


<!--2、 根据用户名称模糊查询用户信息 -->
<!--${value}:拼接符号,不建议使用,接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value-->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.pojo.User">
<!-- SELECT * FROM USER WHERE USERNAME LIKE'%张三%' -->
SELECT * FROM USER WHERE USERNAME LIKE '%${value}%'
</select>


<!-- 3、添加用户 -->
<!-- 自增主键返回 
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:相对于insert来说,它的执行顺序
resultType:指定的结果类型 -->

<insert id="insertUser" parameterType="cn.itcast.mybatis.pojo.User">

<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>

insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
<!-- 
使用mysql的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
 -->
<!--  
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
    SELECT uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
 -->   
</insert>

<!-- 4、删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>

<!-- 5、更新用户 -->
<update id="updateUser" parameterType="cn.itcast.mybatis.pojo.User">
update user set
username = #{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>

</mapper>

3.6.3 在SqlMapConfig.xml加载映射文件.xml
在sqlMapConfig.xml中加载User.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>
    <settings>
        <!-- 开启延迟加载,注意必须写在前面 -->
            <!-- 打开延迟加载开关 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!-- 将积极加载改为消极加载即是按需加载 -->
            <setting name="aggressiveLazyLoading" value="false"/>

        <!-- 开启二级缓存 -->
           <setting name="cacheEnabled" value="true"/>
    </settings>


    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理,事务控制由mybatis管理-->
            <transactionManager type="JDBC" />
        <!-- 数据库连接池,由mybatis管理-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>


    <!-- 加载映射文件 -->
    <mappers>
        <!-- 1、通过resource方法一次加载一个映射文件 -->
        <mapper resource="sqlmap/User.xml" /> 
        <!-- 2、通过mapper接口加载单个 映射文件
                遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
                上边规范的前提是:使用的是mapper代理方法 -->
        <!--  <mapper resource="mapper/UserMapper.xml" /> (很重要!!!) --> 
         <!--3、批量加载mapper
                指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
                遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
                上边规范的前提是:使用的是mapper代理方法-->
        <package name="cn.itcast.mybatis.mapper"/>
    </mappers> 

</configuration>

说明:
在sqlmap文件目录里面User.xml中写入sql查询语句(以及输入参数,输出参数信息),然后将User.xml配置文件加载进SqlMapConfig.xml文件中。然后在源文件中导入SqlMapConfig.xml。

数据库里面加载.sql语句,是右键->运行SQL文件,添加进去即可

3.6.4程序测试
在src目录下新建一个名为cn.itheima.mybatis.first的包,并在该包下创建一个MybatisFirst 单元测试类,紧接着在该类中编写如下单元测试方法:
这里写图片描述
完整代码如下:

package cn.itcast.mybatis.first;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.annotation.Resource;
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 org.junit.Test;
import cn.itcast.mybatis.pojo.User;

public class MybatisFirst {

//1、根据id查询用户信息,得到一条记录结果
    @Test
    public void findUserByIdTest() throws Exception{
        //导入mybatis配置文件
        String resource="SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //1、创建会话工厂
        SqlSessionFactory sqlSessionFactory=
                new SqlSessionFactoryBuilder().build(inputStream);
        //2、根据工厂得到sqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //3、通过sqlSession操作数据库
             //(control键然后attach mybatis-3.2.7-source.zip )
        //statement=namespace.id
        //parameter:指定和映射文件中所匹配的parameterType类型的参数
        //sqlSession。selectOne结果是与映射文件中所匹配的resultType类型的参数
        User user=sqlSession.selectOne("test.findUserById", 1);
        System.out.println(user);

        //4、关闭会话
        sqlSession.close(); 
    }

//2、根据用户名字模糊查询
    @Test
    public void findUserByNameTest() throws Exception{
        //导入mybatis配置文件
        String resource="SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //1、创建会话工厂
        SqlSessionFactory sqlSessionFactory=
                new SqlSessionFactoryBuilder().build(inputStream);
        //2、根据工厂得到sqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //3、通过sqlSession操作数据库
             //(control键然后attach mybatis-3.2.7-source.zip )
        //statement=namespace.id
        //parameter:指定和映射文件中所匹配的parameterType类型的参数
        //sqlSession.selectOne结果是与映射文件中所匹配的resultType类型的参数
        //selectList:表示查询出一个列表
        List<User>list=sqlSession.selectList("test.findUserByName", "张三");
        System.out.println(list);

        //4、关闭会话
        sqlSession.close(); 
    }

//3、插入用户信息
    @Test
    public void insertUserTest() throws Exception{
        //导入mybatis配置文件
        String resource="SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream= Resources.getResourceAsStream(resource);

        //1、创建会话工厂
        SqlSessionFactory sqlSessionFactory=
                new SqlSessionFactoryBuilder().build(inputStream);
        //2、根据工厂得到sqlSession
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //3、通过sqlSession操作数据库
        //插入用户对象
        User user=new User();
        user.setUsername("王小军");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("河南郸城");

        sqlSession.insert("test.insertUser",user);

        //提交事务
        sqlSession.commit();

        //获取用户信息主键
        System.out.println(user.getId());

        //4、关闭会话
        sqlSession.close();         
    }

//4、删除用户信息
        @Test
        public void deleteUserTest() throws Exception{
            //导入mybatis配置文件
            String resource="SqlMapConfig.xml";
            //得到配置文件流
            InputStream inputStream= Resources.getResourceAsStream(resource);
            //1、创建会话工厂
            SqlSessionFactory sqlSessionFactory=
                    new SqlSessionFactoryBuilder().build(inputStream);
            //2、根据工厂得到sqlSession
            SqlSession sqlSession=sqlSessionFactory.openSession();
            //3、通过sqlSession操作数据库
            //根据id 删除用户
            sqlSession.delete("test.deleteUser",27);                
            //提交事务
            sqlSession.commit();

            //4、关闭会话
            sqlSession.close(); 

        }

//5、更新用户信息
        @Test
        public void updateUserTest() throws Exception{
           //导入mybatis配置文件
            String resource="SqlMapConfig.xml";
            //得到配置文件流
            InputStream inputStream= Resources.getResourceAsStream(resource);
            //1、创建会话工厂
            SqlSessionFactory sqlSessionFactory=
                    new SqlSessionFactoryBuilder().build(inputStream);
            //2、根据工厂得到sqlSession
            SqlSession sqlSession=sqlSessionFactory.openSession();
            //3、通过sqlSession操作数据库
            //更新用户对象
            User user=new User();
            //必须设置id
            user.setId(29);
            user.setUsername("王大军");
            user.setBirthday(new Date());
            user.setSex("2");
            user.setAddress("河南洛阳");

            sqlSession.insert("test.updateUser",user);

            //提交事务
            sqlSession.commit();

            //4、关闭会话
            sqlSession.close();         
        }
}

3.7 总结

  1. parameterType:在映射文件中通过parameterType指定输入 参数的类型
  2. resultType:在映射文件中通过resultType指定输出结果的类型。

  3. selectOne 和 selectList
    selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现,使用selectList也可以实现(list中只有一个对象)。
    selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。

  4. #{} 和 ${}区别
 #{}表示一个占位符号;而 ${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
 #{}和${}均是接收输入参数,类型可以是简单类型,pojohashmap。

 如果接收简单类型,#{}中可以写成value或其它名称,而${}中只能写成value。
 如果接收pojo对象值,#{}和${}均是通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

四、mybatis 和 hibernate 本质区别和应用场景

hibernate:是一个标准ORM框架(对象关系映射)。
入门门槛较高的,不需要程序写sql,sql语句自动生成了。
对sql语句进行优化、修改比较困难的。

应用场景:适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:mybatis是一个不完全 的ORM框架,
虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。

应用场景:适用与需求变化较多的项目,比如:互联网项目。

猜你喜欢

转载自blog.csdn.net/hefenglian/article/details/80607454
今日推荐