Mybatis编程式开发实战

参照mybatis3中文文档
入门以及配置还有动态sql等等全部都有,非常详细
建议大家别看我的,直接看mybats中文文档. 最起码要把mybatis入门仔细研读一遍

1.首先引入pom里引入mybatis ,mysql
 
            org.mybatis
            mybatis

            3.5.1
        

        
            mysql
            mysql-connector-java
            5.1.21
        
2.配置数据库和mybttis

单独做个配置文件db.properties,方便后期维护

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/gp-mybatis?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true
jdbc.username=root
jdbc.password=123456




    
    
        
        

        
        

        
        
        
        
        
        
        
        
        
    

    
        
    



    





    
        
            
            
                
                
                
                
            
        
    \


    
        
        
    


3.mybatis的使用

1.API方式
SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
如下面代码块中的com.gupaoedu.mapper.BlogMapper.selectBlogById

com.gupaoedu.mapper.BlogMapper.selectBlogById映射的sql语句

   /**
     * 使用MyBatis API方式
     * @throws IOException
     */
    @Test
    public void testStatement() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sqlSessionFactory.openSession();
        try {
            Blog blog = (Blog) session.selectOne("com.gupaoedu.mapper.BlogMapper.selectBlogById", 1);
            System.out.println(blog);
        } finally {
            session.close();
        }
    }
sqlsession的众多API可以直接执行sql语句

2.通过 SqlSession.getMapper(XXXMapper.class) 接口方式

API这种方式虽然能够正常工作,并且对于使用旧版本 MyBatis 的用户来说也比较熟悉。但是现在有了一种更简洁的方式 ——使用正确描述每个语句的参数和返回值的接口
(比如 BlogMapper.class),我们不仅可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。


    /**
     * 通过 SqlSession.getMapper(XXXMapper.class)  接口方式
     * @throws IOException
     */
    @Test
    public void testSelect() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sqlSessionFactory.openSession(); // ExecutorType.BATCH
        try {
            BlogMapper mapper = session.getMapper(BlogMapper.class);
            Blog blog = mapper.selectBlogById(1);
            System.out.println(blog);
        } finally {
            session.close();
        }
    }

sqlsesss.getmapper(BlogMapper.class)里的mapper接口


public interface BlogMapper {
    /**
     * 根据主键查询文章
     * @param bid
     * @return
     */
    public Blog selectBlogById(Integer bid);

    /**
     * 根据实体类查询文章
     * @param blog
     * @return
     */
    public List selectBlogByBean(Blog blog );

    /**
     * 文章列表翻页查询
     * @param rowBounds
     * @return
     */
    public List selectBlogList(RowBounds rowBounds);

    /**
     * 更新博客
     * @param blog
     * @return
     */
    public int updateByPrimaryKey(Blog blog);

    /**
     * 新增博客
     * @param blog
     * @return
     */
    public int insertBlog(Blog blog);

    /**
     * 根据博客查询作者,一对一,嵌套结果
     * @param bid
     * @return
     */
    public BlogAndAuthor selectBlogWithAuthorResult(Integer bid);

    /**
     * 根据博客查询作者,一对一,嵌套查询,存在N+1问题
     * @param bid
     * @return
     */
    public BlogAndAuthor selectBlogWithAuthorQuery(Integer bid);

    /**
     * 查询文章带出文章所有评论(一对多)
     * @param bid
     * @return
     */
    public BlogAndComment selectBlogWithCommentById(Integer bid);

    /**
     * 查询作者带出博客和评论(多对多)
     * @return
     */
    public List selectAuthorWithBlog();

    List selectByExample(BlogExample example);

}

BlogMapper.xml,真正的sql语句,映射接口的sql语句

只有接口肯定是不行的,这里的xml是真正的sql语句
为了这个简单的例子,我们似乎在这个文件头上写了不少配置,但实际上它并不多。在一个 XML 映射文件中,可以定义无数个映射语句,这样一来,XML 头部和文档类型声明占去的部分就显得微不足道了。




    
    

    




    
        

        
        
    

    
    
        
        
        
        
            
            
        
    

    
    
        
        
         
    

    
    
        
            
            
        
    

    
    
        
        
        
            
            
            
            
                
                
            
        
    

    

    
    

    

    
    

    
    

    
    

    
    

    
    

    


    
        update blog
        set name = #{name,jdbcType=VARCHAR}
        where bid = #{bid,jdbcType=INTEGER}
    

    
    insert into blog (bid, name, author_id)
    values (#{bid,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{authorId,jdbcType=INTEGER})

    

    
    
        bid, name, author_id
    
    
        
            
                
                    
                        
                            
                                
                                    and ${criterion.condition}
                                
                                
                                    and ${criterion.condition} #{criterion.value}
                                
                                
                                    and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                                
                                
                                    and ${criterion.condition}
                                    
                                        #{listItem}
                                    
                                
                            
                        
                    
                
            
        
    
    

你可能注意到这和使用完全限定名调用 Java 对象的方法Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);类似。这样,该命名就可以直接映射到在命名空间中同名的 Mapper 类,并将已映射的 select 语句中的名字、参数和返回类型匹配成方法。 因此你就可以像上面那样很容易地调用这个对应 Mapper 接口的方法,就像下面这样: 明明空间类似于类,下面语句中的id则是方法名.另外这个id之所以没用些全路径是因为我们的mabtis.xml里配置了别名

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

这种方法有些优势,在mybatis中文文档中已声明首先它不依赖于字符串字面值,会更安全一点; 其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择已映射的 SQL 语句。

三 编程式开发的核心对象

下面核心对象的介绍的话,上面已经说了不少了,mybatis中文档里也有解释
- SqlSessionFactoryBuilder
- SqlSessionFactory
- SqlSession
- Mapper

四 Mybatis编程式开发,各核心对象作用域(Scope)和生命周期

理解我们目前已经讨论过的不同作用域和生命周期类是至关重要的,因为错误的使用会导致非常严重的并发问题

提示 对象生命周期和依赖注入框架
依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。 如果对如何通过依赖注入框架来使用 MyBatis 感兴趣,可以研究一下 MyBatis-Spring 或 MyBatis-Guice 两个子项目。

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在我们在使用过程中要创建很多的sqlsession会话,因此没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,一般我们生产中会设计成单例的,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。 换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

在你的所有的代码中一致地使用这种模式来保证所有数据库资源都能被正确地关闭。

映射器实例

映射器是一些由你创建的、绑定你映射的语句的接口。映射器接口的实例是从 SqlSession 中获得的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。尽管如此,映射器实例的最佳作用域是方法作用域。 也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可丢弃。 并不需要显式地关闭映射器实例,尽管在整个请求作用域保持映射器实例也不会有什么问题,但是你很快会发现,像 SqlSession 一样,在这个作用域上管理太多的资源的话会难于控制。 为了避免这种复杂性,最好把映射器放在方法作用域内。下面的示例就展示了这个实践:

try (SqlSession session = sqlSessionFactory.openSession()) {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  // 你的应用逻辑代码
}


MyBatis 的配置

你可能感兴趣的:(Mybatis编程式开发实战)