Mybatis框架学习笔记

来源:互联网 发布:找车拉货用什么软件 编辑:程序博客网 时间:2024/05/03 15:14
mybatis是个很好用的持久化框架,不然你不会看这篇文章的对不对。

ibatis已经退休了,所以我们直接用mybatis


官方jar包下载 https://github.com/mybatis/mybatis-3/releases
笔者使用的版本是:mybatis-3.2.7.jar
包里面还有一个pdf介绍怎么使用mybatis,可以去参考一下

当然,使用mybatis是要操作数据库的,这里以mysql数据库为例。
这里提供一下GPL的版本下载地址:http://dev.mysql.com/downloads/windows/installer/

笔者创建了一个数据库叫mybatis,并创建了表test,表内容如下:


1.创建mybatis-config.xml
首先我们先创建mybatis的xml文件mybatis-config.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="com/rich/util/jdbc.properties" /> <!-- 要放在Configuration标签下的最前面,不然报错 --> <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/rich/util/TestMapper.xml"/> </mappers> </configuration>

再创建一个配置文件jdbc.properties来存放键值对,代码如下:
driver = com.mysql.jdbc.Driverurl = jdbc:mysql://localhost:3306/mybatisusername = rootpassword = root

当然你也可以不创建上面的配置文件,直接在mybatis-config.xml的dataSource标签下替换掉相应的property value就行了。
mybatis-config.xml文件中的标签用法

MyBatis配置文件中大标签configuration下子标签包括:

configuration —— 根元素 

  • properties —— 定义配置外在化
  • settings —— 一些全局性的配置
  • typeAliases —— 为一些类定义别名
  • typeHandlers —— 定义类型处理,也就是定义java类型与数据库中的数据类型之间的转换关系
  • objectFactory —— 用于指定结果集对象的实例是如何创建的
  • plugins —— Mybatis的插件,插件可以修改Mybatis内部的运行规则
  • environments —— 配置Mybatis的环境 
    • environment 
      • transactionManager —— 事务管理器
      • dataSource —— 数据源
  • databaseIdProvider
  • mappers —— 指定映射文件或映射类

这里不展开讲了,详细描述请参考:http://blog.csdn.net/scau_rich/article/details/38706137


2.创建TestMapper.xml
在mybatis-config.xml文件中,mapper标签指定的映射文件TestMapper.xml是用来定义SQL映射语句的,代码如下:

<?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.rich.mybatis.UserMapper"> <select id="getAll" resultType="com.rich.test.UserMapper"> select * from test </select> <select id="findById" parameterType="int" resultType="com.rich.test.UserMapper" > select * from test where id=#{id} </select> </mapper>

在这里笔者只写了两条sql的select语句,分别是获取表的所有内容和根据id查找相应的记录,其它如update,insert,delete等动作可以自行实现,原理相同。

这里注意一下,mapper标签中的namespace不能与select标签中resultType属性一样,不然会报错。



3.创建实体类User

