在JavaEE中使用Mybatis框架
MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。每个 MyBatis 应用程序主要都是使用 SqlSessionFactory 实例的,一个 SqlSessionFactory 实例可以通过 SqlSessionFactoryBuilder 获得。SqlSessionFactoryBuilder 可以从一个 xml 配置文件或者一个预定义的配置类的实例获得。
使用框架就是引用别人封装好的 jar 包,按照别人规定好的方式进行配置并调用 jar 包里的各种方法。那 Mybatis 需要进行哪些配置呢?我们来看一个例子:
一、使用XML实现数据的访问
1、创建简单的 POJO 类
package com.wenji.entity; public class Employee { private int id; private String firstName; private String lastName; private int salary; public Employee() {} public Employee(int id,String firstName, String lastName, int salary) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.salary = salary; } //省略getter、setter方法 }
2、设置 mybatis 配置文件
Configure.xml(文件名随便起), 在 src/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> <typeAliases> <typeAlias type="com.wenji.entity.Employee" alias="Employee"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="oracle.jdbc.driver.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </dataSource> </environment> </environments> <mappers> <mapper resource="com/wenji/mapping/Employee.xml"></mapper> </mappers> </configuration>
3、设置 Mybatis 映射文件
<?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.wenji.UserMapper"> <select id="GetEmployeeByID" parameterType="int" resultType="Employee"> select id,first_name firstName,last_name lastName,salary from HTCPP.Employee where id = #{id} </select> </mapper>
下面是对这两个配置文件一点解释说明:
- 配置文件 Configure.xml 是 mybatis 用来建立 sessionFactory,里面主要包含了数据库连接相关内容,还有 java 类所对应的别名,比如:<typeAlias type="com.wenji.entity.Employee" alias="Employee"/> 这个别名非常重要,在具体的类的映射中,比如: Employee.xml 中 resultType 就是对应这个。要保持一致,这里的 resultType 还有另外单独的定义方式,后面我们再详细介绍说明。
- Configure.xml 里面的 <mapper resource="com/wenji/mapping/Employee.xml"></mapper> 是包含要映射的类的 xml 配置文件。
- 在 Employee.xml 文件里面主要是定义各种 SQL 语句,以及这些语句的参数,以及要返回的类型等等。
4、测试是否成功
package com.wenji.test; import java.util.List; import java.util.Date; import java.util.Iterator; import java.io.Reader; 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 com.wenji.entity.Employee; public class ManageEmployee { private static SqlSessionFactory sqlSessionFactory; private static Reader reader; static { try { reader = Resources.getResourceAsReader("configure.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (Exception e) { e.printStackTrace(); } } public static SqlSessionFactory getSession() { return sqlSessionFactory; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SqlSession session = sqlSessionFactory.openSession(); try { Employee employee = (Employee) session.selectOne( "com.wenji.UserMapper.GetEmployeeByID", 2); if(employee!=null){ System.out.println("First Name: " + employee.getFirstName()); System.out.println("Last Name: " + employee.getLastName()); System.out.println("Salary: " + employee.getSalary()); } } finally { session.close(); } } }
二、使用注解实现数据的访问
Mybatis 也提供了注解的方式来定义映射,来看下面这个示例
Employee 类不变,Employee.xml 文件不见了,取而代之的是 IEmployee.java 接口
package com.wenji.dao; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import com.wenji.entity.Employee; public interface IEmployee { @Select("select id,first_name firstName,last_name lastName,salary from Employee where id = #{id3}") public Employee getEmployeeByID(int id2); @Select("select id,first_name firstName,last_name lastName,salary from Employee ") public List<Employee> getEmployeeList(); @Insert(" INSERT INTO Employee(id,first_name, last_name,salary) VALUES(#{id}, #{firstName}, #{lastName}, #{salary})") public void insertEmployee(Employee ee); @Update("UPDATE Employee SET id=#{id},first_name = #{firstName},last_name = #{lastName},salary = #{salary} WHERE id =#{id}") public void updateEmployee(Employee ee); @Delete("DELETE FROM Employee WHERE id = #{id}") public void deleteEmployee(int id); }
因为不存在 Employee.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> <typeAliases> <typeAlias type="com.wenji.entity.Employee" alias="Employee"/> <!-- <package name="entity"></package> --> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="oracle.jdbc.driver.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property> <property name="username" value="developer"></property> <property name="password" value="developer"></property> </dataSource> </environment> </environments> <mappers> <!-- <mapper resource="com/wenji/mapping/Employee.xml"></mapper> --> </mappers> </configuration>
测试方法有很大的不同
package com.wenji.test; import java.util.List; import java.util.Date; import java.util.Iterator; import java.io.Reader; 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 com.wenji.dao.IEmployee; import com.wenji.entity.Employee; public class ManageEmployee { private static SqlSessionFactory sqlSessionFactory; private static Reader reader; static { try { reader = Resources.getResourceAsReader("configure.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); sqlSessionFactory.getConfiguration().addMapper(IEmployee.class); } catch (Exception e) { e.printStackTrace(); } } public static SqlSessionFactory getSession() { return sqlSessionFactory; } public static void main(String[] args) { getEmployeeByID(1); // getEmployeeList(); // testInsert(); // testUpdate(); // testDelete(); } private static void getEmployeeByID(int id){ SqlSession session = sqlSessionFactory.openSession(); try { IEmployee iEmployee = session.getMapper(IEmployee.class); Employee employee = iEmployee.getEmployeeByID(id); System.out.print("First Name: " + employee.getFirstName()); System.out.print(" Last Name: " + employee.getLastName()); System.out.println(" Salary: " + employee.getSalary()); } finally { session.close(); } } private static void getEmployeeList(){ SqlSession session = sqlSessionFactory.openSession(); try { IEmployee iEmployee = session.getMapper(IEmployee.class); List<Employee> employees = iEmployee.getEmployeeList(); printEmployees(employees); } finally { session.close(); } } public static void testInsert(){ try{ // 获取Session连接 SqlSession session = sqlSessionFactory.openSession(); // 获取Mapper IEmployee eMapper = session.getMapper(IEmployee.class); System.out.println("Test insert start..."); // 执行插入 Employee ee = new Employee(); ee.setId(5); ee.setFirstName("zhang"); ee.setLastName("san"); ee.setSalary(100); eMapper.insertEmployee(ee); // 提交事务 session.commit(); // 显示插入之后Employee信息 System.out.println("After insert"); getEmployeeList(); System.out.println("Test insert finished..."); }catch (Exception e){ e.printStackTrace(); } } public static void testUpdate(){ try{ SqlSession session = sqlSessionFactory.openSession(); IEmployee eMapper = session.getMapper(IEmployee.class); System.out.println("Test update start..."); printEmployees(eMapper.getEmployeeList()); // 执行更新 Employee ee = eMapper.getEmployeeByID(5); ee.setFirstName("New name"); eMapper.updateEmployee(ee); // 提交事务 session.commit(); // 显示更新之后Employee信息 System.out.println("After update"); getEmployeeList(); System.out.println("Test update finished..."); }catch (Exception e){ e.printStackTrace(); } } // 删除用户信息 public static void testDelete(){ try{ SqlSession session = sqlSessionFactory.openSession(); IEmployee eMapper = session.getMapper(IEmployee.class); System.out.println("Test delete start..."); // 显示删除之前Employee信息 System.out.println("Before delete"); getEmployeeList(); // 执行删除 eMapper.deleteEmployee(5); // 提交事务 session.commit(); // 显示删除之后User信息 System.out.println("After delete"); getEmployeeList(); System.out.println("Test delete finished..."); }catch (Exception e){ e.printStackTrace(); } } /** * * 打印用户信息到控制台 * * @param users */ private static void printEmployees(final List<Employee> employees) { for (Employee employee : employees) { System.out.print("id: " + employee.getId()); System.out.print("First Name: " + employee.getFirstName()); System.out.print(" Last Name: " + employee.getLastName()); System.out.println(" Salary: " + employee.getSalary()); } } }
三、使用接口+XML实现数据的访问
从上面两个例子可以看出,注解的方式简洁且代码友好,XML的方式可以实现更复杂的功能,且官方推荐使用XML的方式。
为了代码友好且使用XML,可以使用接口+XML的方式,只需简单的修改方式一。
增加 IEmployee.java 接口,注意:接口的路径需要和 mybatis 命名空间保持一致。
然后就可以使用方式二的测试方法访问数据库,注意:方式二测试方法中的红色代码可以去掉了。
package com.wenji.dao; import java.util.List; import com.wenji.entity.Employee; public interface IEmployee { Employee getEmployeeByID(int id2); List<Employee> getEmployeeList(); void insertEmployee(Employee ee); void updateEmployee(Employee ee); void deleteEmployee(int id); }