作者: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(); } } }
所以步驟就是
- 通過 SqlSessionFactory 打開 SqlSession
- 通過 SqlSession 獲得 Mapper
- 通過 Mapper 操作數據庫
- SqlSession commit
- 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