package com.rich.po;public class User { private int id; private String name; private String description;  public User(int id) {  this.id = id; }  public int getId() {  return id; } public void setId(int id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public String getDescription() {  return description; } public void setDescription(String description) {  this.description = description; }}

4.创建Mapper接口:UserMapper
package com.rich.test;import java.util.List;import org.apache.ibatis.annotations.Select; import com.rich.po.User; public interface UserMapper {  @Select("select * from test") public List<User> getAll();  @Select("select * from test where id=#{id}") public User findById(int id);} 
这里要注意,UserMapper中的方法与TestMapper.xml中的文件映射的sql语句的id要一样。

5.创建MybatisTest类
下面是重头戏,对数据库进行访问,创建一个java文件MybatisTest,以下是代码:
package com.rich.test;import java.io.IOException;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 com.rich.po.User;public class MybatisTest {  public static void main(String[] args) {  //配置mybatis默认文件  String resource = "com/rich/util/mybatis-config.xml";  InputStream inputStream = null;  try {   //读入   inputStream = Resources.getResourceAsStream(resource);     } catch (IOException e) {   e.printStackTrace();  }  //创建SqlSessionFactory mybatis最重要的工厂类。build方法读入配置文件  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  //也可以在这里写入jdbc.properties的键值对  //SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, jdbc.properties);  //注册接口,不注册会时不时报Type interface com.souvi.ibatis.xxxMapper is not known to the MapperRegistry的错误  sqlSessionFactory.getConfiguration().addMapper(UserMapper.class);  //获得session  SqlSession session = sqlSessionFactory.openSession();   try {   //使用UerMapper接口,提倡使用   UserMapper userMapper = session.getMapper(UserMapper.class);   //调用getAll方法   List<User> users = userMapper.getAll();   for(User user : users) {    System.out.println(user.getId() + ":" + user.getName() + "-----------" + user.getDescription());   }  } finally {   session.close();  } // try{// 下面是不使用接口方式,直接把返回值写入到dao中,获取数据库数据// 需要在xml里面使用// List<User> users = session.selectList("com.rich.mybatis.UserMapper.getAll");// System.out.println(user.getId() +);// for(User user : users) {// System.out.println(user.getId() + ":" + user.getName() + "-----------" + user.getDescription());// }// } finally {// session.close();// } }}

看到数据, 成功。


补充知识:

这里具体讲述一下ResultMap,这个mybatis最重要的标签。

主要的用法是为了匹配数据库不一致的字段。上面的例子因为是精确匹配,所以不需要使用ResultMap,直接使用resultType返回到领悟对象即可。

<resultMap id="userResultMap" type="User">  <id property="id" column="user_id" />  <result property="username" column="username"/>  <result property="password" column="password"/></resultMap>
你可以看到我们使用了resultMap来代替resultType。注意resultMap和resultType不能同时出现
<select id="selectUsers" parameterType="int" resultMap="userResultMap">  select user_id, user_name, hashed_password  from some_table  where id = #{id}</select>

当然你也可以使用as来代替resultMap,但原理是一样的。

<select id="selectUsers" parameterType="int" resultType="User">  select    user_id             as "id",    user_name           as "userName",    hashed_password     as "hashedPassword"  from some_table  where id = #{id}</select>

resultMap可以除了映射单个表之外,当然可以关联多个表映射,映射有两种方式,一种是嵌套查询,另外一种嵌套结果。
嵌套查询:
<resultMap id="blogResult" type="Blog">  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/></resultMap> <select id="selectBlog" parameterType="int" resultMap="blogResult">  SELECT * FROM BLOG WHERE ID = #{id}</select> <select id="selectAuthor" parameterType="int" resultType="Author">  SELECT * FROM AUTHOR WHERE ID = #{id}</select>

你可以看到,当调用selectBlog这个select语句时,返回的resultMap会同时查询association中的select属性的值,并把返回的结果传入到author这个属性当中。


这里补充一下,association这个标签的意思是一个复合类型,跟JAVA中的对象的意思类似,可以把任意基本类型集包装成association类型,像:
<association property="author" javaType="Author">    <id property="id" column="author_id"/>    <result property="username" column="author_username"/>    <result property="password" column="author_password"/>    <result property="email" column="author_email"/>    <result property="bio" column="author_bio"/>    <result property="favouriteSection" column="author_favourite_section"/>  </association>

还有一种类型叫collection,与association很类似,用法几乎都一样,但是这里注意一下,association是用于1-1对应的,collection用于1-N对应的,简而言之,association是单一对象,collection是对象集合。
<collection property="posts" ofType="Post">    <id property="id" column="post_id"/>    <result property="subject" column="post_subject"/>    <association property="author" javaType="Author"/>    <collection property="comments" ofType="Comment">      <id property="id" column="comment_id"/> </collection>

嵌套结果:
<resultMap id="blogResult" type="Blog">  <id property="id" column="blog_id" />  <result property="title" column="blog_title"/>  <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/></resultMap> <resultMap id="authorResult" type="Author">  <id property="id" column="author_id"/>  <result property="username" column="author_username"/>  <result property="password" column="author_password"/>  <result property="email" column="author_email"/>  <result property="bio" column="author_bio"/></resultMap>

把author嵌入到blogResult中。查询的时候需要进行关联查询,然后返回结果集。查询sql语句是:
<select id="selectBlog" parameterType="int" resultMap="blogResult">  select    B.id            as blog_id,    B.title         as blog_title,    B.author_id     as blog_author_id,    A.id            as author_id,    A.username      as author_username,    A.password      as author_password,    A.email         as author_email,    A.bio           as author_bio  from Blog B left outer join Author A on B.author_id = A.id  where B.id = #{id}</select>

这里也提供集合的嵌套查询:
<select id="selectBlog" parameterType="int" resultMap="blogResult">  select  B.id as blog_id,  B.title as blog_title,  B.author_id as blog_author_id,  P.id as post_id,  P.subject as post_subject,  P.body as post_body,  from Blog B  left outer join Post P on B.id = P.blog_id  where B.id = #{id}</select>

返回的resultMap
<resultMap id="blogResult" type="Blog">  <id property="id" column="blog_id" />  <result property="title" column="blog_title"/>  <collection property="posts" ofType="Post">    <id property="id" column="post_id"/>    <result property="subject" column="post_subject"/>    <result property="body" column="post_body"/>  </collection></resultMap>

留个坑:<discriminator>的用法很好玩,有兴趣的自行查找,这里就不展开了

0 0
原创粉丝点击