首页 > 代码库 > MyBatis应用开发(2)应用之开发方式XML文件篇
MyBatis应用开发(2)应用之开发方式XML文件篇
1.1. 开发方法
有三种使用MyBatis的方法:
(1)使用XML配置文件的方式。
(2)使用注解方式。
(3)使用API方式。
1.2. XML方式
1.2.1. 开发步骤
目标:使用MyBatis从数据库中查询t_person表的全部记录。
MyBatis使用XML文件来配置数据库中的记录与Java对象之间的映射关系,实现了SQL语句和Java代码的分离。
使用MyBatis 的XML配置方式开发数据库应用的步骤如下所示:
(1)编写POJO类Person。
(2)编写Mapper接口PersonMapper。
(3)编写业务接口PersonService。
(4)编写业务实现类PersonServiceImpl。
(5)编写MyBatis Mapper配置文件PersonMapper.xml。
(6)编写MyBatis总体配置文件SqlMapConfig.xml。
(7)编写log4j的配置文件log4j.properties。
(8)编写单元测试类PersonServiceTest。
1.2.2. 编写POJO类
对应于数据库中的t_person表。
/** * @Title: Person.java * @Package com.test.mybatis3.pojo * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午3:21:32 * @version V1.0 */ package com.test.mybatis3.pojo; /** * @ClassName: Person * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午3:21:32 * */ public class Person { //用于满足POJO要求的无参数构造函数。 public Person() { } //用于简化测试代码。 public Person(String id, String name, int status) { super(); this.id = id; this.name = name; this.status = status; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } private String id; private String name; private int status; @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", status=" + status + "]"; } }
1.2.3. 编写Mapper接口
使用MyBatis访问数据库,有两种方式:
(1)直接使用SqlSession的selectList()等方法。
此时并不需要编写Mapper接口,但仍然需要编写Mapper配置文件PersonMapper.xml。
此方法虽然可以减少一些Java代码编写工作,但是缺点是降低了项目的代码的结构化程度,可能造成可维护性降低。
(2)使用Mapper接口的方法。
此时不仅需要编写Mapper配置文件PersonMapper.xml,而且需要编写Mapper接口PersonMapper.java。另外,对于Mapper配置文件的要求也提高了,namespace的名称需要指定为Mapper接口的全限定名(包含包名和接口名)。MyBatis会自动将Mapper接口映射到一个同名的namespace所在Mapper配置上,而该Mapper配置的SQL语句的id会映射到Mapper接口的同名方法上。
优点是项目的结构化程度提高了,有利于代码的维护工作。
获取该优点的代价是Mapper配置文件需要额外的遵循以下的约定规则:
(a)规则1:mapper的namespace的值必须为对应的Mapper接口PersonMapper的全限定名。
(b)规则2: SQL语句的id的值必须为对应的Mapper接口PersonMapper的同名方法。
/** * @Title: PersonMapper.java * @Package com.test.mybatis3.mapper * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:00:52 * @version V1.0 */ package com.test.mybatis3.mapper; import java.util.List; import com.test.mybatis3.pojo.Person; /** * @ClassName: PersonMapper Mapper接口 * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:00:52 * */ public interface PersonMapper { /** * 查询所有记录。 * 对应于PersonMapper.xml文件中的id为findAllPersons的select语句。 * @return * @throws Exception */ List<Person> findAllPersons() throws Exception; }
1.2.4. 编写业务接口
/** * @Title: PersonService.java * @Package com.test.mybatis3.service * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:03:07 * @version V1.0 */ package com.test.mybatis3.service; import java.util.List; import com.test.mybatis3.pojo.Person; /** * @ClassName: PersonService 业务接口 * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:03:07 * */ public interface PersonService { /** * 查询所有记录。 * @return * @throws Exception */ List<Person> findAllPersons() throws Exception; }
1.2.5. 编写业务实现类
/** * @Title: PersonServiceImpl.java * @Package com.test.mybatis3.service.impl * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:03:57 * @version V1.0 */ package com.test.mybatis3.service.impl; import java.util.List; import com.test.mybatis3.mapper.PersonMapper; import com.test.mybatis3.pojo.Person; import com.test.mybatis3.service.PersonService; /** * @ClassName: PersonServiceImpl 业务实现类。 * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:03:57 * */ public class PersonServiceImpl implements PersonService { public PersonServiceImpl(){ } public PersonServiceImpl(PersonMapper personMapper) { super(); this.personMapper = personMapper; } private PersonMapper personMapper; public PersonMapper getPersonMapper() { return personMapper; } public void setPersonMapper(PersonMapper personMapper) { this.personMapper = personMapper; } /* * 查询所有记录。转发到了Mapper接口PersonMapper的findAllPersons()方法。 * @see com.test.mybatis3.service.PersonService#findAllPersons() */ @Override public List<Person> findAllPersons() throws Exception { return this.personMapper.findAllPersons(); } }
1.2.6. 编写Mapper配置文件
在使用Mapper方式时,必须严格按照MyBatis约定规则来编写Mapper配置文件。
<?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"> <!-- 规则1:mapper的namespace的值必须为对应的Mapper接口PersonMapper的全限定名。 --> <mapper namespace="com.test.mybatis3.mapper.PersonMapper"> <!-- 规则2: SQL语句的id的值必须为对应的Mapper接口PersonMapper的同名方法。 即:findAllPersons必须为PersonMapper接口的对应方法的名称。 --> <select id="findAllPersons" resultType="com.test.mybatis3.pojo.Person"> select * from t_person order by id asc </select> </mapper>
1.2.7. 编写总体配置文件
<?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="development"> <!-- -配置MyBatis运行环境中的各项参数 --> <environment id="development"> <!-- 配置事务管理器 ,存在JDBC和MANAGED两种类型,目前使用JDBC即可。--> <transactionManager type="JDBC"/> <!-- 配置数据源,存在三种类型:UNPOOLED,POOLED,JNDI,目前使用POOLED即可。 --> <dataSource type="POOLED"> <!-- 配置JDBC数据源的必备参数 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="test"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- 配置项目中将会使用的Mapper配置文件 --> <mappers> <!-- 配置PersonMapper的配置文件。 --> <mapper resource="mapper/PersonMapper.xml"/> </mappers> </configuration>
1.2.8. 编写log4j的配置文件
在开发过程中,为了观察到MyBatis比较详细的运行信息,尤其是SQL语句相关信息,需要编写log4j.properties文件对log4j进行配置,将日志输出级别设置为DEBUG级别,可以观察到MyBatis执行的SQL语句,可以用于排除一些相关的bug。
log4j.rootLogger=DEBUG,CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n log4j.logger.com.genuitec.eclipse.sqlexplorer=WARN log4j.logger.org.apache=WARN log4j.logger.NET.sf.hibernate=WARN
1.2.9. 编写单元测试
本文将使用JUNIT单元测试的方式来对MyBatis的各项功能进行说明。
/** * @Title: PersonServiceTest.java * @Package com.test.mybatis3.test * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:07:06 * @version V1.0 */ package com.test.mybatis3.test; import java.io.InputStream; import java.util.List; 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 org.junit.Test; import com.test.mybatis3.mapper.PersonMapper; import com.test.mybatis3.pojo.Person; import com.test.mybatis3.service.PersonService; import com.test.mybatis3.service.impl.PersonServiceImpl; /** * @ClassName: PersonServiceTest * @Description: * @author http://www.cnblogs.com/coe2coe/ * @date 2017年4月9日 下午4:07:06 * */ public class PersonServiceTest { /** * 直接使用SqlSession的selectList()方法来查询数据。 * @throws Exception */ @Test public void testFindAllPersonsBySession() throws Exception { System.out.println("by Session"); //使用SqlMapConfig.xml配置文件。 InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); //构造MyBatis的SessionFactory对象. SqlSessionFactory sessionBuilder = new SqlSessionFactoryBuilder().build(is); //将会指向MyBatis的Session对象实例。 SqlSession session = null; try{ //打开Session。 session = sessionBuilder.openSession(); //直接调用SqlSession的selectList()方法查询结果集。 //selectList()方法的参数是一个语句的标识符。 //该标识符由两部分组成:A.B //A:一个namespace的名称。最好是类似于Java包名的唯一的字符串。 //本例子中为com.test.mybatis3.mapper.PersonMapper。 //B:该namespace下的一个namespace范围内的唯一标识字符串。 //本例子中为findAllPersons。 List<Person> persons = session.selectList("com.test.mybatis3.mapper.PersonMapper.findAllPersons"); //输出查询结果。 for(Person person : persons){ System.out.println(person); } } catch(Exception ex){ ex.printStackTrace(); throw ex; } finally{ //确保关闭session对象。 if(null != session){ session.close(); session = null; } } } /** * 使用Mapper接口PersonMapper的方法来查询数据。 * @throws Exception */ @Test public void testFindAllPersonsByMapper() throws Exception { System.out.println("by Mapper"); //使用SqlMapConfig.xml配置文件。 InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); //构造MyBatis的SessionFactory对象. SqlSessionFactory sessionBuilder = new SqlSessionFactoryBuilder().build(is); //将会指向MyBatis的Session对象实例。 SqlSession session = null; try{ //打开Session。 session = sessionBuilder.openSession(); //找到MyBatis自动实现的PersonMapper接口的代理对象。 PersonMapper personMapper = session.getMapper(PersonMapper.class); //创建PersonService接口的实现对象。 PersonService personService = new PersonServiceImpl(personMapper); //调用PersonService接口的findAllPersons()方法, //内部会执行PersonMapper的findAllPersons()方法。 List<Person> persons = personService.findAllPersons(); //输出查询结果。 for(Person person : persons){ System.out.println(person); } } catch(Exception ex){ ex.printStackTrace(); throw ex; } finally{ //确保关闭session对象。 if(null != session){ session.close(); session = null; } } } }
运行结果:
(1)直接使用SqlSession的selectList()方法来查询数据的运行结果:
by Session
0 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Preparing: select * from t_person order by id asc
66 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Parameters:
98 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Total: 2
Person [id=lisi, name=li si, status=0]
Person [id=zhangsan, name=zhang san, status=0]
(2)使用Mapper接口PersonMapper的方法的运行结果:
by Mapper
0 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Preparing: select * from t_person order by id asc
48 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - ==> Parameters:
79 [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findAllPersons - <== Total: 2
Person [id=lisi, name=li si, status=0]
Person [id=zhangsan, name=zhang san, status=0]
至此,使用MyBatis开发数据库应用的开发步骤介绍完毕。
MyBatis应用开发(2)应用之开发方式XML文件篇