Mybatis详解

基于MyBatis3.0.6的基本操作介绍

MyBatis SqlSessionFactory SqlSessionFactory本身是由SqlSessionFactoryBuilder创建的,一般而言,在一个应用中,一个数据库只会对应一个SqlSessionFactory,所以一般我们都把SqlSessionFactory定义成单例模式,或通过Spring等进行注入。

SqlSessionFactoryBuilder创建SqlSessionFactory的方法有:

 

Java代码  

1. SqlSessionFactory build(InputStream inputStream)  

2. SqlSessionFactory build(InputStream inputStream, String environment)  

3. SqlSessionFactory build(InputStream inputStream, Properties properties)  

4. SqlSessionFactory build(InputStream inputStream, String env, Properties props)  

5. SqlSessionFactory build(Configuration config)  

 

这些方法主要设计到的参数有InputStream,environment,properties,其中InputStream是从配置文件中获取的一个输入流;environment表示在配置文件里面配置的众多的environment中,当前要使用的是哪一个environment,包括数据源和事务,缺省则使用默认的environment;使用properties,MyBatis则会加载对应的属性或文件,它们可以在配置文件中使用。 

 

 

从XML中构建SqlSessionFactory

 

Java代码  

1. private static SqlSessionFactory sqlSessionFactory = null;  

2.       

3.     static {  

4.         try {  

5.             InputStream is = Resources.getResourceAsStream("config/mybatis_config.xml");  

6.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);  

7.         } catch (IOException e) {  

8.             // TODO Auto-generated catch block  

9.             e.printStackTrace();  

10.        }  

11.          

12.    }  

13.      

14.    public static SqlSessionFactory getSqlSessionFactory() {  

15.        return sqlSessionFactory;  

16.    }  

 

下面讲讲配置文件的基本结构:

mybatis的配置文件一般包括如下几个部分:

properties:properties用于定义或导入属性,然后在后面的环境中使用

settings:settings用于设置一些mybatis在运行时的行为方式,具体的设置信息可以查看mybatis的文档

typeAliases:typeAliases是为系统中的Java类型指定一个较短的别名

environments:MyBatis 可以配置多种环境。这会帮助你将 SQL映射应用于多种数据库之中。

 

Xml代码  

1. <environments default="development">  

2.         <environment id="development">  

3.             <transactionManager type="JDBC" />  

4.             <dataSource type="POOLED">  

5.                 <property name="driver" value="${jdbc.driver}" />  

6.                 <property name="url" value="${jdbc.url}" />  

7.                 <property name="username" value="${jdbc.username}" />  

8.                 <property name="password" value="${jdbc.password}" />  

9.             </dataSource>  

10.        </environment>  

11.    </environments>  

由于MyBatis可以配置多个environment,所以可以在创建SqlSessionFactory的时候指定具体的环境来创建特定的环境下的SqlSessionFactory,  不指定则使用默认的环境。

 

 

transactionManager

MyBatis中有两种事务管理器类型(也就是 type=”[JDBC|MANAGED]”):

·        JDBC –这个配置直接简单使用了 JDBC的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。

·        MANAGED –这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring JEE 应用服务器的上下文) 默认情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止, closeConnection属性设置为 false

dataSource

dataSource 元素使用基本的 JDBC数据源接口来配置 JDBC连接对象的资源。

·        许多 MyBatis的应用程序将会按示例中的例子来配置数据源。然而它并不是必须的。要知道为了方便使用延迟加载,数据源才是必须的。

有三种内建的数据源类型(也就是 type=”???”):

UNPOOLED –这个数据源的实现是每次被请求时简单打开和关闭连接。它有一点慢,这是对简单应用程序的一个很好的选择,因为它不需要及时的可用连接。不同的数据库对这个的表现也是不一样的,所以对某些数据库来说配置数据源并不重要,这个配置也是闲置的。 UNPOOLED类型的数据源仅仅用来配置以下 5种属性:

·        driver –这是 JDBC 驱动的 Java 类的完全限定名(如果你的驱动包含,它也不是数据源类)

·        url –这是数据库的 JDBC URL地址。

·        username –登录数据库的用户名。

·        password –登录数据库的密码。

·        defaultTransactionIsolationLevel –默认的连接事务隔离级别。

作为可选项,你可以传递数据库驱动的属性。要这样做,属性的前缀是以“driver.”头的,例如:

·        driver.encoding=UTF8

“ UTF8 ” “ encoding ”,DriverManager.getConnection(url,driverProperties)方法传递给数据库驱动。

POOLED –这是 JDBC 连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。这是一种当前 Web应用程序用来快速响应请求很流行的方法。

除了上述(UNPOOLED)的属性之外,还有很多属性可以用来配置 POOLED数据源:

·        poolMaximumActiveConnections –在任意时间存在的活动(也就是正在使用)接的数量。默认值:10

