Mybatis - 简单使用Mybatis 实现 增删改查

1.传统的JDBC实现

   首先我们先看下传统的JDBC的代码 :


public class JdbcDemo {

	private final static String CONN_URL="jdbc:oracle:thin:@localhost:1521:xe";
	private final static String ORACLE_DRIVER="oracle.jdbc.OracleDriver";
	private final static String CONN_NAME="hr";
	private final static String CONN_PASSWORD="hr";
	
	public static void main(String[] args) throws Exception {
		
		Class.forName(ORACLE_DRIVER);
		Connection conn = DriverManager.getConnection(CONN_URL, CONN_NAME, CONN_PASSWORD);
		String sql="select * from f_client";
		PreparedStatement psm = conn.prepareStatement(sql);
//		psm.setInt(1, 14);
		ResultSet rs = psm.executeQuery();
		while(rs.next()){
			 System.out.println(rs.getString("username")+" :"+rs.getString("now_address"));
		}
		rs.close();
		psm.close();
		conn.close();
	}
}

      在这里我们使用的是Oracle数据库,使用通过SQL语句操作数据库 ,会发现以下问题 :

    (1)数据库连接,使用时创建,不使用立即释放,对数据库频繁的连接开启和关闭,造成数据库资源浪费,影响数据库性能;
       解决:使用数据库连接池来解决;
  (2)将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护。
       解决:将sql语句配置在xml配置文件中,就不需要编译源代码了。
  (3)向preparedStatement中设置参数.对占位符位置和设置参数值,硬编码在java代码中,不利于维护;
       解决:将sql语句及占位符和参数全部配置在xml中;
  (4)从resutSet中遍历结果集数据时,存在硬编码,不利于维护;
       解决:将结果自动映射为java对象;


2.Mybatis的一些名词及其作用

   mybatis是持久层的框架,是apache下的顶级项目,可以github中clone;

   mybatis将主要精力放在sql上,通过mybatis提供的映射方式,自由的灵活生成(半自动化,大部分的程序需要的sql)满足的sql语句;
   mybatis可以将向preparedStatementa中输入参数自动进行输入映射,将查询结果集灵活的映射为java对象(输出映射);   
    
   SqlMapConfig.xml 是mybatis的全局配置文件,配置了数据源,事务等mybatis运行环境,配置映射文件(sql语句)mapper.xml...;
   
   SqlSessionFactory 会话工厂,作用:创建SqlSession;根据配置文件创建工厂
   
   SqlSession 会话 ,作用 :操作数据库,发出sql的增删改查;是接口
   
   Executor 执行器 ,作用 :sqlSession内部通过执行器操作数据库;是接口(基本执行器,缓存执行器)
   
   mapped statement 底层封装对象,作用 :对操作数据库存储封装,包括sql语句,输入参数,输出结果类型;
   
   数据输入输出的参数类型:值类型,hashmap ,pojo自定义。


3.实例 - 实现对客户信息的增删改查

        注意里面的所出现的名词,查看 2里面的相关名词 及其解释 ,mybatis实例代码在文章最后,包含里面的jar包均有(JDBC - Oracle数据库驱动)。

    (1)创建员工表和添加数据

           创建F_Client 客户表 :

CREATE TABLE F_CLIENT(
    ID NUMBER(12) PRIMARY KEY,--用户编号
    USERNAME VARCHAR2(20) NOT NULL,--用户姓名
    CLIENT_CERTIFICATE_NO VARCHAR2(20) NOT NULL UNIQUE,--证件号码
    BORN_DATE DATE,--出生日期
    FAMILY_REGISTER_ADDRESS VARCHAR2(200),--家庭住址
    NOW_ADDRESS VARCHAR2(200) NOT NULL,--现在住址
    CONTACT_MODE VARCHAR2(50) NOT NULL,--联系方式
    URGENCY_CONTACT_MODE VARCHAR2(50) NOT NULL,--紧急联系方式
    CREATE_DATE DATE NOT NULL--创建时间
);

         添加4条数据 :

     

