---恢复内容开始---
本篇文章对我的学习内容做一个归纳梳理,同时也记录一些学习过程中遇上的问题及注意事项等等。在编写时会引用一些mybatis开发手册中的内容。希望能帮上一些正在学习的朋友们。本篇中所采用的一些组件版本如下:mybatis—3.4.2、junit—4.12、mysql-connector—5.0.7。
ps:吐槽一下开发手册,一些地方写的有点不太清楚,中文版还有一股机翻的味道。。。如果觉得写的好就点个赞呗,如果觉得写的不好就提提建议吧!_(:з」∠)_
一、快速入门
二、xml配置文件
三、xml映射文件
要使用 MyBatis,只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:
1 <dependency> 2 <groupId>org.mybatis</groupId> 3 <artifactId>mybatis</artifactId> 4 <version>x.x.x</version> 5 </dependency
简单来说分为两步:①从配置文件中获取输入流。②使用sqlSessionFactoryBuilder.build()方法,将输入流传入,获取sqlSessionFactory。
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
配置文件:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <environments default="development"> 7 <environment id="development"> 8 <transactionManager type="JDBC"/> 9 <dataSource type="POOLED"> 10 <property name="driver" value="${driver}"/> 11 <property name="url" value="${url}"/> 12 <property name="username" value="${username}"/> 13 <property name="password" value="${password}"/> 14 </dataSource> 15 </environment> 16 </environments> 17 <mappers> 18 <mapper resource="org/mybatis/example/BlogMapper.xml"/> 19 </mappers> 20 </configuration>
1 SqlSession session = sqlSessionFactory.openSession();
映射文件,配置SQL语句
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="org.mybatis.example.BlogMapper"> 6 <select id="selectBlog" resultType="Blog"> 7 select * from Blog where id = #{id} 8 </select> 9 </mapper>
执行:采用 "namespace.id(语句)" 的方式进行调用。
1 Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
sqlSessionFactoryBuilder:一般不长久保持实例,构建完sessionFactory即可销毁。
sqlSessionFactory:一旦被创建就应该在运行期间一直存在,没有理由清除或重建。建议使用单例模式来对待它。
sqlSession:因为是线程不安全的,存在线程安全问题,不建议以静态的方式存在,建议在方法或请求结束后调用close()方法销毁。
1 <!--environments:环境集,内部可包含多个环境 2 default:环境的集默认环境,可以自定义 3 通常——developement:开发模式 、work:工作模式--> 4 <environments default="development"> 5 <!--environment:环境,id:指定环境对应的模式,可以自定义--> 6 <environment id="development">
关于default和id的对应关系:在开发手册中介绍的不够完善,而我在视频中学习时只是说,id与default必须一致,详细也没有多说。经过我的测试,default表示默认采用的环境属性,在环境集中必须有至少一个的该类型环境。也就是说在构建sessionFactory时,如果没有设定指定的环境参数,它就会按照default的参数去寻找一个环境来使用,所以必须得有一个同名的环境存在。而如果在环境集中有多个环境存在,在构建sessionFactory时如果不想使用默认环境,则应指定环境参数。
1 <!-- transactionManager:指定事务管理方式,type:事务管理模式,分为JDBC和MANAGED 2 JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。 3 MANAGED – 不进行事务管理交由容器来管理事务,如spring,j2ee服务器上下文。 默认情况下会关闭连接, 4 然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。 --> 5 <transactionManager type="MANAGED"> 6 <property name="closeConnection" value="false"/> 7 </transactionManager>
1 <!-- dataSource:数据源,配置关于数据库连接的信息 2 type:连接类型,分为三种 [UNPOOLED|POOLED|JNDI] --> 3 <dataSource type="POOLED"> 4 <property name="driver" value="com.mysql.jdbc.Driver" /> 5 <property name="url" value="jdbc:mysql://localhost:3306/mybatis" /> 6 <property name="username" value="root" /> 7 <property name="password" value="root" /> 8 </dataSource>
POOLED:"池"类型连接,减少了创建新的连接实例时所必需的初始化和认证时间。是一种使得并发 Web 应用快速响应请求的流行处理方式。
UNPOOLED:按照请求来打开和关闭连接,对于不使用连接池的情况下使用。由于频繁打开和关闭会导致性能效率较低,对性能要求不高时也可以使用。
JNDI: 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
1 <!-- mappers:mapper的集合,mapper标签都位于此标签下 --> 2 <mappers> 3 <!-- mapper:注册映射文件或映射类,也就是告诉mybatis去哪里找映射。有4种注册方式: --> 4 <!-- 1.使用工程内的路径结构指定映射文件 --> 5 <mapper resource="cn/edu/mybatis/test1/PeopleMapper.xml" /> 6 <!-- 2.使用全类名指定映射类 --> 7 <mapper class="cn.edu.mybatis.test1.PeopleMapper"/> 8 <!-- 3.指定mybatis的扫描基础包,将会自动包含该包下所有映射文件及映射文件 (该种方式在typeAliases时会再详细介绍) --> 9 <package name="cn.edu.mybatis.test1"/> 10 <!-- 4.采用统一资源定位符指定映射文件 (这种方式有点看不懂,测了几个也测不出来,所以用官方的样例,望有知道使用方式的朋友能告知一下!) --> 11 <mapper url="file:///var/mappers/BlogMapper.xml"/> 12 </mappers>
1 <!-- 定义一个properties,用于引用外部proerties,也可以使用标签下的<property>来构造一个properties 2 resource:引用文件路径 --> 3 <properties resource="db.properties"> 4 <!-- 注:当property与外部文件的属性重名时,结果为外部文件的值,不会产生覆盖 --> 5 <property name="password" value="124567"/> 6 </properties>
在声明好properties之后,可以采用 “${键}” 的方式来获取对应的值,提高配置的简洁及通用性。例:
1 <dataSource type="POOLED"> 2 <property name="driver" value="${driverClass}" /> 3 <property name="url" value="${jdbcUrl}" /> 4 <property name="username" value="${username}" /> 5 <property name="password" value="${password}" /> 6 </dataSource>
1 <typeAliases> 2 <!-- 为一个全类名声明一个别名,以后使用别名便等于使用全类名 3 注:即使声明了别名,全类名也可以使用,即两者可以混用,但一般不建议混用--> 4 <typeAlias type="cn.edu.mybatis.test1.People" alias="_People"/> 5 <!-- 将某个包内的全部类设定一个默认别名 --> 6 <package name="cn.edu.mybatis.test1"/> 7 </typeAliases>
关于typeAlias:可以使用@Alias注解来为一个类声明别名,减少配置文件的使用。如:
1 @Alias("people") 2 public class People {...}
关于package和@Alias:在有@Alias注解的情况下,注解中声明的别名优先。在开发手册中写的默认别名为首字母小写的类名,但经过测试,默认别名为类名的不区分大小写形式,如:cn.edu.mybatis.test1.People的默认别名可以为:people、People、pEopLe,但一般还是建议使用首字母小写的类名。
注:在下面的介绍中暂时不使用别名,而是继续使用全类名来保证严谨性。
其它的一些,如:设置(sesttings),对象工厂(objectFactory)等等,由于篇幅过长及不是很常用等一些问题,在这里不进行赘述,有兴趣的朋友可以自行去了解。
基础查询:
1 <!-- select:查询语句,具体sql语句写在标签内 2 parameterType:传入参数类型 3 resultType:传出参数类型 4 #{变量名}:表示占位符,替代传入的参数,只有一个传入参时可以不使用变量名作为占位符--> 5 <select id="findPeople" parameterType="int" resultType="cn.edu.mybatis.test1.People" > 6 select * from people where id = #{id} 7 </select>
增、删、改:将标签改为对应的insert、delete、update即可,传入传出参数同查询,sql语句也是自己自定义。
当传入参数为一个类的时候,语句的写法:
1 <update id="insert" parameterType="cn.edu.mybatis.test1.People"> 2 insert into people(name,age) values(#{name},#{age}) 3 </update>
此时占位符将会与类的属性进行一一对应,因此必须使用与属性同名的占位符。
注:可以在sql语句中使用${xxx}插入一个动态的字符串实现动态sql,但这种方式会导致sql注入风险,不建议使用。mybatis有提供更好的动态sql方式,在后面会介绍。
1 public void select() { 2 /* 调用方法1: */ 3 People people = session.selectOne("cn.edu.mybatis.test1.PeopleMapper.findPeople", 1); 4 System.out.println(people); 5 /* 调用方法2: */ 6 PeopleMapper mapper = session.getMapper(PeopleMapper.class); 7 people = mapper.findPeople(1); 8 System.out.println(people); 9 /* 调用方法3: */ 10 people = mapper.findPeopleById(1); 11 System.out.println(people); 12 }
第一种方式为调用session的方法的方式,传入 "命名空间.语句id"及参数,进行调用。增删改同理。
第二种方式声明了一个接口,在接口内声明了一个与映射文件中某个标签的id相同,传入传出参数也相同的方法。然后通过session.getMapper()方法获取该接口的实现,再使用接口进行调用方法。这种方法更加的贴近面向对象的操作方式,同时使用了接口进行了一定程度的隔离,也免除了过长的字符串编写带来的一些隐患。是推荐的一种调用方式。
1 public interface PeopleMapper { 2 People findPeople(int id); 3 }
第三种方式看起来和第二种方式区别不大,属于一个小小的变种。它采用了注解的配置方式,直接将sql语句写在注解内,减少了配置文件的出现。建议在编写一些功能逻辑简单的sql语句时使用这种方式,可以极大的减轻配置文件带来的负担。同样,对应的也有@Insert、@Update、@Delete。
1 @Select("select * from people where id = #{id}") 2 People findPeopleById(int id);
注:在只使用注解的情况下需要在配置文件的mapper中进行注册该映射类,如果之前注册过同名的映射文件的话,则不用注册。
多条结果的情况,只需声明结果集内的类型即可,mybatis会自动封装。
1 <select id="findAllPeople" resultType="cn.edu.test.People" > 2 select * from people 3 </select>
当数据库的字段与实体的属性名不同时,会导致属性无法获取的情况发生。如,在数据类型相同,但表为PEOPLE(p_id,p_name,p_age)的情况下,再使用前面用到的查询语句,将会返回null,这是由于反射机制导致的。解决方法有两种:第一种,在sql语句中使用as,就可以将查询结果改名成与属性名相同,这种方式比较繁琐笨重。第二种,mybatis提供的更好的解决方式,resultMap。
1 <resultMap type="cn.edu.mybatis.test1.People" id="peopleMap"> 2 <!-- column:数据库字段名 property:对应属性名--> 3 <id column="p_id" property="id"/> 4 <result column="p_name" property="name"/> 5 <result column="p_age" property="age"/> 6 </resultMap>
查询语句中将resultType改为resultMap:
1 <select id="findAllPeople" resultMap="peopleMap" > 2 select * from people 3 </select>
使用这种方式便可以解决冲突的问题。一些更加复杂的映射就不进行赘述了,需要的朋友可以自行查询。顺便一提,通常数据库列使用大写单词命名,单词间用下划线分隔;而java属性一般遵循驼峰命名法。在配置文件中的setting标签中,有一个mapUnderscoreToCamelCase属性,将其设置为true可以使这两种命名方式进行自动映射转换。
原文:http://www.cnblogs.com/qbzf-Blog/p/6347923.html