·        poolMaximumIdleConnections –任意时间存在的空闲连接数。

·        poolMaximumCheckoutTime –在被强制返回之前,池中连接被检查的时间。默认:20000毫秒(也就是 20)

·        poolTimeToWait –这是给连接池一个打印日志状态机会的低层次设置,还有重新尝试获得连接,这些情况下往往需要很长时间为了避免连接池没有配置时静默失)。默认值:20000毫秒(也就是 20)

·        poolPingQuery –发送到数据的侦测查询,用来验证连接是否正常工作,并且准备接受请求。默认是“NO PINGQUERY SET” ,这会引起许多数据库驱动连接由一个错误信息而导致失败。

·        poolPingEnabled –这是开启或禁用侦测查询。如果开启,你必须用一个合法的 SQL语句(最好是很快速的)设置 poolPingQuery属性。默认值:false

·        poolPingConnectionsNotUsedFor –这是用来配置 poolPingQuery多次时间被用一次。这可以被设置匹配标准的数据库连接超时时间,来避免不必要的侦测。默认值: 0(也就是所有连接每一时刻都被侦测-但仅仅当poolPingEnabled true 时适用)

JNDI –这个数据源的实现是为了使用如 Spring或应用服务器这类的容器,容器可以集中或在外部配置数据源,然后放置一个 JNDI上下文的引用。这个数据源配置只需要两个属:

·        initial_context – ( initialContext.lookup(initial——context)。这是个可选属性,如果被忽略,那么data_source属性将会直接以initialContext为背景再次寻找。

·        data_source –这是引用数据源实例位置的上下文的路径。它会以由initial_context查询返回的环境为背景来查找,如果 initial_context没有返回结果时,直接以初始上下文为环境来查找。

再之后就是Mapper了,Mapper就是映射SQL语句的,首先要告诉mybatis要到哪里去找这些SQL语句,即指定资源位置。

Java代码  

1. <mappers>  

2.         <mapper resource="com/tiantian/mybatis/model/BlogMapper.xml"/>  

3.     </mappers>   

 

下面是我在测试过程中的一个简单的配置文件:

Xml代码  

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.     <properties resource="config/jdbc.properties"></properties>  

7.     <typeAliases>  

8.         <typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/>  

9.     </typeAliases>  

10.    <environments default="development">  

11.        <environment id="development">  

12.            <transactionManager type="JDBC" />  

13.            <dataSource type="POOLED">  

14.                <property name="driver" value="${jdbc.driver}" />  

15.                <property name="url" value="${jdbc.url}" />  

16.                <property name="username" value="${jdbc.username}" />  

17.                <property name="password" value="${jdbc.password}" />  

18.            </dataSource>  

19.        </environment>  

20.    </environments>  

21.    <mappers>  

22.        <mapper resource="com/tiantian/mybatis/model/BlogMapper.xml"/>  

23.    </mappers>  

24.</configuration>  

 

在上面配置文件中导入了一个外部的属性文件,MyBatis配置文件中的属性引入可以是直接包含在properties元素中的,也可以是利用properties元素从外部引入的,还可以是在创建SqlSessionFactory的时候,作为一个参数properties传入。既然MyBatis配置文件中的属性可以从这么多地方引入,那就牵涉到一个优先级的问题,MyBatis将会按照下面的顺序来寻找它们:

·        先是配置文件中,properties元素体中的属性被读取

·        再是利用properties元素从外部引入的属性文件中的属性被读取,会覆盖前面读取的相同的属性

·        最后是创建SqlSessionFactory时传入的properties中的属性被读取,同样会覆盖前面相同的属性

 

在有了SqlSessionFactory之后就是获取特定的SqlSession了,在使用mybatis的过程中每一个操作都是离不开SqlSession的,所以获取SqlSession是相当重要的。此外,SqlSession是不能被共享、线程不安全的,所以在每次需要SqlSession的时候都应该打开一个,然后在用完了之后再把它关上。

Java代码  

1. SqlSession session = sqlSessionFactory.openSession();  

 

SqlSessionFactory中湖区SqlSession的方法有:

Java代码  

1. SqlSession openSession()  

2. SqlSession openSession(boolean autoCommit)  

3. SqlSession openSession(Connection connection)  

4. SqlSession openSession(TransactionIsolationLevel level)  

5. SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)  

6. SqlSession openSession(ExecutorType execType)  

7. SqlSession openSession(ExecutorType execType, boolean autoCommit)  

8. SqlSession openSession(ExecutorType execType, Connection connection)  

9. Configuration getConfiguration();  

它们的主要区别在于:

·        Transaction(事务):你想为 session使用事务或者使用自动提交

·        Connection(连接):你想 MyBatis 获得来自配置的数据源的连接还是提供你自己

