zoukankan      html  css  js  c++  java
  • mybatis3 step by step 快速上手

    作者:Panda Fang

    出处:http://www.cnblogs.com/lonkiss/p/6895617.html

    原创文章,转载请注明作者和出处,未经允许不可用于商业营利活动

    官方网站 http://www.mybatis.org/mybatis-3/zh/index.html , 汉化做的不错

    首先安装 mysql ,不详述,前面写过

    创建一个数据库, 命名为 mybatis

    CREATE DATABASE IF NOT EXISTS `mybatis` DEFAULT CHARACTER SET utf8;

    创建一个学生表

    CREATE TABLE IF NOT EXISTS `t_student` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) NOT NULL,
      `age` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    插入一条记录

    INSERT INTO `t_student` (`id`, `name`, `age`) VALUES(1, '张三', 10);

    eclipse 中创建 maven  project , archetype 选择 quickstart

    最终结构预览

    pom 中加入 依赖

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.8</version>
    </dependency>

    再加上 mysql jdbc 依赖

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.42</version>
    </dependency>

    在src/main/java 目录中创建两个文件, jdbc.properties 和 mybatis-config.xml

    jdbc.properties 内容

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis
    jdbc.username=root
    jdbc.password=123456

    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>
      <properties resource="jdbc.properties" />
      
      <environments default="development">
        <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
          </dataSource>
        </environment>
      </environments>
    </configuration>

    mybatis-config.xml 内容这么长, 哪里来, 可以直接复制官方文件 入门教程 中模板。 但是要稍作修改,比如指定 properties文件 通过  <properties resource="jdbc.properties" />  放在  environments   内容之前

    下面的value 名称引用的变量名也要改成 jdbc.properties 文件中的 key 名称, 又或者 jdbc.properties 中的key名称与官方教程中的名称一致则可以不用改

    建一个util子包, 建一个DBUtil类

    package com.github.pandafang.mybatis.quickstart.util;
    
    import java.io.IOException;
    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;
    
    public class DBUtil {
    
        private static SqlSessionFactory sqlSessionFactory;
        
        public static SqlSessionFactory getSqlSessionFactory()  {
            
            if (sqlSessionFactory == null ) {
                String resource = "mybatis-config.xml";
                InputStream inputStream = null;
                try {
                    inputStream = Resources.getResourceAsStream(resource);
                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                } catch (IOException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
            return sqlSessionFactory;
        }
        
        public static SqlSession openSqlSession() {
            return getSqlSessionFactory().openSession();
        }
    }

    注意  String resource = "mybatis-config.xml";  如果mybatis-config.xml文件不是在 源代码的根目录下,而是在某个包下,则要写成 "org/mybatis/example/mybatis-config.xml" 这种形式。所谓源代码根目录,如果是个常见结构的项目,就是指在src目录下, 如果是maven约定结构的,就是在 src/main/java目录下 。

    SqlSessionFactory和SqlSession是mybatis中操作数据库 的核心。

    建一个model子包, 建一个 Student 类

    package com.github.pandafang.mybatis.quickstart.model;
    
    public class Student {
    
        private Integer id;
        private Integer age;
        private String name;
        
        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
    }

    代码写好之后,在 mybatis-config.xml 中 增加 typeAlias , 注意位置 要在 properties之后 environments 之前

    <configuration>
    
      <properties resource="jdbc.properties" />
      
        <typeAliases>
          <typeAlias alias="Student" type="com.github.pandafang.mybatis.quickstart.model.Student"/>
        </typeAliases>
      
      <environments default="development">
         
    …………………………
    其它内容
    …………………………
    
    </configuration>

    建一个mapper子包, 建一个StudentMapper  interface 

    package com.github.pandafang.mybatis.quickstart.mapper;
    
    import com.github.pandafang.mybatis.quickstart.model.Student;
    
    public interface StudentMapper {
        
        public int add(Student student);
    
    }

    再在同位置建一个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.github.pandafang.mybatis.quickstart.mapper.StudentMapper">
      <insert id="add" parameterType="Student">
        INSERT INTO t_student(name, age) VALUES(#{name}, #{age})
      </insert>
    </mapper>

    namespace 就是 mapper的含包名的完整限定名, <insert> 就是插入操作,其他还有 select update delete 等等(官方文档:mybatis – MyBatis 3 | Mapper XML 文件), id 就是StudentMapp中定义的方法名, parameterType 就是这个方法的参数类型,此处Student, 就是mybatis-config.xml 中的 typeAlias 定义的alias, 如果没有定义 typeAlias ,这个parameterType 后面也要使用Student的含包名的完整限定名。mybatis是半自动的orm框架, 这里还是要写SQL , #{name} 这种形式就是取 Student类中的属性

    准备工作做完, 开始真正通过mybatis操作数据库了。

    maven project自带了一个App 类, 如果没有可以自己建一个,在main方法里面执行数据库增加记录的操作 ,代码如下

    package com.github.pandafang.mybatis.quickstart;
    
    import org.apache.ibatis.session.SqlSession;
    
    import com.github.pandafang.mybatis.quickstart.mapper.StudentMapper;
    import com.github.pandafang.mybatis.quickstart.model.Student;
    import com.github.pandafang.mybatis.quickstart.util.DBUtil;
    
    public class App 
    {
        public static void main( String[] args )
        {
            SqlSession ss = DBUtil.openSqlSession();
            try {
                
                Student student = new Student("李四", 22);
                StudentMapper studentMapper = ss.getMapper(StudentMapper.class);
                int result = studentMapper.add(student);
                ss.commit();
                if (result > 0) {
                    System.out.println("增加成功, result:" + result);
                }
                else {
                    System.out.println("增加失败");
                }
                
            } 
            finally {
                ss.close();
            }
           
        }
    }

    所以步骤就是

    1. 通过 SqlSessionFactory 打开 SqlSession 
    2. 通过 SqlSession 获得 Mapper
    3. 通过 Mapper 操作数据库
    4. SqlSession commit
    5. SqlSession close

     至此 一个完整可运行的demo完成

    代码在线阅读: https://coding.net/u/pandafang/p/mybatis-quickstart/git/tree/v1.0

    前面已经做了 增,继续完成改、查、删。

    修改 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.github.pandafang.mybatis.quickstart.mapper.StudentMapper">
    
    <resultMap type="Student" id="StudentResult">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
    </resultMap>
    
      <insert id="add" parameterType="Student">
        INSERT INTO t_student(name, age) VALUES(#{name}, #{age})
      </insert>
      <update id="update" parameterType="Student">
          UPDATE t_student SET name=#{name}, age=#{age} WHERE id=#{id}
      </update>
      <select id="findById" parameterType="Integer" resultType="Student">
          SELECT * FROM t_student WHERE id=#{id}
      </select>
      <select id="findAll" resultMap="StudentResult">
          SELECT * FROM t_student
      </select>
      <delete id="delete" parameterType="Integer">
          DELETE FROM t_student WHERE id=#{id}
      </delete>
    </mapper>

    修改 App.java 文件 内容变成下面这样

    package com.github.pandafang.mybatis.quickstart;
    
    import java.util.List;
    
    import org.apache.ibatis.session.SqlSession;
    
    import com.github.pandafang.mybatis.quickstart.mapper.StudentMapper;
    import com.github.pandafang.mybatis.quickstart.model.Student;
    import com.github.pandafang.mybatis.quickstart.util.DBUtil;
    
    public class App 
    {
        public static void main( String[] args )
        {
            SqlSession ss = DBUtil.openSqlSession();
            try {
                
                Student student = new Student("李四", 22);
                StudentMapper studentMapper = ss.getMapper(StudentMapper.class);
                int result = studentMapper.add(student);
                ss.commit();
                if (result > 0) {
                    System.out.println("增加成功, result:" + result);
                }
                else {
                    System.out.println("增加失败");
                }
                
                Student student2 = new Student("王五", 23);
                student2.setId(2);
                studentMapper.update(student2);
                ss.commit();
                
                Student student3 = studentMapper.findById(2);
                if (student3 != null) {
                    System.out.println("查到 student id=" + student3.getId() + " name=" + student3.getName() + " age=" + student3.getAge());
                }
                else {
                    System.out.println("没有查到id 为2的 student");
                }
                
                System.out.println("------ 查询所有的Student -------");
                List<Student> students = studentMapper.findAll();
                
                for (Student stu : students) {
                    System.out.println("查到 student id=" + stu.getId() + " name=" + stu.getName() + " age=" + stu.getAge());
                }
                
                studentMapper.delete(student3);
                ss.commit();
                
            } 
            finally {
                ss.close();
            }
           
        }
    }

     运行App ,然而在执行 findById时 报错:

    Error instantiating class …… with invalid types () or values (). Cause: java.lang.NoSuchMethodException:……<init>()

     遇到这个错误,是因为前面写有参构造函数, 无参构造函数没了, 要为 Student 类显示写出无参数构造函数。 

    再次运行 App 就ok了。

    至此,使用mybatis + mysql 增删改查就实现了。

    代码在线阅读:https://coding.net/u/pandafang/p/mybatis-quickstart/git/tree/v1.1

    延伸

    之前add返回的整数是插入的行数, 并不是id , 那插入后如何获取自增的 id 呢,

    修改 StudentMapper.xml , 在insert 上加入   useGeneratedKeys="true" keyProperty="id" 

      <insert id="add" parameterType="Student" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO t_student(name, age) VALUES(#{name}, #{age})
      </insert>

    加了上面两个属性后, 插入后 数据库自增的主键id 会自动填充到作为参数的对象中

    然后代码就是下面这样

    Student student = new Student("李四", 22);
    StudentMapper studentMapper = ss.getMapper(StudentMapper.class);
    int result = studentMapper.add(student);
    ss.commit();
    Integer id = student.getId();
    if (id != null) {
        System.out.println("插入成功 id=" + id);
    }

     参考资料 : http://www.cnblogs.com/fsjohnhuang/p/4078659.html

    至此版本的代码在线阅读: https://coding.net/u/pandafang/p/mybatis-quickstart/git/tree/v1.2

    历史版本代码下载:https://coding.net/u/pandafang/p/mybatis-quickstart/git/tags

    这篇文章的测试代码都卸载main 方法中,为了不引入过多的外部知识提高难度。 实际开发应该用junit

  • 相关阅读:
    RestTemplate的异常:Not enough variables available to expand
    WebApplicationContext类的作用
    select动态绑定vue.js
    spring的 @Scheduled的cron表达式
    Spring使用webjar
    ThreadLocal基本原理及运用
    mybatis choose标签的使用
    @RequestBody和@RequestParam区别
    js遍历 for-of
    MySql 模糊查询
  • 原文地址:https://www.cnblogs.com/lonkiss/p/6895617.html
Copyright © 2011-2022 走看看