insert into F_CLIENT (ID, USERNAME, CLIENT_CERTIFICATE_NO, BORN_DATE, FAMILY_REGISTER_ADDRESS, NOW_ADDRESS, CONTACT_MODE, URGENCY_CONTACT_MODE, CREATE_DATE)
values (1, 'sawyer', '1593224056', to_date('10-10-1980', 'dd-mm-yyyy'), '北京市海淀区东北旺', 'peaking', '123456789', '987654321', to_date('15-12-2015 08:47:13', 'dd-mm-yyyy hh24:mi:ss'));

insert into F_CLIENT (ID, USERNAME, CLIENT_CERTIFICATE_NO, BORN_DATE, FAMILY_REGISTER_ADDRESS, NOW_ADDRESS, CONTACT_MODE, URGENCY_CONTACT_MODE, CREATE_DATE)
values (2, 'yangly', '1593224057', to_date('11-10-1980', 'dd-mm-yyyy'), '北京市海淀区东北旺', 'peaking', '123456789', '987654321', to_date('15-12-2015 08:47:13', 'dd-mm-yyyy hh24:mi:ss'));

insert into F_CLIENT (ID, USERNAME, CLIENT_CERTIFICATE_NO, BORN_DATE, FAMILY_REGISTER_ADDRESS, NOW_ADDRESS, CONTACT_MODE, URGENCY_CONTACT_MODE, CREATE_DATE)
values (3, 'gaozhy', '1593224058', to_date('12-12-1980', 'dd-mm-yyyy'), '湖北省洪山区黄家湖', 'shanghai', '123456789', '987654321', to_date('15-12-2015 08:47:13', 'dd-mm-yyyy hh24:mi:ss'));

insert into F_CLIENT (ID, USERNAME, CLIENT_CERTIFICATE_NO, BORN_DATE, FAMILY_REGISTER_ADDRESS, NOW_ADDRESS, CONTACT_MODE, URGENCY_CONTACT_MODE, CREATE_DATE)
values (4, 'wangmj', '1593224059', to_date('13-04-1980', 'dd-mm-yyyy'), '湖北省洪山区黄家湖', 'hubei', '123456789', '987654321', to_date('15-12-2015 08:47:13', 'dd-mm-yyyy hh24:mi:ss'));

   (2)配置Log4j DEBUG

            新建Log4j.properties 文件

# Global logging configuration
# 开发的时候配置为 DEBUG 
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 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

 

    (3)配置SqlMapConfig.xml



        
	
		
			
			
				
				
				
				
			
		
	
        
	
		
	

  (4)实现客户表操作的mapper 

          1)注意namespace ,sql操作标签id,需要使用

          2)sql 语句不需要 分号 (;)

          3)parameterType 参数类型

          4)resultType 返回结果类型










	
	
	
	

	
	

	
	

	
	
		delete from f_client where id=#{id}
	

    
	

		update f_client set
		username=#{username},client_certificate_no=#{client_certificate_no},born_date=#{born_date},family_register_address=#{family_register_address},now_address=#{now_address},contact_mode=#{contact_mode},urgency_contact_mode=#{urgency_contact_mode}
		where id=#{id}

	







      命名: Client.xml(原始的) , mapper代理开发映射文件名称叫做xxxmapper.xml;
    作用: 在映射文件中配置sql语句
namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离;
注意:使用mapper代理的方法开发,namespace有特殊的重要作用;
paramterType : 在映射文件中通过指定参数类型
resultType :输出结果类型
#{} 表示一个占位符
${} 表示一个拼接符号,会引起sql注入,不建议使用;
selectOne 表示查询出一条记录进行映射
selectList 表示查询出一个列表(多条记录)进行映射


   (5)实现客户表的Pojo 

package mybatis.po;

import java.util.Date;


/**
 * 
 * 用户po
 * 作者:原明卓
 * 时间:2015年12月17日 下午2:58:18
 * 描述:TODO
 */