·        Execution(执行):你想 MyBatis 复用预处理语句和/或批量更新语句(包括插入和删除)

 默认的opensession方法没有参数,它会创建有如下特性的SqlSession:

·        会开启一个事务,也就是不自动提交

·        连接对象会从当前正在使用的environment中的数据源中得到

·        事务隔离级别将会使用驱动或数据源的默认值

·        预处理语句不会被复用,也不会批量更新语句

ExecutorType有三个值:

·        ExecutorType.SIMPLE 它会为每个语句的执行创建一个新的预处理语句

·        ExecutorType.REUSE 它会复用预处理语句

·        ExecutorType.BATCH 这个执行器会批量执行更新语句

 

mybatis的基本操作就是增、删、改、查,即insert、delete、update和select。在进行这些基本的操作的时候可以直接利用SqlSession访问Mapper配置文件里面的映射来进行,也可以利用与Mapper配置文件相对应的Mapper接口来进行操作,条件是Mapper接口中定义的方法的参数和返回值要与Mapper配置文件中定义的参数和返回值相同。此外,在使用Mapper接口的时候,对应的SQL语句是可以写在Mapper配置文件中的,也可以直接利用对应的注解在Mapper接口中对应的方法上进行标明,这将在下面的示例代码中看到。

 

下面是一系列的示例代码:

先贴一个用于获取SqlSessionFactory的工具类:

Java代码  

1. import java.io.IOException;  

2. import java.io.InputStream;  

3.   

4. import org.apache.ibatis.io.Resources;  

5. import org.apache.ibatis.session.SqlSessionFactory;  

6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  

7.   

8. public class Util {  

9.       

10.    private static SqlSessionFactory sqlSessionFactory = null;  

11.      

12.    static {  

13.        try {  

14.            InputStream is = Resources.getResourceAsStream("config/mybatis_config.xml");  

15.            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);  

16.        } catch (IOException e) {  

17.            // TODO Auto-generated catch block  

18.            e.printStackTrace();  

19.        }  

20.          

21.    }  

22.      

23.    public static SqlSessionFactory getSqlSessionFactory() {  

24.        return sqlSessionFactory;  

25.    }  

26.      

27.}  

 

mybatis的配置文件:

Xml代码  

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.     <properties resource="config/jdbc.properties"></properties>  

7.     <typeAliases>  

8.         <typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/>  

9.     </typeAliases>  

10.    <environments default="development">  

11.        <environment id="development">  

12.            <transactionManager type="JDBC" />  

13.            <dataSource type="POOLED">  

14.                <property name="driver" value="${jdbc.driver}" />  

15.                <property name="url" value="${jdbc.url}" />  

16.                <property name="username" value="${jdbc.username}" />  

17.                <property name="password" value="${jdbc.password}" />  

18.            </dataSource>  

19.        </environment>  

20.    </environments>  

21.    <mappers>  

22.        <mapper resource="com/tiantian/mybatis/model/BlogMapper.xml"/>  

23.    </mappers>  

24.</configuration>  

 

BlogMapper.xml

Xml代码  

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.   

6. <mapper namespace="com.tiantian.mybatis.model.BlogMapper">  

7. <!--  新增记录  -->  

8.     <insert id="insertBlog" parameterType="Blog">  

