一.MyBatis简介
一说起对象关系映射框架,大家第一时间想到的肯定是Hibernate。Hibernate作为一个著名的框架,功能十分强大。我们只需要配置好实体类和数据表之间的关系,Hibernate就会自动帮我们完成生成并执行SQL语句,映射结果集这样的工作。但是也正是由于Hibernate如此强大的功能,导致了它的缺点:一是非常笨重,启动Hibernate的SessionFactory非常耗时,开销巨大;二是配置复杂,学习成本较高,系统调优也不容易;三是自定义查询功能较弱,查询结果如果不是映射的实体类,查询起来就比较麻烦。因此另一个ORM框架MyBatis,越来越流行。
前面说到的几个Hibernate的缺点,反过来正好就是MyBatis的优点:一是非常轻量,系统开销小;二是配置简单,易于学习,官方文档我直觉上感觉比Log4j2的文档还少;三正好就是MyBatis的特点,映射查询结果非常灵活。另外MyBatis还有一个优点就是自带中文文档,可能有些地方感觉不太通顺,但是完全足够我们学习和使用了。
二.配置环境
1.依赖引入
添加MyBatis最简单的办法就是使用Maven或Gradle这样的构建工具。在这里我使用Gradle。在项目中添加如下几行即可。如果确定不使用新的Java 8 时间API,那么第二行的依赖还可以去掉。这里我用的数据库是MySQL,因此还需要添加MySQL的JDBC驱动。
1
2
3
|
compile group: 'org.mybatis' , name: 'mybatis' , version: '3.4.2' compile group: 'org.mybatis' , name: 'mybatis-typehandlers-jsr310' , version: '1.0.2' compile group: 'mysql' , name: 'mysql-connector-java' , version: '5.1.40' |
2.配置文件
然后我们需要编写MyBatis的配置和映射文件。所有这些配置文件最好放在类路径上,对于Gradle项目来说就是src/main/resources文件夹下。我们先来编写一个配置文件。配置文件每个部分的详细作用请参见官方文档,这里只简单说明一下。
属性部分。在这里定义MyBatis需要的属性,可以用在下面的多个地方。另外属性也可以从外部properties文件中导入。
系统设置。在这里指定MyBatis的全局配置。详细的配置参加文档。
简写名。在映射文件中需要指定Java实体类的全名,我们可以在这里指定简写名简化配置。
环境。在这里我们要指定数据库连接、事务管理器等配置。还可以指定测试环境、生产环境等多个环境对应不同的数据库配置。
映射文件。在这里指定映射文件,或者也可以添加使用注解配置的类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?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> <property name= "driver" value= "com.mysql.jdbc.Driver" /> <property name= "url" value= "jdbc:mysql://localhost:3306/test" /> <property name= "username" value= "root" /> <property name= "password" value= "12345678" /> <property name= "driver.useSSL" value= "false" /> </properties> <!--系统设置--> <settings> <setting name= "cacheEnabled" value= "true" /> <setting name= "lazyLoadingEnabled" value= "true" /> </settings> <!--指定简写名--> <typeAliases> < package name= "yitian.study.entity" /> </typeAliases> <!--配置环境,可以配置多个环境用于测试、调试和生产--> <environments default = "development" > <environment id= "development" > <transactionManager type= "JDBC" /> <dataSource type= "POOLED" > <property name= "driver" value= "${driver}" /> <property name= "url" value= "${url}" /> <property name= "username" value= "${username}" /> <property name= "password" value= "${password}" /> </dataSource> </environment> </environments> <!--配置映射文件--> <mappers> <mapper resource= "BaseEntityMapper.xml" /> </mappers> </configuration> |
3.创建SqlSessionFactory
有了配置文件,我们就可以开始使用MyBatis了。首先要做的事情是创建MyBatis的SqlSessionFactory,它和Hibernate的SessionFactory类似,是主要的工厂类,一个应用程序中只需要创建一个即可。
下面是一个工具类,用双检锁简单的实现了一个线程安全的工具类。核心代码在最内层的if判断中。由于配置文件在类路径上,所以我们只需要指定文件名即可。这里用到了MyBatis提供的Resources工具类,创建一个输入流,然后交给SqlSessionFactoryBuilder来创建一个SqlSessionFactory。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public abstract class MyBatisUtils { private static volatile SqlSessionFactory sqlSessionFactory; public static final String MyBatisConfigLocation = "configuration.xml" ; public static SqlSessionFactory getSqlSessionFactory() throws IOException { if (sqlSessionFactory == null ) { synchronized (MyBatisUtils. class ) { if (sqlSessionFactory == null ) { InputStream input = Resources.getResourceAsStream(MyBatisConfigLocation); sqlSessionFactory = new SqlSessionFactoryBuilder().build(input); input.close(); } } } return sqlSessionFactory; } } |
创建好SqlSessionFactory之后,我们就可以开始使用MyBatis了。这里先回过头看看如何创建MyBatis映射文件。然后我们在继续使用MyBatis。
三.单表映射
1.数据表和实体类
在配置文件最后的mapper部分定义的就是映射文件。映射文件也是我们需要重点学习的地方。在映射文件中我们需要定义各种SQL语句,并建立它们和Java实体类之间的关系。这里我们使用最简单的单表映射:数据表和实体类之间属性名相同,一一对应。
首先先来添加一个实体类。
1
2
3
4
5
|
public class Person { private int id; private String username; private LocalDate birthday; } |
对应的数据库表如下。
1
2
3
4
5
|
CREATE TABLE person ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR( 255 ) NOT NULL UNIQUE, birthday DATE ); |
2.映射文件
然后我们来编写映射文件。映射文件包含5条SQL语句,分别是增删查改以及按名称查找。每一条语句都需要一个标识符,将会在后面再代码中用到。如果是查询语句还需要resultType,指定返回类型。MyBatis会将数据表列明和这里指定的类型属性按名称自动映射起来。如果需要在语句中传入参数,可以使用 parameterType属性,指定Java实体类的全名或简写,然后就可以在SQL语句中使用#{}来访问参数的属性了。如果是简单的映射,那么parameterType属性还可以省略,MyBatis会自动从传入的Java对象中获取相应的属性。对于某些数据库(例如MySQL),还可以在插入的时候指定useGeneratedKeys="true",让数据库自动生成主键。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?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= "yitian.study.dao.mapper" > <select id= "selectPerson" resultType= "Person" parameterType= "Person" > SELECT * FROM Person WHERE id = #{id} </select> <select id= "selectPersonByName" resultType= "Person" > SELECT * FROM Person WHERE username = #{username} </select> <insert id= "insertPerson" useGeneratedKeys= "true" > INSERT INTO Person (username, birthday) VALUES (#{username}, #{birthday}) </insert> <update id= "updatePerson" > UPDATE Person SET birthday = #{birthday} WHERE id = #{id} </update> <delete id= "deletePerson" > DELETE FROM Person WHERE id = #{id} </delete> </mapper> |
四.使用MyBatis
以上这些都配置好之后,我们就可以来使用MyBatis了。这里我们使用一个单元测试来查看MyBatis的功能。在创建SQLSessionFactory之后,我们需要获取MyBatis最核心的对象SqlSession,所有操作都需要SqlSession来进行。另外它是非线程安全的对象,不能放在类的静态字段上,最好也不要作为实例字段。我们要在需要的时候创建它,不用的时候及时释放。
常用的方法有增删查改这几个方法。这些方法的第一个参数是前面我们在映射文件中定义的语句ID,第二个参数是要传入的参数。对于查询来说有selectOne和selectList方法,它们的区别主要在于返回个数,如果确定只返回一个对象就使用selectOne方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import static org.assertj.core.api.Assertions.*; public class MyBatisTest { private static SqlSessionFactory sqlSessionFactory; private SqlSession sqlSession; @BeforeClass public static void init() throws IOException { sqlSessionFactory = MyBatisUtils.getSqlSessionFactory(); } @Before public void before() { sqlSession = sqlSessionFactory.openSession( true ); //自动提交 } @After public void after() { sqlSession.close(); } @Test public void testMyBatisUtils() { assertThat(sqlSessionFactory).isNotNull(); } @Test public void testInsert() { Person p = new Person( 0 , "yitian" , LocalDate.of( 1993 , 5 , 6 )); sqlSession.insert( "insertPerson" , p); Person s = sqlSession.selectOne( "selectPersonByName" , p.getUsername()); assertThat(s).isNotNull(); System.out.println(s); sqlSession.delete( "deletePerson" , s); } @Test public void testUpdate() { Person p = new Person( 1 , "leo" , LocalDate.of( 1993 , 5 , 6 )); sqlSession.insert( "insertPerson" , p); p = sqlSession.selectOne( "selectPersonByName" , p.getUsername()); LocalDate b = LocalDate.of( 1987 , 7 , 8 ); p.setBirthday(b); sqlSession.update( "updatePerson" , p); Person s = sqlSession.selectOne( "selectPersonByName" , p.getUsername()); assertThat(s.getBirthday()).isEqualTo(b); System.out.println(s); sqlSession.delete( "deletePerson" , s); } } |
另外默认情况下MyBatis的事务管理是开启的,意味着我们必须显式使用commit()方法才能提交事务。这里在打开SqlSession的时候指定了自动提交,这样我们的所有更改都会立即反映到数据库中。
五.使用映射类
在前面的例子中,使用的都是字符串来指定要使用的查询。但是这样做非常不方便,字符串容易发生错误,而且无法获得IDE的智能补全。所以MyBatis提供了另一种方式来执行SQL语句,这就是使用映射类。
映射类其实就是一个简单的接口。该接口中的方法和映射文件中定义的语句一一对应。接口方法的名称必须和语句id完全相同,接口方法的返回值和参数和相应的语句相对应。
1
2
3
4
5
6
7
|
public interface PersonMapper { Person selectPerson( int id); Person selectPersonByName(String name); void insertPerson(Person person); void updatePerson(Person person); void deletePerson(Person person); } |
仅仅增加映射类还不够,我们需要修改映射文件,以便让MyBatis能找到这个映射类。做法就是将映射文件的命名空间改为对应的映射文件的类名。
1
|
<mapper namespace= "yitian.study.mapper.PersonMapper" > |
映射类定义和配置好之后,我们就可以使用了。使用方法很简单,在SqlSession上调用getMapper方法,并传入要获取的Mapper类即可。
1
2
3
4
5
6
7
|
PersonMapper mapper = sqlSession.getMapper(PersonMapper. class ); Person p = new Person( 0 , "yitian" , LocalDate.of( 1993 , 5 , 6 )); mapper.insertPerson(p); Person s = mapper.selectPersonByName(p.getUsername()); assertThat(s).isNotNull(); System.out.println(s); mapper.deletePerson(p); |
有了映射对象,我们就可以以类型安全的方式来存取对象了,同时还可以获得IDE的补全功能。
以上所述是小编给大家介绍的MyBatis快速入门之环境搭建和单表映射,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/wangyayun/archive/2017/03/28/6631748.html