MyBATIS(即iBATIS)入门实例讲解
至从“关系数据库之父”Edgar F Codd提出《A Relational Model of Data for Large Shared Data Banks》(大型共享数据库数据的关系模型)标志着关系型数据库理论基础的诞生;再到1978年Oracle公司(原来叫)发布世界上第一个关系型数据库,标志着数据库已经可以运用到实际用途中。三十多年来,关系型数据库在各行各业的应用,都得到了蓬勃发展。即使最近今年,NoSQL技术发胀的如火如荼。但是,在银行、证券等行业,关系型数据库在数据存储中的地位短时间内依然是无可替代!
1975年推出的Smalltalk语言,是第一个完整实现的面向对象语言,向人们展示了“面向对象编程思想”的强大!并且,随着1995年Java技术的推出,以及以后Java在各个领域的大规模成功应用,另外微软推出的C#,PHP对面向对象支持力度的提高,更是把“面向对象编程思想”推向了高潮!
程序离开了数据,就一无是处、百无一用!数据离开了程序,就等于宣布了数据的死期!但是,关系型数据库是“面向集合”的;Java编程是“面向对象”的。这就存在一个“映射不对称性”。为了解决这个问题,我们的前辈提出来“O/R Mapping”技术,而MyBATIS、Hibernate是这里的两个比较优秀的开源解决方案!今天,我们就用实例来讲解一下MyBATIS。
有点背景需要说明一下,由于计划分享一个SpringMVC+Spring+MyBATIS整合的说明文章。所以,将这个入门当成“整合”文章的第一部分。另外,这里的业务场景是:基于数据库,完成对用户的增删改查。
先在MyEclipse中建一个”Web Project”,名字就叫”SSM”(这个可以随意取,我是为了搭建一个空工程,方便以后使用)。然后,在工程中,新建两个"Source Folder",分别命名为cfg(Configuration,存放配置文件)、test(存放测试用例);在WEB-INF/lib下,新建两个目录,MySQL和MyBATIS,然后把MySQL,和MyBATIS的Jar包分别拷贝到这个目录中。选中两个Jar把,”Add Build Path”一下。如下图:
另外,测试的时候需要使用JUnit。所以,将MyEclipse自带的JUnit v4的类库添加到“Build Path”中。
由于MyBATIS是一个O/R Mapping框架。我们首先需要建立起来Java中的对象和数据库中的表。具体代码如下:
用户User模型代码如下:
package com.diguage.ssm.domain; import java.util.Date; /** * @author D瓜哥,http://www.diguage.com/ * */ public class User { private Integer id; private String name; private Date birthday; private String sex; private String password; private String email; //Getter方法和Setter方法省略,自己补全。 }
请注意这个类中package名。为了方便统一管理,将所有的包都放在com.diguage.ssm下,在这个包的下面另外建立domain(存放领域模型)、dao(存放数据访问)。
user表建表语句如下(另外,请在MySQL中,新建ssm数据库,然后在这里数据库中新建下表):
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30), `password` char(50), `sex` char(2), `birthday` date, `email` varchar(50), PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
有了这两个基础,我们就可以写User类的映射文件了。映射文件的书写可以参考《MyBATIS User Guide》(“参考资料”中给出了中/英文版的下载链接),这里就直接给出配置文件(注意,这个文件放在和User类同一个包里。)里:
<?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.diguage.ssm.domain.UserMapper"> <select id="query" parameterType="int" resultType="User"> SELECT * FROM user WHERE id = #{id} </select> <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id" flushCache="true"> INSERT INTO user (name, password, sex, birthday, email) VALUES (#{name}, #{password}, #{sex}, #{birthday}, #{email}) </insert> <update id="update" parameterType="User"> UPDATE user SET name = #{name}, password = #{password}, sex = #{sex}, birthday = #{birthday}, email = #{email} WHERE id = #{id} </update> <delete id="delete" parameterType="int"> DELETE FROM user WHERE id = #{id} </delete> </mapper>
在我看来,这个映射文件就是建立在数据库表和Java对象之间的一个虚“拟机”,屏蔽两者之间的差异,时使其可以协同工作。这里需要注意的是namespace属性。在一个稍微大型一点的系统,命名冲突是一个很头疼的问题。Java通过package来区分,这里使用这个namespace属性来区分。
到这里,我们就能开始“配置”MyBATIS了。MyBATIS的映射文件和Hibernate的映射文件类似;而MyBATIS的配置文件和Hibernate的hibernate.cfg.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" /> <typeAliases> <typeAlias alias="User" type="com.diguage.ssm.domain.User" /> </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="com/diguage/ssm/domain/UserMapper.xml" /> </mappers> </configuration>
注意这个配置文件(存放到上面新建的cfg文件夹下)中的typeAlias标签。从上面的User类的代码中,可以看出User类的权限定名是:com.diguage.ssm.domain.User。但是,我们在映射文件UserMapper.xml中写的都是User。正是因为我在这里使用这个typeAlias,给User类起了个别名,才可以在映射文件中简写成User。另外,注意这里的mapper标签,使用resource属性说明一下映射文件的位置。
也许细心的配置已经注意到了,这里别没有写JDBC链接数据库的一些必要信息。但是有“properties”这个标签。我个人认为,把数据库链接信息提取出来单独放到一个文件中比较好。所以,这里还有一个property文件(存放在上面新建的cfg文件夹下,同时根据自己的实际情况修改MySQL的链接信息),用于存放数据库链接信息。内容如下:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8 username=ssm password=adai
这里说明一下,URL中需要带上useUnicode=true&characterEncoding=UTF-8,否则可能会出现乱码我问题
到这里,我们还没写过几段代码,下面我们就正在开始,在上面新建的test文件下,新建MyBATISTest.java,代码如下:
package com.diguage.ssm.dao; import java.io.IOException; import java.io.InputStream; import java.util.Date; 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.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.diguage.ssm.domain.User; public class MyBATISTest { private static SqlSessionFactory sessionFactory = null; private SqlSession session = null; @BeforeClass public static void init() throws IOException { //由于这个配置文件的读取和SqlSessionFactory的建立,只需要做一次。所以,建立在@BeforeClass"修饰"的方法中 String resource = "MyBATISConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Before public void operSession() { //每次调用方法之前,都需要新建一个Session。所以,在@Before修饰的方法中 session = sessionFactory.openSession(true); } @After public void closeSession() { session.close(); } @Test public void save() { User user = new User(); user.setBirthday(new Date()); user.setName("D瓜哥"); user.setEmail("123@abc.com"); user.setPassword("MyPass"); user.setSex("男"); session.insert("com.diguage.ssm.domain.UserMapper.save", user); System.out.println("新生成的主键是:" + user.getId()); } @Test public void delete() { session.delete("com.diguage.ssm.domain.UserMapper.delete", 4); } @Test public void update() { User u = session.selectOne("com.diguage.ssm.domain.UserMapper.query", 3); System.out.println(u.getPassword()); u.setPassword("diguage.com"); session.update("com.diguage.ssm.domain.UserMapper.update", u); } @Test public void query() { User u = session.selectOne("com.diguage.ssm.domain.UserMapper.query", 3); System.out.println(u.getName()); System.out.println(u.getEmail()); } }
这里,我想说明一点,在运行save方法时,可以看出,已经新生成了“主键”id。所以,这里也就回答了“MyBATIS(即iBATIS)问题集”中的第九个问题。
这个文章写的有点“仓促”。很多地方没有说明白,以后再慢慢说明。另外,也可以看“MyBATIS User Guide”。里面说明了很多问题。(只是例子写的有点零散。不过,有我的这个例子,可以相互参考着学习。希望对各位感兴趣的朋友有帮助。
想用微博分享,但是不知道为啥不行。需要的话,给我私信吧。抱歉!
参考资料:
- A Relational Model of Data for Large Shared Data Banks
- MyBATIS官网
- 维基百科中关于Smalltalk的介绍
- 中文版MyBATIS User Guide下载链接
- 英文版MyBATIS User Guide下载链接
原文链接:https://wordpress.diguage.com/archives/62.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。