public class FClient {
	 @Override
	public String toString() {
		return "FClient [id=" + id + ", username=" + username
				+ ", client_certificate_no=" + client_certificate_no
				+ ", born_date=" + born_date + ", family_register_address="
				+ family_register_address + ", now_address=" + now_address
				+ ", contact_mode=" + contact_mode + ", urgency_contact_mode="
				+ urgency_contact_mode + ", create_data=" + create_data + "]";
	}
	//属性名和数据库名对应
	 private Integer id;
	 private String username;
	 private String client_certificate_no;
	 private Date born_date;
	 private String family_register_address;
	 private String now_address;
	 private String contact_mode;
	 private String urgency_contact_mode;
	 private Date create_data;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getClient_certificate_no() {
		return client_certificate_no;
	}
	public void setClient_certificate_no(String client_certificate_no) {
		this.client_certificate_no = client_certificate_no;
	}
	public Date getBorn_date() {
		return born_date;
	}
	public void setBorn_date(Date born_date) {
		this.born_date = born_date;
	}
	public String getFamily_register_address() {
		return family_register_address;
	}
	public void setFamily_register_address(String family_register_address) {
		this.family_register_address = family_register_address;
	}
	public String getNow_address() {
		return now_address;
	}
	public void setNow_address(String now_address) {
		this.now_address = now_address;
	}
	public String getContact_mode() {
		return contact_mode;
	}
	public void setContact_mode(String contact_mode) {
		this.contact_mode = contact_mode;
	}
	public String getUrgency_contact_mode() {
		return urgency_contact_mode;
	}
	public void setUrgency_contact_mode(String urgency_contact_mode) {
		this.urgency_contact_mode = urgency_contact_mode;
	}
	public Date getCreate_data() {
		return create_data;
	}
	public void setCreate_data(Date create_data) {
		this.create_data = create_data;
	}

}


  (6)实现操作方法

           1)使用Resources.getResourceAsStream(sqlmapconfig.xml) 加载数据库配置

           2)创建会话工厂 :参入为mybatis的配置文件信息

           3)通过工厂得到SqlSession

           4)通过sqkSession操作数据库 ,第一个参数:映射文件中statement的id等于=namespace+"."+statement的id,结果与ResultType 的结果集一样

           5)释放资源


package mybatis.frist;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import mybatis.po.FClient;

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.Test;

/**
 * 测试Mybatis
 *
 * 作者:原明卓 时间:2015年12月17日 下午4:37:25 描述:TODO
 */
public class TestMyBatis {

	// 根据id查询用户信息,得到一条记录结果
	@Test
	public void findClientByIdTest() {
		String resource = "SqlMapConfig.xml";

		InputStream is;
		SqlSession os = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 创建会话工厂 :参入为mybatis的配置文件信息
			SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);

			// 通过工厂得到SqlSession
			os = build.openSession();

			// 通过sqkSession操作数据库
			// 第一个参数:映射文件中statement的id等于=namespace+"."+statement的id
			// 结果与ResultType 的结果集一样
			FClient client = os.selectOne("test.findClientById", 14);

