Mybatis入门

为什么使用Mybatis?

我们要从JDBC程序开始说起

需求

案例场景: 根据 user 表,查询出所有“上海”的用户对象,返回一个pojo的 List集合。

初始化测试数据

1、创建数据库,数据库名:mybatisDemo

2、将如下Sql语句在数据库中执行,初始化测试数据

-- ----------------------------

-- Table structure for `user`

-- ----------------------------
DROP DATABASE IF EXISTS `mybatisDemo`;
CREATE DATABASE mybatisDemo CHARSET=utf8;
DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `username` varchar(32) NOT NULL COMMENT '用户名称',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `sex` char(1) DEFAULT NULL COMMENT '性别',

  `address` varchar(256) DEFAULT NULL COMMENT '地址',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of user

-- ----------------------------

INSERT INTO `user` VALUES ('1', '张三', '2018-07-10', '1', '北京');

INSERT INTO `user` VALUES ('2', '李四', '2018-07-10', '1', '上海');

INSERT INTO `user` VALUES ('3', '王五', '2018-07-10', '1', '广州');

INSERT INTO `user` VALUES ('4', '王六', '2018-07-10', '1', '深圳');

INSERT INTO `user` VALUES ('5', '王八', '2018-07-10', '1', '上海');
JDBC 实现

代码:

  1. 创建pojo类
    import java.util.Date;
    public class User {
        private Integer id;
        private String username;
        private String sex;
        private Date birthday;
        private String address;
     
        // 省略getter ,setter,toString 方法
         // ......
           // ......
    }
    
    2.编写JDBC代码
    public class JdbcTest {
        @Test
        public void test1(){
            ResultSet resultSet = null;
            PreparedStatement preparedStatement = null;
            Connection connection = null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                String url = "jdbc:mysql://127.0.0.1:3306/mybatisdemo";
                connection = DriverManager.getConnection(url,"root","root");
                List<User> users = new ArrayList<>();//JDK 1.7 之后才允许
                //
                String sql = " select  id, username ,birthday,sex , address from user where address  = ? ";
                String addr = "上海";
    
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1,addr);
    
                boolean isSelect = preparedStatement.execute();
                if(isSelect){
                    resultSet = preparedStatement.getResultSet();
                    while (resultSet.next()){
                        int id = resultSet.getInt("id");
                        String username = resultSet.getString("username");
                        Date birthday = resultSet.getDate("birthday");
                        String sex = resultSet.getString("sex");
                        String address = resultSet.getString("address");
                        User user = new User(id,username,sex,birthday,address);
                        users.add(user);
                    }
                }
                for (User u :
                        users) {
                    System.out.println(u);
                }
    
        /*        ResultSet resultSet = preparedStatement.executeQuery();
                int count = preparedStatement.executeUpdate();*/
    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
    //            关闭结果集
                if(resultSet!=null) try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); }
    //            关闭statement
                if(preparedStatement!=null) try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); }
    //            关闭连接
                if( connection!=null) try { connection.close(); } catch (SQLException e) { e.printStackTrace(); }
            }
    
        }
    }
    

JDBC问题分析:

上边使用JDBC的原始方法(未经封装)实现了查询数据库表记录的操作。

1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

2、Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变Java代码。

3、使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。

4、对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

下面我们将通过Mybatis 解决部分问题。

