Java三大框架之Mybatis

三大框架之Mybatis

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

Mybatis架构

Java三大框架之Mybatis_第1张图片

初步接触Mybatis

mybatis下载:mybaits的代码由github.com管理,Mybatis下载地址
导入jar包 :加入mybatis核心包、依赖包、数据驱动包。junit-4.9.jar这个包是为测试方便加入的
Java三大框架之Mybatis_第2张图片
创建配置文件 :在classpath下创建config目录(source folder类型)log4j.properties
Java三大框架之Mybatis_第3张图片

# 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

mybatis默认使用log4j作为输出日志信息。

第一个mybatis程序

在config下创建SqlMapConfig.xml




	
	
		
		
			
		
			
				
				
				
				
			
		
	

创建一个User实体类

private int id;
private String name;
private String password;
private String sex;
private int  age;

sql映射文件User.xml





namespace :命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。
**mybatis框架需要加载映射文件,将User.xml添加在SqlMapConfig.xm


		

在User.xml配置根据id获取用户信息


parameterType:
定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。resultType:定义结果映射类型。

测试程序(新建一个测试类)

public class MyTest {
	SqlSessionFactory ssf = null;
	@Before
	public void creatFactory(){
		InputStream input = null;
			try {
				input = Resources.getResourceAsStream("SqlMapConfig.xml");
			} catch (IOException e) {
				e.printStackTrace();
			}
		ssf = new SqlSessionFactoryBuilder().build(input);
	}
	/** 通过id查找*/
	@Test
	public void testFindUserById(){
		SqlSession session =ssf.openSession();
		//System.out.println(session);
		User user = session.selectOne("test.findUserById", 8);
		System.out.println(user);
		session.close();
	}
}

根据用户名查询


parameterType:定义输入到sql中的映射类型, v a l u e 表 示 使 用 参 数 将 {value}表示使用参数将 value使{value}替换,做字符串的拼接。
注意:如果是取简单数量类型的参数,括号中的值必须为value
resultType:定义结果映射类型。

测试代码

@Test
	public void testFindUserByName(){
		SqlSession session =ssf.openSession();
		
		List  userList = session.selectList("test.findUserByName", "xiao");
		System.out.println(userList);
		session.close();
	}

#{}和${}

#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。一般用在=之后。
表 示 拼 接 s q l 串 , 通 过 {}表示拼接sql串,通过 sql{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value。一般用在like之后。

5.6.2parameterType和resultType

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

5.6.3selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
selectList可以查询一条或多条记录

添加用户


	  insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
	
@Test
	public void testInsert() {
		// 数据库会话实例
		SqlSession sqlSession = null;
			// 创建数据库会话实例sqlSession
			sqlSession = sqlSessionFactory.openSession();
			// 添加用户信息
			User user = new User();
			user.setUsername("张小明");
			user.setAddress("河南郑州");
			user.setSex("1");
			user.setPrice(1999.9f);
			sqlSession.insert("test.insertUser", user);
			//提交事务
			sqlSession.commit();
			}

mysql自增主键返回

  1. 通过修改sql映射文件,可以将mysql自增主键返回

		
		
			select LAST_INSERT_ID()
		
	   insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address});
	
  1. 添加selectKey实现将主键返回

keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
resultType:返回的主键是什么类型
LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。

Mysql使用 uuid实现主键
需要增加通过select uuid()得到uuid值



	select uuid()

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

注意这里使用的order是“BEFORE”

删除用户

  1. 映射文件

	
		delete from user where id=#{id}
	
  1. 5.8.2测试程序
// 根据id删除用户
	@Test
	public void testDelete() {
		// 数据库会话实例
		SqlSession sqlSession = null;
			// 创建数据库会话实例sqlSession
			sqlSession = sqlSessionFactory.openSession();
			// 删除用户
			sqlSession.delete("test.deleteUserById",18);
			// 提交事务
			sqlSession.commit();
			sqlSession.close();
	}

修改用户

  1. 映射文件


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

  1. 测试程序
public void testUpdate() {
		// 数据库会话实例
		SqlSession sqlSession = null;
			// 创建数据库会话实例sqlSession
			sqlSession = sqlSessionFactory.openSession();
			// 添加用户信息
			User user = new User();
			user.setId(16);
			user.setUsername("张小明");
			user.setAddress("河南郑州");
			user.setSex("1");
			user.setPrice(1999.9f);
			sqlSession.update("test.updateUser", user);
			// 提交事务
			sqlSession.commit();
			sqlSession.close();
		}

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定义输出结果的类型。

你可能感兴趣的:(Mybatis,Java)