SQL--( 初识 MyBatis)

  1. 云栖社区>
  2. 博客>
  3. 正文

SQL--( 初识 MyBatis)

姜白告 2018-08-06 08:52:56 浏览740
展开阅读全文

MyBatis介绍

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
   Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。


使用mybatis的原因

 JDBC编程存在的问题
     1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,   如果使用数据库链接池可解决此问题。
     2、Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
     3、使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
     4、对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。


框架搭建


下载  https://github.com/mybatis/mybatis-3/releases
    mybatis-3.2.7.jar----mybatis的核心包
    lib----mybatis的依赖包
    mybatis-3.2.7.pdf----mybatis使用手册


1.创建java工程,jdk1.7
2.加入jar包  mybatis核心包、依赖包、数据驱动包。
3.在classpath下创建log4j.properties

    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4.在classpath(config)下创建SqlMapConfig.xml

约束文档路径:mybatis-3.2.7.jar/org/apache/ibatis/builder/xml/mybatis-3-config.dtd
5.创建实体类、数据库表

    privateintid;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址

6.在classpath(config)下的sqlmap目录下创建sql映射文件User.xml  

<?xmlversion="1.0"encoding="UTF-8"?>
    <!DOCTYPEmapper
    PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="test">
        <selectid="findUserById"parameterType="int"resultType="com.oaec.mybatis.pojo.User">
            select * from s_user where id = #{id}
        </select>

    </mapper>

 parameterType:定义输入到sql中的映射类型,
#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。
    resultType:定义结果映射类型。
7.mybatis框架需要加载映射文件,将Users.xml添加在SqlMapConfig.xml
    <!--加载映射文件-->

    <mappers>
        <mapper resource="sqlmap/User.xml"/>
    </mappers>

8.测试程序
9. 模糊查询

<select id="findUserByUsername" parameterType="java.lang.String"
            resultType="com.oaec.mybatis.pojo.User">
   select * from user where username like '%${value}%' 
</select>

10.#{}和${}    

#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{}括号中可以是value或其它名称。

${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,如果parameterType传输单个简单类型值,${}括号中只能是value。

11.parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

12.selectOne和selectList
    selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常
    selectList可以查询一条或多条记录


13.添加数据

    <insert id="insertUser" parameterType="com.oaec.mybatis.po.User">
        insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
    </insert>
    User user = new User();
    user.setUsername("张旭");
    user.setAddress("卢龙");
    user.setSex("1");
    sqlSession.insert("test.insertUser", user);

14.删除数据

    <delete id="deleteUserById" parameterType="int">
        delete from user where id=#{id}
    </delete>
    sqlSession.delete("test.deleteUserById",1);

15.修改数据

<update id="updateUser" parameterType="com.oaec.mybatis.pojo.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        where id=#{id}
    </update>
    User user = new User();
            user.setId(2);
            user.setUsername("冯");
            user.setAddress("秦皇岛");
            user.setSex("1");
            sqlSession.update("test.updateUser", user);

16.总结 :Mybatis解决jdbc编程的问题
    1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
    解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
    2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
    3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
    解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
    4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
    
17.与hibernate比较
    Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

    Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

    Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
    总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

Mapper动态代理方式    

1. 代理方式要遵循的规范

    1、    Mapper.xml文件中的namespace与mapper接口的类路径相同。
    2、    Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 
    3、    Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
    4、    Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

2. 接口文件

public interface UserMapper {
    //根据用户id查询用户信息
    public User findUserById(int id) throws Exception;
    //查询用户列表
    public List<User> findUserByUsername(String username) throws Exception;
    //添加用户信息
    publicvoid insertUser(User user)throws Exception; 
}

3.映射文件UserMapper.xml

<?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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 
注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址
-->
<mapper namespace="com.oaec.mybatis.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="user">
        SELECT * FROM USER WHERE id=#{value}
    </select>
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.oaec.mybatis.po.User">
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>
    <insert id="insertUser" parameterType="com.oaec.mybatis.po.User">
        insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>    

4.加载映射文件

<!-- 加载映射文件 -->
<mappers>
    <mapperresource="mapper/UserMapper.xml"/>
</mappers>

5.测试    

package com.oaec.mybatis.mapper;

import java.io.InputStream;
import java.util.ArrayList;
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 org.junit.Before;
import org.junit.Test;


public class UserMapperTest {

    private SqlSessionFactory sqlSessionFactory;

    // 此方法是在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        // 创建sqlSessionFactory

        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 创建会话工厂,传入mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);
    }

    
    @Test
    public void testFindUserById() throws Exception {
        
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //调用userMapper的方法
        
        User user = userMapper.findUserById(1);
        
        System.out.println(user);
        
        
    }
    

    @Test
    public void testFindUserByName() throws Exception {
        
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //调用userMapper的方法
        
        List<User> list = userMapper.findUserByName("小明");
        
        sqlSession.close();
        
        System.out.println(list);
        
        
    }

}

具体使用请看下篇博客--《SQL--(MyBatis 实战)》

网友评论

登录后评论
0/500
评论
姜白告
+ 关注