Mybatis 实现

  1. 创建maven工程

  2. 导入mybatis,jdbc等相关包

    <dependencies>
         <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.48</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
         <dependency>
             <groupId>org.mybatis</groupId>
             <artifactId>mybatis</artifactId>
             <version>3.5.3</version>
         </dependency>
         <!-- https://mvnrepository.com/artifact/junit/junit -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
       
     </dependencies>
  3. 建立数据库和数据表

    -- ----------------------------
    -- Table structure for `user`
    -- ----------------------------
    DROP DATABASE IF EXISTS `mybatisDemo`;
    CREATE DATABASE mybatisDemo CHARSET=utf8;
    DROP TABLE IF EXISTS `user`;
    
    CREATE TABLE `user` (
    
      `id` int(11) NOT NULL AUTO_INCREMENT,
    
      `username` varchar(32) NOT NULL COMMENT '用户名称',
    
      `birthday` date DEFAULT NULL COMMENT '生日',
    
      `sex` char(1) DEFAULT NULL COMMENT '性别',
    
      `address` varchar(256) DEFAULT NULL COMMENT '地址',
    
      PRIMARY KEY (`id`)
    
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    
    -- Records of user
    
    -- ----------------------------
    
    INSERT INTO `user` VALUES ('1', '张三', '2018-07-10', '1', '北京');
    
    INSERT INTO `user` VALUES ('2', '李四', '2018-07-10', '1', '上海');
    
    INSERT INTO `user` VALUES ('3', '王五', '2018-07-10', '1', '广州');
    
    INSERT INTO `user` VALUES ('4', '王六', '2018-07-10', '1', '深圳');
    
    INSERT INTO `user` VALUES ('5', '王八', '2018-07-10', '1', '上海');
  4. 配置jdk编译环境,防止乱码

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                        </configuration>
            </plugin>
        </plugins>
    </build>
  5. 新建实体类和Dao接口

public class User {
    private Integer id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
}
//get,set 构造方法以及toString方法省略
public interface UserDao {
    User selectUserByPrimaryKey(int id);
}
  1. 配置使用mybatis

    1. 配置文件:mybatis-cofig.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="env1">
              <environment id="env1">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisDemo"/>
                      <property name="username" value="root"/>
                      <property name="password" value="root"/>
                  </dataSource>
              </environment>
          </environments>
      
      
          <mappers>
              <mapper resource="mybatis/mapper/UserMapper.xml"/>
          </mappers>
      
      </configuration>
    2. 映射文件:UserDao.xml(sql语句 )

      <?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="net.suncaper.mybatis01hello.dao.UserDao">
          <select id="selectUserByPrimaryKey" parameterType="_int" resultType="net.suncaper.mybatis01hello.domain.User">
              select * from user where id = #{id}
          </select>
      </mapper>

也可以把配置文件写成这样,使用resultMap的方式让查询出的值与实体类的属性名一一对应:

<?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="top.leafii.mybatis01.mapper.UserMapper">
    <resultMap id="userMap" type="top.leafii.mybatis01.domain.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="birthday" property="birthday"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
    </resultMap>
    <select id="selectUserByAddrSexa" parameterType="map" resultMap="userMap">
        select * from user where sex=#{sex} and address=#{address}
    </select>
</mapper>
  * 名称空间namespace要和Dao接口的完整类名对应
  * sql语句的id和方法名一致
  * 注意写上sql语句的参数和返回类型(parameterType 和 resultType )
  * parameterType如果方法中是int,parameterType要写成_int,如果方法中是Integer,就要写成int
  * resultType就是为了将查询好的数据的字段名和实体类的属性一一对应
  * 记住把映射文件添加到配置文件中(mapper标签 )
  1. 写java运行代码

    • 读取配置文件
    • 创建SqlSessionFactory对象
    • 打开SqlSession 对象(mybatis框架的核心对象)
    • 通过SqlSession获取UserDao接口对象
    • 执行对应的sql方法
    • 关闭SqlSession
public class Main {
    UserDao dao = null;
    public static void main(String[] args) throws Exception {
       //1. 读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml");
        //2. 创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3. 打开SqlSession,SqlSession相当于jdbc的Connection
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //4. 拿到Dao接口代理对象
        UserDao dao = sqlSession.getMapper(UserDao.class);
        User user = dao.selectUserByPrimaryKey(5);
        System.out.println(user);
        //5.关闭资源
        sqlSession.close();
    }
}

Mybatis官网
mavenreposiry网站