Mybatis

Mybatis

1.为什么使用mybatis

MyBatis是一个半自动化的持久化层框架。

JDBC
SQL夹在Java代码块里,耦合度高导致硬编码内伤
维护不易且实际开发需求中sql是有变化,频繁修改的情况多见

Hibernate和JPA
长难复杂SQL,对于Hibernate而言处理也不容易
内部自动生产的SQL,不容易做特殊优化
基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难,导致数据库性能下降

对开发人员而言,核心sql还是需要自己优化

sql和java编码分开,功能边界清晰,一个专注业务、一个专注数据

2.下载地址

3.HelloWorld

<!-- sql demo-->
CREATE TABLE `employee` (
  `id` varchar(50) NOT NULL default '',
  `name` varchar(50) default NULL,
  `gender` char(1) default NULL,
  `address` varchar(100) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `employee` VALUES ('1', '张全蛋', '1', '暴走大事件');
INSERT INTO `employee` VALUES ('2', '王尼玛', '1', '暴走大事件');
INSERT INTO `employee` VALUES ('3', '李小华', '0', '富士康');
INSERT INTO `employee` VALUES ('4', '赵铁柱', '1', '富士康');
INSERT INTO `employee` VALUES ('5', '风清扬', '1', '华山');
INSERT INTO `employee` VALUES ('6', '周杰伦', '1', '台北');
INSERT INTO `employee` VALUES ('7', '卡死了', '1', '我说的');

使用步骤:

  1. 导入jar包

2)添加mybatis全局配置文件,log4j日志文件,数据源信息文件

3)创建实例类(POJO,domain,javaBean,entity),实体类的映射文件(sql映射文件)

4)将映射文件注册到mybatis全局配置文件中

5)编写SQL,根据全局配置文件拿到SqlSessionFactory,通过SqlSessionFactory拿到SqlSession对象,调用封装好的方法进行CRUD,关闭会话。

package com.igeek.pojo;

public class Employee {

	private String id ;
	private String name;
	private char gender;
	private String address;
	
}





<mapper namespace="hello">
	<select id="selOne" resultType="com.igeek.pojo.Employee">
		select * from employee where id=#{id} 
	select>
	
    
    
    
      
      
mapper>
try {
		//根据全局配置文件。利用SqlSessionFactoryBuilder创建数据库会话工厂对象。
		Reader reader = Resources.getResourceAsReader("resource.xml");
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		//通过会话工厂获取SqlSession对象,一个SqlSession对象代表和数据库的一次会话
		SqlSession session = sqlSessionFactory.openSession();
		//推荐使用namespace+id,防止多个配置文件中的id重复。
		Employee emp = session.selectOne("hello.selOne", "1");	
		System.out.println(emp);
		//每次使用完需要关闭sqlsession对象。(必须)
		session.close();
		//注意:SqlSession跟connection一样都不是线程安全的,因此不能被共享。不推荐写成成员变量。每次使用重新获取。
} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
} 

##4.mybatis三种开发模式

1.请看上面HelloWorld的demo

​ (存在问题,每次都要指定查询那个命名空间下的那个标签的sql,类型是object类型)

2.使用接口+配置文件

​ (接口与配置文件动态绑定。mybatis会为接口自动创建代理对象)

​ (注意:1.需要将namespace中的值,写成接口的全路径 2.接口方法名称跟标签id一致)

​ (使用接口式优点,有明确的返回值,更严格的类型检查。将规范与实现分离,可以使用不同的持久层技术,方便开发扩展以及维护。)

3.使用接口+注解

SqlSession可以直接调用方法的id进行数据库操作,但是我们一般还是推荐使用SqlSession获取到Dao接口的代理类,执行代理对象的方法,可以更安全的进行类型检查操作。。。 推荐使用第二种开发模式!!!!!

//第二种方式的demo...
	@Test
	public void test2(){
		SqlSession session = getSqlSession();
		EmployeeDao employeeDao = session.getMapper(EmployeeDao.class);
		System.out.println(employeeDao.getClass());
		Employee employee = employeeDao.selOne(2);
		System.out.println(employee);
	}
	
	//封装一个获取sqlsession对象的方法。
	public SqlSession getSqlSession(){
		Reader reader=null;
		try {
			reader = Resources.getResourceAsReader("resource.xml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		//通过会话工厂获取SqlSession对象,一个SqlSession对象代表和数据库的一次会话
		SqlSession session = sqlSessionFactory.openSession();
		return session;
	}

##5.全局配属属性内容

settings

typeAliases

typeHandlers

typeHandlers JDK1.8 日期类 JSR310规范,时间类型处理器。

plugins

环境中的自定义数据源,默认使用mybatis提供的数据源

数据库厂商支持(全局文件中配置完,在映射文件中配置当前SQL在那个数据库环境下执行.)

mapper注册一个SQL映射

6.DTD设置

7.Mapper中的CRUD


  	 <insert id="insertEmp" parameterType="com.igeek.pojo.Employee">
  		insert into employee values(#{id},#{name},#{gender},#{address})
  	insert>
    <update id="updateEmp">
    	update employee set name = #{name},gender = #{gender},address=#{address}
    	where id = #{id}
    update>
    <delete id="deleteEmp">
    	delete from employee where id = #{id}
    delete> 
	@Test
	public void test2(){
		SqlSession session = getSqlSession();
		EmployeeDao employeeDao = session.getMapper(EmployeeDao.class);
		Employee employee = new Employee();
		employee.setId("7");
		employeeDao.deleteEmp(employee);
		//注意,拿到的sqlSession对象需要手动的提交,接口中的返回值类型可以是void,int long boolean
        //可以设置自动提交工厂对象.openSession(true);
		session.commit();
		session.close();
	}	

8.mybatis使用主键自增


9.#{}中的参数处理

1.当传递的参数只有一个的时候,mybatis不会做特殊处理。

2.当传递多个参数的时候,mybatis会封装一个Map,当前map的key 默认是param1...paramN,取的时候使用key拿到value,也可以通过索引。可以在接口方法中使用@Param注解来直接封装map的key...如果多个参数的话推荐传入POJO,通过#{属性名}来取出。也可以直接在接口声明位置传入一个map集合。如果经常使用可以创建一个TO对象,封装数据信息。(transfer object)

public Employee getEmp(@Param("id")Integer id,String lastName);
	取值:id==>#{id/param1}   lastName==>#{param2}

public Employee getEmp(Integer id,@Param("e")Employee emp);
	取值:id==>#{param1}    lastName===>#{param2.lastName/e.lastName}

##特别注意:如果是Collection(List、Set)类型或者是数组,
		 也会特殊处理。也是把传入的list或者数组封装在map中。
			key:Collection(collection),如果是List还可以使用这个key(list)
				数组(array)
public Employee getEmpById(List<Integer> ids);
	取值:取出第一个id的值:   #{list[0]}

10.#{}与${}区别

#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;
大多情况下,我们去参数的值都应该去使用#{};
sql语句中不支持占位符 ( ? ) 的地方需要使用${}取值  比如orderby 排序。

11.集合数据的查询

方法的返回值类型为List嵌套实体类,select标签中resultType指定集合中对象的类型即可。

你可能感兴趣的:(框架)