9.         insert into t_blog(title,content,owner) values(#{title},#{content},#{owner})  

10.    </insert>  

11.<!--  查询单条记录 -->  

12.    <select id="selectBlog" parameterType="int" resultType="Blog">  

13.        select * from t_blog where id = #{id}  

14.    </select>  

15.<!--  修改记录   -->  

16.    <update id="updateBlog" parameterType="Blog">  

17.        update t_blog set title = #{title},content = #{content},owner = #{owner} where id = #{id}  

18.    </update>  

19.<!--  查询所有记录,查询多条记录即返回结果是一个集合的时候,resultType不是集合类型,而是集合所包含的类型 -->  

20.    <select id="selectAll" resultType="Blog">  

21.        select * from t_blog  

22.    </select>  

23.<!--  模糊查询   -->  

24.    <select id="fuzzyQuery" resultType="Blog" parameterType="java.lang.String">  

25.        select * from t_blog where title like "%"#{title}"%"  

26.    </select>  

27.<!--  删除记录   -->  

28.    <delete id="deleteBlog" parameterType="int">  

29.        delete from t_blog where id = #{id}  

30.    </delete>  

31.</mapper>  

SQL映射语句中一些应该注意的问题:

1.     resultType的值应该是返回类型的完全名或别名,当返回的结果是一个集合的时候,resultType应为集合中所包含的类型,而不是集合类型,如上面的Blog

2.    resultType和resultMap都是表示指定返回结果的,但两者不能同时使用

3.    对于Insert映射语句有一个useGeneratedKeys属性,该属性的默认值为false,当该属性的值为true时,在进行插入操作时,mybatis会取到当前正在插入的记录在数据库中的自动递增的主键值,并把它设置给指定的实体的属性,这就需要设置一个keyProperty属性,用于指定实体中表示主键的属性

 

 

Blog.java

Java代码  

1. package com.tiantian.mybatis.model;  

2.   

3. public class Blog {  

4.   

5.     private int id;  

6.   

7.     private String title;  

8.   

9.     private String content;  

10.  

11.    private String owner;  

12.  

13.    public int getId() {  

14.        return id;  

15.    }  

16.  

17.    public void setId(int id) {  

18.        this.id = id;  

19.    }  

20.  

21.    public String getTitle() {  

22.        return title;  

23.    }  

24.  

25.    public void setTitle(String title) {  

26.        this.title = title;  

27.    }  

28.  

29.    public String getContent() {  

30.        return content;  

31.    }  

32.  

33.    public void setContent(String content) {  

34.        this.content = content;  

35.    }  

36.  

37.    public String getOwner() {  

38.        return owner;  

39.    }  

40.  

41.    public void setOwner(String owner) {  

42.        this.owner = owner;  

43.    }  

44.  

45.    @Override  

46.    public String toString() {  

47.        return "id: " + id + ", title: " + title + ", content: " + content  

48.                + ", owner: " + owner;  

49.    }  

50.  

51.}  

 

BlogMapper.java

Java代码  

1. package com.tiantian.mybatis.model;  

2.   

3. import java.util.List;  

4.   

5. import org.apache.ibatis.annotations.Delete;  

6. import org.apache.ibatis.annotations.Insert;  

7. import org.apache.ibatis.annotations.Select;  

8. import org.apache.ibatis.annotations.Update;  

9.   

10./** 

11. * 以下的操作1都是把SQL写在配置文件里面的,而操作2都是直接用注解标明要执行的SQL语句 

12. * 因为该Mapper的全名跟BlogMapper.xml文件里面的namespace是一样的,所以不能在这里面 

13. * 用注解定义一个与BlogMapper.xml文件里面同名的映射 

14. * @author andy 

15. * 

16. */  

17.public interface BlogMapper {  

18.  

19.    public Blog selectBlog(int id);  

20.      

21.    @Select("select * from t_blog where id = #{id}")  

22.    public Blog selectBlog2(int id);  

23.      

24.    public void insertBlog(Blog blog);  

25.      

26.    @Insert("insert into t_blog(title,content,owner) values(#{title},#{content},#{owner})")  

27.    public void insertBlog2(Blog blog);  

28.      

29.    public void updateBlog(Blog blog);  

30.      

31.    @Update("update t_blog set title=#{title},content=#{content},owner=#{owner} where id=#{id}")  

32.    public void updateBlog2(Blog blog);  

33.      

34.    public void deleteBlog(int id);   

35.      

36.    @Delete("delete from t_blog where id = #{id}")  

37.    public void deleteBlog2(int id);  

38.      

39.    public List<Blog> selectAll();  

40.      

41.    @Select("select * from t_blog")  

42.    public List<Blog> selectAll2();  

43.      

44.    public List<Blog> fuzzyQuery(String title);  

45.      

46.    @Select("select * from t_blog where title like \"%\"#{title}\"%\"")  

47.    public List<Blog> fuzzyQuery2(String title);  

48.      

49.}  

 

Test1.java

Java代码  

1. package com.tiantian.mybatis.test;  

2.   

3. import java.util.List;  

4.   

5. import org.apache.ibatis.session.SqlSession;  

6. import org.junit.Test;  

7.   

8. import com.tiantian.mybatis.model.Blog;  

9. import com.tiantian.mybatis.util.Util;  

10.  

11./** 

12. * 该系列操作是通过把SQL写在配置文件里面, 

13. * 然后利用SqlSession进行操作的 

14. * @author andy 

15. * 

16. */  

17.public class Test1 {  

18.  

19.    /** 

20.     * 新增记录 

21.     */  

22.    @Test  

23.    public void testInsertBlog() {  

24.        SqlSession session = Util.getSqlSessionFactory().openSession();  

25.        Blog blog = new Blog();  

26.        blog.setTitle("中国人");  

27.        blog.setContent("五千年的风和雨啊藏了多少梦");  

28.        blog.setOwner("天天");  

29.        session.insert("com.tiantian.mybatis.model.BlogMapper.insertBlog", blog);  

30.        session.commit();  

31.        session.close();  

32.    }  

33.      

34.    /** 

35.     * 查询单条记录 

36.     */  

37.    @Test  

38.    public void testSelectOne() {  

39.        SqlSession session = Util.getSqlSessionFactory().openSession();  

40.        Blog blog = (Blog)session.selectOne("com.tiantian.mybatis.model.BlogMapper.selectBlog"8);  

41.        System.out.println(blog);  

42.        session.close();  

43.    }  

44.      

45.    /** 

46.     * 修改记录 

47.     */  

48.    @Test  

49.    public void testUpdateBlog() {  

50.        SqlSession session = Util.getSqlSessionFactory().openSession();  

51.        Blog blog = new Blog();  

52.        blog.setId(7);//需要修改的Blogid  

53.        blog.setTitle("中国人2");//修改Title  

54.        blog.setContent("黄色的脸,黑色的眼,不变是笑容");//修改Content  

55.        blog.setOwner("天天2");//修改Owner  

56.        session.update("com.tiantian.mybatis.model.BlogMapper.updateBlog", blog);  

57.        session.commit();  

58.        session.close();  

59.    }  

60.      

61.    /** 

62.     * 查询所有的记录 

63.     */  

64.    @Test  

65.    public void testSelectAll() {  

66.        SqlSession session = Util.getSqlSessionFactory().openSession();  

67.        List<Blog> blogs = session.selectList("com.tiantian.mybatis.model.BlogMapper.selectAll");  

68.        for (Blog blog:blogs)  

69.            System.out.println(blog);  

70.        session.close();  

71.    }  

72.      

73.    /** 

74.     * 模糊查询 

75.     */  

76.    @Test  

77.    public void testFuzzyQuery() {  

78.        SqlSession session = Util.getSqlSessionFactory().openSession();  

79.        String title = "中国";  

80.        List<Blog> blogs = session.selectList("com.tiantian.mybatis.model.BlogMapper.fuzzyQuery", title);  

81.        for (Blog blog:blogs)  

82.            System.out.println(blog);  

83.        session.close();  

84.    }  

85.      

86.    /** 

87.     * 删除记录 

88.     */  

89.    @Test  

90.    public void testDeleteBlog() {  

91.        SqlSession session = Util.getSqlSessionFactory().openSession();  

92.        session.delete("com.tiantian.mybatis.model.BlogMapper.deleteBlog"8);  

93.        session.commit();  

94.        session.close();  

95.    }  

96.      

97.}  

 

Test2.java

Java代码  

1. package com.tiantian.mybatis.test;  

2.   

3. import java.util.List;  

4.   

5. import org.apache.ibatis.session.SqlSession;  

6. import org.junit.Test;  

7.   

8. import com.tiantian.mybatis.model.Blog;  

9. import com.tiantian.mybatis.model.BlogMapper;  

10.import com.tiantian.mybatis.util.Util;  

11.  

12./** 

13. * 该系列操作是将SQL语句写在配置文件里面, 

14. * 然后通过对应Mapper接口来进行操作的 

15. * @author andy 

16. * 

17. */  

18.public class Test2 {  

19.  

20.    /** 

21.     * 新增记录 

22.     */  

23.    @Test  

24.    public void testInsertBlog() {  

25.        SqlSession session = Util.getSqlSessionFactory().openSession();  

26.        Blog blog = new Blog();  

27.        blog.setTitle("中国人");  

28.        blog.setContent("五千年的风和雨啊藏了多少梦");  

29.        blog.setOwner("天天");  

30.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

31.        blogMapper.insertBlog(blog);  

32.        session.commit();  

33.        session.close();  

34.    }  

35.  

36.    /** 

37.     * 查询单条记录 

38.     */  

39.    @Test  

40.    public void testSelectOne() {  

41.        SqlSession session = Util.getSqlSessionFactory().openSession();  

42.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

43.        Blog blog = blogMapper.selectBlog(7);  

44.        System.out.println(blog);  

45.        session.close();  

46.    }  

47.  

48.    /** 

49.     * 修改记录 

50.     */  

51.    @Test  

52.    public void testUpdateBlog() {  

53.        SqlSession session = Util.getSqlSessionFactory().openSession();  

54.        Blog blog = new Blog();  

55.        blog.setId(9);// 需要修改的Blogid  

56.        blog.setTitle("中国人2");// 修改Title  

57.        blog.setContent("黄色的脸,黑色的眼,不变是笑容");// 修改Content  

58.        blog.setOwner("天天2");// 修改Owner  

59.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

60.        blogMapper.updateBlog(blog);  

61.        session.commit();  

62.        session.close();  

63.    }  

64.  

65.    /** 

66.     * 查询所有记录 

67.     */  

68.    @Test  

69.    public void testSelectAll() {  

70.        SqlSession session = Util.getSqlSessionFactory().openSession();  

71.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

72.        List<Blog> blogs = blogMapper.selectAll();  

73.        for (Blog blog : blogs)  

74.            System.out.println(blog);  

75.        session.close();  

76.    }  

77.  

78.    /** 

79.     * 模糊查询 

80.     */  

81.    @Test  

82.    public void testFuzzyQuery() {  

83.        SqlSession session = Util.getSqlSessionFactory().openSession();  

84.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

85.        String title = "中国";  

86.        List<Blog> blogs = blogMapper.fuzzyQuery(title);  

87.        for (Blog blog : blogs)  

88.            System.out.println(blog);  

89.        session.close();  

90.    }  

91.  

92.    /** 

93.     * 删除记录 

94.     */  

95.    @Test  

96.    public void testDeleteBlog() {  

97.        SqlSession session = Util.getSqlSessionFactory().openSession();  

98.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

99.        blogMapper.deleteBlog(10);  

100.        session.commit();  

101.        session.close();  

102.    }  

103.  

104.}  

 

Test3.java

Java代码  

1. package com.tiantian.mybatis.test;  

2.   

3. import java.util.List;  

4.   

5. import org.apache.ibatis.session.SqlSession;  

6. import org.junit.Test;  

7.   

8. import com.tiantian.mybatis.model.Blog;  

9. import com.tiantian.mybatis.model.BlogMapper;  

10.import com.tiantian.mybatis.util.Util;  

11.  

12./** 

13. * 该系列操作是利用Mapper接口来进行的 

14. * ,然而其相应的SQL语句是通过对应的 

15. * 注解AnnotationMapper中对应的方法上定义的 

16. * @author andy 

17. * 

18. */  

19.public class Test3 {  

20.  

21.    /** 

22.     * 新增记录 

23.     */  

24.    @Test  

25.    public void testInsert() {  

26.        SqlSession session = Util.getSqlSessionFactory().openSession();  

27.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

28.        Blog blog = new Blog();  

29.        blog.setTitle("title2");  

30.        blog.setContent("content2");  

31.        blog.setOwner("owner2");  

32.        blogMapper.insertBlog2(blog);  

33.        session.commit();  

34.        session.close();  

35.    }  

36.      

37.    /** 

38.     * 查找单条记录 

39.     */  

40.    @Test  

41.    public void testSelectOne() {  

42.        SqlSession session = Util.getSqlSessionFactory().openSession();  

43.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

44.        Blog blog = blogMapper.selectBlog2(1);  

45.        System.out.println(blog);  

46.        session.close();  

47.    }  

48.      

49.    /** 

50.     * 查找多条记录,返回结果为一集合 

51.     */  

52.    @Test  

53.    public void testSelectAll() {  

54.        SqlSession session = Util.getSqlSessionFactory().openSession();  

55.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

56.        List<Blog> blogs = blogMapper.selectAll2();  

57.        for (Blog blog:blogs)  

58.            System.out.println(blog);  

59.        session.close();  

60.    }  

61.      

62.    /** 

63.     * 修改某条记录 

64.     */  

65.    @Test  

66.    public void testUpdate() {  

67.        SqlSession session = Util.getSqlSessionFactory().openSession();  

68.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

69.        Blog blog = new Blog();  

70.        blog.setId(3);  

71.        blog.setTitle("title3");  

72.        blog.setContent("content3");  

73.        blog.setOwner("owner3");  

74.        blogMapper.updateBlog2(blog);  

75.        session.commit();  

76.        session.close();  

77.    }  

78.      

79.    /** 

80.     * 删除记录 

81.     */  

82.    @Test  

83.    public void testDelete() {  

84.        SqlSession session = Util.getSqlSessionFactory().openSession();  

85.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

86.        blogMapper.deleteBlog2(5);  

87.        session.commit();  

88.        session.close();  

89.    }  

90.      

91.    @Test  

92.    public void testFuzzyQuery() {  

93.        SqlSession session = Util.getSqlSessionFactory().openSession();  

94.        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

95.        List<Blog> blogs = blogMapper.fuzzyQuery2("中国");  

96.        for (Blog blog:blogs)  

97.            System.out.println(blog);  

98.        session.close();  

99.    }  

100.      

101.}  

 

对应的建表语句:

Java代码  

1. CREATE TABLE `t_blog` (  

2.   `id` int(11) NOT NULL AUTO_INCREMENT,  

3.   `title` varchar(255) DEFAULT NULL,  

4.   `content` varchar(255) DEFAULT NULL,  

5.   `owner` varchar(50) DEFAULT NULL,  

6.   PRIMARY KEY (`id`)  

7. )  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MyBatis的动态SQL详解

博客分类: 

·        mybatis

MyBatis动态SQLDynamicforeach 

基础部分可以查看我的另一篇博客:http://haohaoxuexi.iteye.com/blog/1333271

 

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。

MyBatis中用于实现动态SQL的元素主要有:

 

·        if

·        choose(when,otherwise)

·        trim

·        where

·        set

·        foreach

if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。先来看如下一个例子:

Xml代码  

1.  <select id="dynamicIfTest" parameterType="Blog" resultType="Blog">  

2.      select * from t_blog where 11 = 1  

3.      <if test="title != null">  

4.          and title = #{title}  

5.      </if>  

6.      <if test="content != null">  

7.          and content = #{content}  

8.      </if>  

9.      <if test="owner != null">  

10.         and owner = #{owner}  

11.     </if>  

12. </select>  

这条语句的意思非常简单,如果你提供了title参数,那么就要满足title=#{title},同样如果你提供了Content和Owner的时候,它们也需要满足相应的条件,之后就是返回满足这些条件的所有Blog,这是非常有用的一个功能,以往我们使用其他类型框架或者直接使用JDBC的时候, 如果我们要达到同样的选择效果的时候,我们就需要拼SQL语句,这是极其麻烦的,比起来,上述的动态SQL就要简单多了。

 

choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。看如下一个例子:

Xml代码  

1.  <select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">  

2.      select * from t_blog where 11 = 1   

3.      <choose>  

4.          <when test="title != null">  

5.              and title = #{title}  

6.          </when>  

7.          <when test="content != null">  

8.              and content = #{content}  

9.          </when>  

10.         <otherwise>  

11.             and owner = "owner1"  

12.         </otherwise>  

13.     </choose>  

14. </select>  

when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出otherwise中的内容。所以上述语句的意思非常简单, 当title!=null的时候就输出and titlte = #{title},不再往下判断条件,当title为空且content!=null的时候就输出and content = #{content},当所有条件都不满足的时候就输出otherwise中的内容。

 

where语句的作用主要是简化SQL语句中where中的条件判断的,先看一个例子,再解释一下where的好处。

Xml代码  

1.  <select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">  

2.      select * from t_blog   

3.      <where>  

4.          <if test="title != null">  

5.              title = #{title}  

6.          </if>  

7.          <if test="content != null">  

8.              and content = #{content}  

9.          </if>  

10.         <if test="owner != null">  

11.             and owner = #{owner}  

12.         </if>  

13.     </where>  

14. </select>  

 where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。像上述例子中,如果title=null, 而content != null,那么输出的整个语句会是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因为MyBatis会智能的把首个and 或 or 给忽略。

 

trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能,示例代码如下:

Xml代码  

1.  <select id="dynamicTrimTest" parameterType="Blog" resultType="Blog">  

2.      select * from t_blog   

3.      <trim prefix="where" prefixOverrides="and |or">  

4.          <if test="title != null">  

5.              title = #{title}  

6.          </if>  

7.          <if test="content != null">  

8.              and content = #{content}  

9.          </if>  

10.         <if test="owner != null">  

11.             or owner = #{owner}  

12.         </if>  

13.     </trim>  

14. </select>  

 

set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。下面是一段示例代码:

Xml代码  

1.  <update id="dynamicSetTest" parameterType="Blog">  

2.      update t_blog  

3.      <set>  

4.          <if test="title != null">  

5.              title = #{title},  

6.          </if>  

7.          <if test="content != null">  

8.              content = #{content},  

9.          </if>  

10.         <if test="owner != null">  

11.             owner = #{owner}  

12.         </if>  

13.     </set>  

14.     where id = #{id}  

15. </update>  

 上述示例代码中,如果set中一个条件都不满足,即set中包含的内容为空的时候就会报错。

 

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:

1.   如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2.   如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3.   如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key

下面分别来看看上述三种情况的示例代码:

1.单参数List的类型:

Xml代码  

1.  <select id="dynamicForeachTest" resultType="Blog">  

2.      select * from t_blog where id in  

3.      <foreach collection="list" index="index" item="item" open="(" separator="," close=")">  

4.          #{item}  

5.      </foreach>  

6.  </select>  

 上述collection的值为list,对应的Mapper是这样的

Java代码  

1.  public List<Blog> dynamicForeachTest(List<Integer> ids);  

 测试代码:

Java代码  

1.  @Test  

2.  public void dynamicForeachTest() {  

3.      SqlSession session = Util.getSqlSessionFactory().openSession();  

4.      BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

5.      List<Integer> ids = new ArrayList<Integer>();  

6.      ids.add(1);  

7.      ids.add(3);  

8.      ids.add(6);  

9.      List<Blog> blogs = blogMapper.dynamicForeachTest(ids);  

10.     for (Blog blog : blogs)  

11.         System.out.println(blog);  

12.     session.close();  

13. }  

 

2.单参数array数组的类型:

Xml代码  

1.  <select id="dynamicForeach2Test" resultType="Blog">  

2.      select * from t_blog where id in  

3.      <foreach collection="array" index="index" item="item" open="(" separator="," close=")">  

4.          #{item}  

5.      </foreach>  

6.  </select>  

 上述collection为array,对应的Mapper代码:

Java代码  

1.  public List<Blog> dynamicForeach2Test(int[] ids);  

 对应的测试代码:

Java代码  

1.  @Test  

2.  public void dynamicForeach2Test() {  

3.      SqlSession session = Util.getSqlSessionFactory().openSession();  

4.      BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

5.      int[] ids = new int[] {1,3,6,9};  

6.      List<Blog> blogs = blogMapper.dynamicForeach2Test(ids);  

7.      for (Blog blog : blogs)  

8.          System.out.println(blog);  

9.      session.close();  

10. }  

 

3.自己把参数封装成Map的类型

Xml代码  

1.  <select id="dynamicForeach3Test" resultType="Blog">  

2.      select * from t_blog where title like "%"#{title}"%" and id in  

3.      <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">  

4.          #{item}  

5.      </foreach>  

6.  </select>  

上述collection的值为ids,是传入的参数Map的key,对应的Mapper代码:

Java代码  

1.  public List<Blog> dynamicForeach3Test(Map<String, Object> params);  

  对应测试代码:

Java代码  

1.  @Test  

2.  public void dynamicForeach3Test() {  

3.      SqlSession session = Util.getSqlSessionFactory().openSession();  

4.      BlogMapper blogMapper = session.getMapper(BlogMapper.class);  

5.      final List<Integer> ids = new ArrayList<Integer>();  

6.      ids.add(1);  

7.      ids.add(2);  

8.      ids.add(3);  

9.      ids.add(6);  

10.     ids.add(7);  

11.     ids.add(9);  

12.     Map<String, Object> params = new HashMap<String, Object>();  

13.     params.put("ids", ids);  

14.     params.put("title""中国");  

15.     List<Blog> blogs = blogMapper.dynamicForeach3Test(params);  

16.     for (Blog blog : blogs)  

17.         System.out.println(blog);  

18.     session.close();  

19. }  

 

 

### MyBatis 详解:使用教程与原理介绍 #### 工作原理概述 MyBatis 是一种持久层框架,它支持定制化 SQL 查询、存储过程以及高级映射。其工作流程可以分为以下几个方面: - 配置文件解析阶段:MyBatis 加载 `mybatis-config.xml` 文件并初始化全局配置信息[^3]。 - 动态 SQL 解析阶段:SQL 映射语句被加载到内存中,并根据参数动态生成最终执行的 SQL 语句。 - 数据库交互阶段:通过 JDBC 进行数据库操作,返回查询结果。 #### 开发环境搭建 要开始使用 MyBatis,需完成以下准备工作: - 导入 MyBatis 的核心 JAR 包作为项目的依赖项。如果采用 Maven 构建工具,则可以通过 POM 文件引入所需依赖[^2]。 ```xml <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.x.x</version> </dependency> ``` #### 全局配置文件说明 (`mybatis-config.xml`) 此文件定义了 MyBatis 的运行环境及相关设置,主要包括数据源配置和事务管理器等内容。以下是典型的 XML 结构示例: ```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> <!-- 环境配置 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!-- Mapper 扫描路径 --> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration> ``` #### SQL 映射文件设计 SQL 映射文件描述了如何将 Java 对象映射至数据库表中的记录。下面是一个简单的例子展示增删改查的操作方式: ```xml <mapper namespace="com.example.mapper.UserMapper"> <!-- 插入新用户 --> <insert id="addUser" parameterType="com.example.model.User"> INSERT INTO users (name, age) VALUES (#{name}, #{age}) </insert> <!-- 删除指定ID的用户 --> <delete id="removeUserById" parameterType="int"> DELETE FROM users WHERE id=#{id} </delete> <!-- 更新现有用户的属性 --> <update id="modifyUserInfo" parameterType="com.example.model.User"> UPDATE users SET name=#{name}, age=#{age} WHERE id=#{id} </update> <!-- 查找特定条件下的所有匹配条目 --> <select id="findUsersByAgeRange" resultType="com.example.model.User"> SELECT * FROM users WHERE age BETWEEN #{minAge} AND #{maxAge} </select> </mapper> ``` #### 编程接口调用方法 在实际编码过程中,通常会借助 MyBatis 提供的 SqlSession 来实现业务逻辑处理。例如: ```java import org.apache.ibatis.session.SqlSession; import com.example.mapper.UserMapper; public class UserService { private final UserMapper userMapper; public UserService(SqlSession sqlSession){ this.userMapper = sqlSession.getMapper(UserMapper.class); } public void addUser(String name,int age){ userMapper.addUser(name,age); // 调用对应的 insert 方法 } public List<User> findUsersInRange(int minAge,int maxAge){ return userMapper.findUsersByAgeRange(minAge,maxAge); // 返回符合条件的结果集 } } ``` #### 官方资源获取途径 对于希望深入研究该技术栈的学习者而言,可以从官方 GitHub 库下载最新版本及其文档资料[^4]: - 地址链接: https://github.com/mybatis/mybatis-3 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值