SSM框架系列-从JDBC到Mybatis(一)

前言

Java学到一定程度,框架终归是不可避免的,毕竟程序开发很多时候不是一个人的事儿。这两天学习了MyBatis框架,想着结合一下这几天学到的东西和实习的经验总结一下。大概的思路就是从JDBC的缺陷到MyBatis的介绍和运行流程,再就是Mybatis的一个增删改查小程序;然后是企业中MyBatis进行数据库开发时采用Dao方法和Mapper方法的一个介绍,最后是和Spring的一个整合。

也希望大家提出宝贵的建议。

JDBC

JDBC小程序

DBHelper(数据库连接类)

/**
  * @param连接数据库
  * */
public class DBHelper {
    //参数配置
//public static final String url = "jdbc:mysql://127.0.0.1/test";
public static final String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf-8";
public static final String name = "com.mysql.jdbc.Driver";
public static final String user = "root";
public static final String password = "8888";

public static Connection conn= null;

public DBHelper() {
    // TODO Auto-generated constructor stub
    try{
        Class.forName(name);            //加载数据库驱动
        conn = DriverManager.getConnection(url, user, password);    //通过驱动管理类获取数据库链接
    }catch(Exception e){
        e.printStackTrace();
    }
}

public static void Close(){
    try {
        conn.close();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}   
}

testJdbc(测试SQL查询)

public class testJdbc {

private static String sql = null;
private static DBHelper db = null;

public static PreparedStatement pst = null;
public static ResultSet ret = null;

public static void main(String[] args) {
    // TODO Auto-generated method stub
    db = new DBHelper();        //通过构造器连接到数据库
    System.out.println(db.conn);
    db.Close();
    /*
    //sql = "INSERT INTO `test`.`user` (`Username`, `Password`, `Age`, `Address`, `UserId`) VALUES"
    //      + " ('bb', '1234', '23', 'hubei', '4');";       //插入语句
    //sql = "UPDATE `test`.`user` SET `Username`='ouou' WHERE `UserId`='1';";   //更新语句
    sql = "DELETE * where `UserId` = '2'";                                  //删除语句  
    String sql1 = "select * from user";                                     //选择语句
    try {
        pst = db.conn.prepareStatement(sql);
        pst.execute();
        ret = pst.executeQuery(sql1);
        while(ret.next()){
            String name = ret.getString(1);
            String pass = ret.getString(2);
            String age = ret.getString(3);
            String addr = ret.getString(4);
            String id = ret.getString(5);
            System.out.println(id+" "+name+" "+pass+" "+age+" "+addr);
        }
    }catch(SQLException e){
        e.printStackTrace();
    }*/ 
  }
 }

问题总结

总结网上搜集到东西和自己实际遇到的归纳为以下几点:

  • 数据库频繁地连接开启和关闭,造成资源的浪费。(使用数据库连接池进行管理)
  • SQL语句、preparedStatement设置参数硬编码在Java代码中,不利于系统维护。(使用xml进行配置)
  • resultSet遍历结果集数据时,也存在硬编码。(将查询的结果集,自动映射成Java对象)

MyBatis

为什么选择MyBatis

  MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 
代码和手工设置参数以及抽取结果集。MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java的 
POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。(选自官网)
  • 也就是说开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc的过程代码。MyBatis通过xml或注解的方式将要执行的各种statement(statement,preparedStatement、CallableStatement)配置起来,并通过Java对象和statement中的SQL进行映射生成最终执行的SQL语句,最后又mybatis框架执行SQL并将结果映射成Java对象并返回。

MyBatis是什么

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。

MyBatis框架图

SSM框架系列-从JDBC到Mybatis(一)_第1张图片
Paste_Image.png

MyBatis的运行流程

  • 在SQLMapConfig.xml(mybati的全局配置文件)中配置mybatis的运行环境等信息。并在其中加载mapper.xml(sql映射文件,配置了操作数据库的SQL语句)文件。
  • 通过mybatis环境等配置信息构造SQLSessionFactory会话工厂。
  • 由会话工厂创建SQLSession来操作数据库。
  • mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有基本执行器和缓存执行器两个实现。
  • Mapped Statement也是mybatis一个底层封装对象,包装了mybatis配置信息及SQL映射信息等。mapper.xml文件中一个SQL对应一个Mapped Statement 对象,SQL的id即是Mapped Statement的id。
  • Mapped Statement对SQL执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行SQL前将输入的Java对象映射至SQL中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
  • Mapped Statement对SQL执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行SQL后将输出结果映射至Java对象中,输出结果映射过程相当于jdbc编程中结果的解析处理过程。

MyBatis的优缺点及Hibernate的简短比较

Mybatis和hibernate的不同之处在于它不是一个完全的ORM框架,它需要开发者自己编写SQL语句,不过mybatis可以通过xml或注解方式灵活配置要运行的SQL语句,并将Java对象和SQL语句映射生成最终执行的SQL,最后将SQL执行的结果再映射生成Java对象。
MyBatis相对于hibernate来说,学习门槛低,易于学习,灵活度也高,适合对关系数据模型要求不高的软件开发,以为其需求变化频繁。正是因为mybatis的高度灵活,所以它无法做到数据库无关性,需要实现支持多种数据库的软件则需要自定义多套SQL映射文件。
Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
所以如是说:没有最好的框架,只有最适合的框架。

简单的CRUD入门程序

导入的包:


SSM框架系列-从JDBC到Mybatis(一)_第2张图片
Paste_Image.png

项目工程结构:


SSM框架系列-从JDBC到Mybatis(一)_第3张图片
Paste_Image.png

输出日志信息配置(log4j.properties):
# Global logging configuration
log4j.rootLogger = DEBUG,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p [%t] - %m%n
全局配置文件(SqlMapConfig.xml):









    
    
        
    
        
            
            
            
            
        
    




    



数据库配置文件(db.properties)

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=8888

User po类:

package com.howie.po;

import java.io.Serializable;
import java.util.Date;

/**
 * @param User po类
 */
public class User implements Serializable {

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

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public String getSex() {
    return sex;
}
public void setSex(String sex) {
    this.sex = sex;
}
public Date getBirthday() {
    return birthday;
}
public void setBirthday(Date birthday) {
    this.birthday = birthday;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}
}

映射文件user.xml

  













    select LAST_INSERT_ID() 

  insert into user(username,birthday,sex,address) 
  values(#{username},#{birthday},#{sex},#{address})




    delete from user where id=#{id}




    update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
    where id=#{id}



测试文件MybatisTest类
(避免麻烦,测试一个查找语句,读者感兴趣的可以自行实现其他功能)

package com.howie.test;

import java.io.IOException;
import java.io.InputStream;

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.howie.po.User;

public class MybatisTest {

public static void findUserByIdTest() throws IOException{
    //配置文件
    String resource = "SqlMapConfig.xml";
    
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //创建回话工厂
    SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(inputStream);
    //通过工厂得到SQLSession
    SqlSession ss = sf.openSession();
    //通过SQLSession操作数据库
    //第一个参数:映射文件中statement的id,等于=namespace+statement的id
    //第二个参数:制定和映射文件中所匹配的parameterType得参数
    //ss.selectOne结果是与映射文件中所匹配的resultType类型的对象
    User user = ss.selectOne("test.findUserById", 1);
    System.out.println(user);
    System.out.print(user.getAddress()+" "+user.getId()+" "+user.getUsername()+
            " "+user.getSex());
    System.out.println();
    //释放资源
    ss.close();
}


  public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        findUserByIdTest();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

未完待续.......

你可能感兴趣的:(SSM框架系列-从JDBC到Mybatis(一))