			System.out.println(client);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (os != null) {
				// 释放资源
				os.close();
			}
		}
	}

	/**
	 * 根据用户姓名模糊查询
	 */
	@Test
	public void findClientByNameTest() {
		String resource = "SqlMapConfig.xml";

		InputStream is;
		SqlSession os = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 创建会话工厂 :参入为mybatis的配置文件信息
			SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);

			// 通过工厂得到SqlSession
			os = build.openSession();

			// 通过sqkSession操作数据库
			// 第一个参数:映射文件中statement的id等于=namespace+"."+statement的id
			// 结果与ResultType 的结果集一样
			List clients = os
					.selectList("test.findClientByName", "ya");

			System.out.println(clients);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (os != null) {
				// 释放资源
				os.close();
			}
		}
	}

	/**
	 * 添加用户信息
	 */
	@Test
	public void addClient() {
		String resource = "SqlMapConfig.xml";

		InputStream is;
		SqlSession os = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 创建会话工厂 :参入为mybatis的配置文件信息
			SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);

			// 通过工厂得到SqlSession
			os = build.openSession();

			// 通过sqkSession操作数据库
			// 第一个参数:映射文件中statement的id等于=namespace+"."+statement的id
			// 结果与ResultType 的结果集一样
			FClient c = new FClient();
			c.setId(5);
			c.setBorn_date(new Date());
			c.setClient_certificate_no("我是新增的");
			c.setContact_mode("我是新增的");
			c.setCreate_data(new Date());
			c.setFamily_register_address("我是新增的");
			c.setNow_address("我是新增的");
			c.setUrgency_contact_mode("我是新增的");
			c.setUsername("yuha");

			int row = os.insert("test.insertClient", c);
			System.out.println(row);
			// 提交事务
			os.commit();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (os != null) {
				// 释放资源
				os.close();
			}
		}

	}
	
	@Test
	public void deleteClient() {
		String resource = "SqlMapConfig.xml";

		InputStream is;
		SqlSession os = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 创建会话工厂 :参入为mybatis的配置文件信息
			SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);

			// 通过工厂得到SqlSession
			os = build.openSession();

			// 通过sqkSession操作数据库
			// 第一个参数:映射文件中statement的id等于=namespace+"."+statement的id
			// 结果与ResultType 的结果集一样

			os.delete("test.deleteClient",15);
			os.commit();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (os != null) {
				// 释放资源
				os.close();
			}
		}

	}
	
	
	@Test
	public void updateClient() {
		String resource = "SqlMapConfig.xml";

		InputStream is;
		SqlSession os = null;
		try {
			is = Resources.getResourceAsStream(resource);
			// 创建会话工厂 :参入为mybatis的配置文件信息
			SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);

			// 通过工厂得到SqlSession
			os = build.openSession();

			// 通过sqkSession操作数据库
			// 第一个参数:映射文件中statement的id等于=namespace+"."+statement的id
			// 结果与ResultType 的结果集一样

			FClient c = new FClient();
			c.setId(4);
			c.setBorn_date(new Date());
			c.setClient_certificate_no("我是修改的1");
			c.setContact_mode("我是修改的");
			c.setCreate_data(new Date());
			c.setFamily_register_address("我是修改增的");
			c.setNow_address("我是修改的");
			c.setUrgency_contact_mode("我是修改的");
			c.setUsername("yuha");
			
			os.update("test.updateClient", c);
			// 提交事务
			os.commit();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (os != null) {
				// 释放资源
				os.close();
			}
		}

	}

}

    (6)实现主键返回 

             在client.xml 的mapper中实现 :

    主键返回 : 
		   mysql: 自增主键返回 使用函数 LAST_INSERT_ID() ,相对于insert语句,在其后执行
		     
                 
                 Select LAST_INSERT_ID()
             
		           非自增主键,使用uuid()函数生成主键,相对于insert语句,在其后执行
			 
                
                 Select UUID()
              
			  
			  Oracel : 使用序列实现,和mysql非自增主键相似;



4.mybatis和hibernate 本质区别和应用场景

 ( 1)hibernate 是一个标准的ORM(对象关系映射)框架,入门门槛高,不需要写sql,sql自动生成,对sql语句进行优化,修改比较困难;
     应用场景 : 适应与需求变化不多的中小型项目,比如:后台管理系统;
  
 ( 2)mybatis 专注的是sql本身,需要自己编写sql语句,sql修改,优化比较方便,一个不完全的orm框架,虽然自己写sql , 也可以实现映射(输入输出映射);
     应用场景 :适应与需求变化较多的项目,比如 :互联网项目;

5.Demo 免积分下载

http://download.csdn.net/detail/lablenet/9369787


你可能感兴趣的:(java)