今天总结的是mybatis,首先说mybatis是什么?
MyBatis 是一个简化和实现了 Java 数据持久化层(persistence layer)的开源框架,它抽象了大量的 JDBC 冗余代 码,并提供了一个简单易用的 API 和数据库交互。 MyBatis 的前身是 iBATIS,iBATIS 于 2002 年由 Clinton Begin 创建。MyBatis 3 是 iBATIS 的全新设计,支持 注解和 Mapper。
而 MyBatis 流行起来有以下原因:
? 它消除了大量的 JDBC 冗余代码
? 它有低的学习曲线
? 它能很好地与传统数据库协同工作
? 它可以接受 SQL 语句
? 它提供了与 Spring 和 Guice 框架的集成支持
? 它提供了与第三方缓存类库的集成支持
? 它引入了更好的性能
下面介绍一个mybatis的小例子:
使用 MyBatis 开发一个简单的 Java 项目:大致步骤如下
? 新建表 STUDENTS,插入样本数据
? 新建一个 Java 项目,将 MyBatis-3.2.2.jar 添加到 classpath 中
? 新建建 MyBatisSqlSessionFactory 单例模式类
? 新建映射器 StudentMapper 接口和 StudentService 类
? 新建一个 JUnit 测试类来测试 StudentService
①我使用的是mysql,首先新建一个数据库mybatis1,再新建表STUDENTS
CREATE TABLE STUDENTS ( stud_id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, email varchar(50) NOT NULL, dob date DEFAULT NULL, PRIMARY KEY (stud_id) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; /*Sample Data for the students table */ insert into students(stud_id,name,email,dob) values (1,‘Student1‘,‘[email protected]‘,‘1983-06-25‘); insert into students(stud_id,name,email,dob) values (2,‘Student2‘,‘[email protected]‘,‘1983-06-25‘);
②我新建的是maven项目,导入jar包在pom.xml中进行了配置
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.bai</groupId> 5 <artifactId>bai</artifactId> 6 <packaging>war</packaging> 7 <version>1.0-SNAPSHOT</version> 8 <name>bai Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <dependencies> 11 <dependency> 12 <groupId>junit</groupId> 13 <artifactId>junit</artifactId> 14 <version>3.8.1</version> 15 <scope>test</scope> 16 </dependency> 17 18 <dependency> 19 <groupId>org.mybatis</groupId> 20 <artifactId>mybatis</artifactId> 21 <version>3.2.2</version> 22 <scope>test</scope> 23 </dependency> 24 <dependency> 25 <groupId>mysql</groupId> 26 <artifactId>mysql-connector-java</artifactId> 27 <version>5.1.22</version> 28 <scope>runtime</scope> 29 </dependency> 30 31 <dependency> 32 <groupId>org.slf4j</groupId> 33 <artifactId>slf4j-api</artifactId> 34 <version>1.7.5</version> 35 <scope>test</scope> 36 </dependency> 37 <dependency> 38 <groupId>org.slf4j</groupId> 39 <artifactId>slf4j-log4j12</artifactId> 40 <version>1.7.5</version> 41 <scope>runtime</scope> 42 </dependency> 43 <dependency> 44 <groupId>log4j</groupId> 45 <artifactId>log4j</artifactId> 46 <version>1.2.17</version> 47 <scope>runtime</scope> 48 </dependency> 49 </dependencies> 50 <build> 51 <finalName>bai</finalName> 52 </build> 53 </project>
③ 新建 log4j.properties 文件,添加到 classpath 中.
log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d [%-5p] %c - %m%n
④ 创建 MyBatis 的主要配置文件 mybatis-config.xml,其中包括数据库连接信息,类型别名等等,然后将其加 到 classpath 中;
<?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 alias="Student" type="com.mybatis3.domain.Student" /> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis1" /> <property name="username" value="root" /> <property name="password" value="" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/mybatis3/mappers/StudentMapper.xml" /> </mappers> </configuration>
⑤创建 SQL 映射器 XML 配置文件 StudentMapper.xml 并且将它放在 com.mybatis3.mappers 包中,注意这个包要在resource下面,如果在main下面的话,会遇到读取不到这个配置文件的问题
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 <mapper namespace="com.mybatis3.mappers.StudentMapper"> 5 <resultMap type="Student" id="StudentResult"> 6 <id property="studId" column="stud_id" /> 7 <result property="name" column="name" /> 8 <result property="email" column="email" /> 9 <result property="dob" column="dob" /> 10 </resultMap> 11 <select id="findAllStudents" resultMap="StudentResult"> 12 SELECT * FROM STUDENTS 13 </select> 14 <select id="findStudentById" parameterType="int" resultType="Student"> 15 SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB 16 FROM STUDENTS WHERE STUD_ID=#{Id} 17 </select> 18 <insert id="insertStudent" parameterType="Student"> 19 INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB) 20 VALUES(#{studId },#{name},#{email},#{dob}) 21 </insert> 22 </mapper>
⑥ 新建 MyBatisSqlSessionFactory 单例类
1 package com.mybatis3.util; 2 3 import org.apache.ibatis.io.Resources; 4 import org.apache.ibatis.session.SqlSession; 5 import org.apache.ibatis.session.SqlSessionFactory; 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 7 8 import java.io.*; 9 import java.io.IOException; 10 import java.io.InputStream; 11 12 /** 13 * Created by peng on 2016/8/4. 14 */ 15 public class MyBatisSqlSessionFactory { 16 private static SqlSessionFactory sqlSessionFactory; 17 public static SqlSessionFactory getSqlSessionFactory(){ 18 if(sqlSessionFactory==null){ 19 InputStream inputStream; 20 try { 21 inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 22 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 23 } 24 catch(IOException e){ 25 System.out.println("aaa"); 26 System.out.println(e.getMessage()); 27 throw new RuntimeException(e.getCause()); 28 } 29 } 30 return sqlSessionFactory; 31 } 32 public static SqlSession openSession(){ 33 return getSqlSessionFactory().openSession(); 34 } 35 }
上述的代码段中,我们创建了一个 SqlSessionFactory 对象,我们将使用它来获得 SqlSession 对象和执行映射的SQL 语句。
⑦ 新建 StudentMapper 接口和 StudentService 类
1. 首先, 创建 JavaBean Student.java
1 package com.mybatis3.domain; 2 3 import java.util.Date; 4 5 /** 6 * Created by peng on 2016/8/4. 7 */ 8 public class Student { 9 private Integer studId; 10 private String name; 11 private String email; 12 private Date dob; 13 public String getName() { 14 return name; 15 } 16 17 public Integer getStudId() { 18 return studId; 19 } 20 21 public String getEmail() { 22 return email; 23 } 24 25 public Date getDob() { 26 return dob; 27 } 28 29 30 public void setStudId(Integer studId) { 31 this.studId = studId; 32 } 33 34 public void setName(String name) { 35 this.name = name; 36 } 37 38 public void setEmail(String email) { 39 this.email = email; 40 } 41 42 public void setDob(Date dob) { 43 this.dob = dob; 44 } 45 46 47 48 }
2. 创建映射器 Mapper 接口 StudentMapper.java 其方法签名和 StudentMapper.xml 中定义的 SQL 映射定义名 相同
1 package com.mybatis3.mappers; 2 3 import com.mybatis3.domain.Student; 4 5 import java.util.List; 6 7 /** 8 * Created by peng on 2016/8/4. 9 */ 10 public interface StudentMapper { 11 List<Student>findAllStudents(); 12 Student findStudentById(Integer id); 13 void insertStudent(Student student); 14 15 }
3. 现在创建 StudentService.java 实现对表 STUDENTS 的数据库操
1 package com.mybatis3.services; 2 3 import com.mybatis3.domain.Student; 4 import com.mybatis3.mappers.StudentMapper; 5 import com.mybatis3.util.MyBatisSqlSessionFactory; 6 import org.apache.ibatis.session.SqlSession; 7 import org.slf4j.LoggerFactory; 8 9 import java.util.List; 10 11 /** 12 * Created by peng on 2016/8/4. 13 */ 14 public class StudentService { 15 private org.slf4j.Logger logger= LoggerFactory.getLogger(getClass()); 16 public List<Student>findAllStudents() 17 { 18 SqlSession sqlSession= MyBatisSqlSessionFactory.openSession(); 19 try { 20 StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); 21 return studentMapper.findAllStudents(); 22 } 23 finally { 24 sqlSession.close(); 25 } 26 } 27 public Student findStudentById(Integer studId) 28 { 29 logger.debug("Select Student By ID:{}",studId); 30 SqlSession sqlSession=MyBatisSqlSessionFactory.openSession(); 31 try{ 32 StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class); 33 return studentMapper.findStudentById(studId); 34 } 35 finally { 36 sqlSession.close(); 37 } 38 } 39 public void createStudent(Student student) 40 { 41 SqlSession sqlSession=MyBatisSqlSessionFactory.openSession(); 42 try{ 43 StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class); 44 studentMapper.insertStudent(student); 45 sqlSession.commit(); 46 } 47 finally { 48 sqlSession.close(); 49 } 50 } 51 }
⑨ 新建一个 JUnit 测试类来测试 StudentService
1 package com.mybatis3.services; 2 3 import com.mybatis3.domain.Student; 4 import org.junit.AfterClass; 5 import org.junit.Assert; 6 import org.junit.BeforeClass; 7 import org.junit.Test; 8 9 import java.util.Date; 10 import java.util.List; 11 12 /** 13 * Created by peng on 2016/8/4. 14 */ 15 public class StudentServiceTest { 16 private static StudentService studentService; 17 @BeforeClass 18 public static void setup(){ 19 studentService=new StudentService(); 20 } 21 @AfterClass 22 public static void teardown(){ 23 studentService=null; 24 } 25 @Test 26 public void testFindAllStudents() 27 { 28 List<Student>students=studentService.findAllStudents(); 29 Assert.assertNotNull(students); 30 for(Student student:students) 31 { 32 System.out.println(student); 33 } 34 } 35 @Test 36 public void testFindStudentById() 37 { 38 Student student=studentService.findStudentById(1); 39 Assert.assertNotNull(student); 40 System.out.println(student); 41 } 42 @Test 43 public void testCCeateStudent() 44 { 45 Student student=new Student(); 46 int id=3; 47 student.setStudId(id); 48 student.setName("student_"+id); 49 student.setEmail("student_"+id+"gmail.com"); 50 student.setDob(new Date()); 51 studentService.createStudent(student); 52 Student newStudent=studentService.findStudentById(id); 53 Assert.assertNotNull(newStudent); 54 } 55 }
⑩ 它是怎么工作的
首先,我们配置了 MyBatis 最主要的配置文件-mybatis-config.xml,里面包含了 JDBC 连接参数;配置了映射器 Mapper XML 配置文件文件,里面包含了 SQL 语句的映射。
我们使用 mybatis-config.xml 内的信息创建了 SqlSessionFactory 对象。每个数据库环境应该就一个 SqlSessionFactory 对象实例,所以我们使用了单例模式只创建一个 SqlSessionFactory 实例。
我们创建了一个映射器 Mapper 接口-StudentMapper,其定义的方法签名和在 StudentMapper.xml 中定义的完全 一样(即映射器 Mapper 接口中的方法名跟 StudentMapper.xml 中的 id 的值相同)。注意 StudentMapper.xml 中 namespace 的值被设置成 com.mybatis3.mappers.StudentMapper,是 StudentMapper 接口的完全限定名。这使我们 可以使用接口来调用映射的 SQL 语句。
在 StudentService.java 中,我们在每一个方法中创建了一个新的 SqlSession,并在方法功能完成后关闭 SqlSession。每一个线程应该有它自己的 SqlSession 实例。SqlSession 对象实例不是线程安全的,并且不被共享。所 以 SqlSession 的作用域最好就是其所在方法的作用域。从 Web 应用程序角度上看,SqlSession 应该存在于 request 级 别作用域上。
注意:
在看书学习的时候,遇到了几个概念性的问题:
classpath概念:设置Classpath的目的,在于告诉Java执行环境,在哪些目录下可以找到您所要执行的Java程序所需要的类或者包。Java执行环境本身就是一个平台,执行于这个平台上的程序是已编译完成的Java程序(后面会介绍到Java程序编译完成之后,会以.class文件存在)。如果将Java执行环境比喻为操作系统,如果设置Path变量是为了让操作系统找到指定的工具程序(以Windows来说就是找到.exe文件),则设置Classpath的目的就是让Java执行环境找到指定的Java程序(也就是.class文件)。
本书中有时候提到新建了某文件加入到classpath中,放到webapp下面的WEB-INF下面即可。
resource想新建package却新建不了?
这两个文件夹的类型都是Sources的时候才能新建package,由于博主学习maven有限,原理不太明白,有懂的读者欢迎指明。
最后运行了测试类,运行成功。