JavaEE框架---Mybatis第一部分

1.Mabatis入门

 1.1Mybatis介绍

      MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

      MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

       Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

 1.2Mybatis架构

1.3Mybatis的配置

  1. mybatis配置
  •        SqlMapConfig.xml:此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
  •        mapper.xml:文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

  • 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
  • 由会话工厂创建sqlSession即会话,操作数据库需要通过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编程中对结果的解析处理过程。

1.4Mybatis的入门程序

1.4.1Mybatis的下载

mybaits的代码由github.com管理

下载地址:https://github.com/mybatis/mybatis-3/releases

  • mybatis-3.2.7压缩包

  • mybatis-3.2.7.jar        mybatis的核心包
  • lib文件夹                  mybatis的依赖包所在
  • mybatis-3.2.7.pdf       mybatis使用手册

1.4.2入门案例需求

  • 根据用户id查询一个用户
  • 根据用户名称模糊查询用户列表
  • 添加用户
  • 更新用户
  • 删除用户

1.4.3环境搭建

1.4.3.1创建包结构

1.4.3.2加入jar包

  • mybatis核心包

  • 依赖包

  • 数据驱动包。

完整:

1.4.4加入配置文件

日志:log4j.properties

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

# 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

核心配置文件:SqlMapConfig.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<!-- 是用resource属性加载外部配置文件=================== -->
	<properties resource="jdbc.properties">
		<!-- 在properties内部用property定义属性 -->
		<!-- 如果外部配置文件有该属性,则内部定义属性被外部属性覆盖 -->
		<!-- <property name="jdbc.username" value="root123" />
		<property name="jdbc.password" value="root123" /> -->
	</properties>
	
	<!-- 别名定义========================================= -->
	<typeAliases>
		<!-- 单个别名定义 -->
		<typeAlias alias="User" type="com.itheima.mybatis.pojo.User" />
		<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
		<package name="com.itheima.mybatis.pojo" />
		<package name="其它包" />
	</typeAliases>
	

	<!-- 和spring整合后 environments配置将废除 =====================-->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- Mapper的位置  Mapper.xml 写Sql语句的文件的位置================= -->
	<mappers>
		<!-- <mapper resource="sqlmap/User.xml"/>
		<mapper resource="com/itheima/mybatis/mapper/UserMapper.xml"/> -->
		
		<!-- 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 -->
		<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->
		
		<!-- 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 -->
		<package name="com.itheima.mybatis.mapper"/>
	</mappers>
	
</configuration>

jdbc.properties:数据库的基础配置文件

1.4.5创建pojo

pojo类作为mybatis进行sql映射使用,po类通常与数据库表对应,

1.4.6在核心配置文件中加载加载映射文件

1.4.7编写用户的映射文件

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

<!-- 写sql语句 -->

<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
<mapper namespace="test">
	<!-- id:statement的id 或者叫做sql的id-->
	<!-- parameterType:声明输入参数的类型 -->
	<!-- resultType:声明输出结果的类型,应该填写pojo的全路径 -->
	<!-- #{}:输入参数的占位符,相当于jdbc的? -->
	
	<!-- 根据用户ID查询用户 ==================-->
	<select id="findUserById" parameterType="Integer" resultType="com.itheima.mybatis.pojo.User">
		SELECT * FROM `user` WHERE id  = #{V}
	</select>
	
	<!--根据应户名模糊查询================================  
	#{}    select * from user where id = ?    占位符  ? ==  '五'
	${}    select * from user where username like '%五%'  字符串拼接
	-->
	<select id="findUserByUserName" parameterType="String" resultType="com.itheima.mybatis.pojo.User">
		SELECT * FROM `user` WHERE username like '%${value}%'
	</select>
	
	<!-- 保存用户 =============================-->
	<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" >
		<!-- selectKey 标签实现主键返回 -->
		<!-- keyColumn:主键对应的表中的哪一列 -->
		<!-- keyProperty:主键对应的pojo中的哪一个属性 -->
		<!-- order:设置在执行insert语句前执行查询id的sql,还是在执行insert语句之后执行查询id的sql -->
		<!-- resultType:设置返回的id的类型 -->
		<selectKey keyProperty="id" resultType="Integer" order="AFTER">
			select LAST_INSERT_ID()
		</selectKey>
		<!-- 使用UUID -->
		<!-- <selectKey keyProperty="id" resultType="String" order="BEFORE">
			select LAST_INSERT_ID()
		</selectKey>
		 -->
		insert into user (username,birthday,address,sex) 
		values (#{username},#{birthday},#{address},#{sex})
	</insert>
	
	<!-- 更新用户=========================== -->
	<update id="updateUserById" parameterType="com.itheima.mybatis.pojo.User">
		update user 
		set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
		where id = #{id}
	</update>
	
	<!-- 删除用户=============================== -->
	<delete id="deleteUserById" parameterType="Integer">
		delete from user where id=#{v}
	</delete>
	
</mapper>

1.4.8测试代码

/**
 * Mybatis入门程序
 */
public class MybatisDemo1 {

	//根据用户ID查询用户
	@Test
	public void demo1() throws IOException {
		
		//加载核心配置文件
		String resource="SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建sessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//执行语句
		User user = sqlSession.selectOne("test.findUserById", 10);
		System.out.println(user);
	}
	
	//根据用户名模糊查询用户
	@Test
	public void demo2() throws IOException {
		
		//加载核心配置文件
		String resource="SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建sessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//执行语句
		List<User> list = sqlSession.selectList("test.findUserByUserName", "五");
		for (User user2 : list) {
			System.out.println(user2);
		}  
	}
	//保存用户
	@Test
	public void demo3() throws IOException {
		
		//加载核心配置文件
		String resource="SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建sessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		//执行sql语句
		User user = new User();
		user.setUsername("宝强");
		user.setBirthday(new Date());
		user.setAddress("sadfsafsafs");
		user.setSex("男");
		sqlSession.insert("test.insertUser", user);
		//提交事务
		sqlSession.commit();
		System.err.println(user.getId());
	}
	
	//更新用户
	@Test
	public void demo4() throws IOException {
		
		//加载核心配置文件
		String resource="SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建sessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		//执行sql语句
		User user = new User();
		user.setId(28);
		user.setUsername("宝强2222222222222");
		user.setBirthday(new Date());
		user.setAddress("sadfsafsafs22222222");
		user.setSex("女");
		sqlSession.update("test.updateUserById", user);
		//提交事务
		sqlSession.commit();
	}
	
	//删除用户
	@Test
	public void demo5() throws IOException {
		
		//加载核心配置文件
		String resource="SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建sessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		//执行sql语句
		sqlSession.delete("test.deleteUserById", 28);
		//提交事务
		sqlSession.commit();
	}
	
}

总结:

一、#{}和${}:

  1. #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
  2. ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value

二、parameterType和resultType

  1. parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
  2. resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中。

三、mybatis与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需要具有很强的经验和能力才行。

总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。 

2.Mapper动态代理方式

2.1开发规范

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

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

2.2Mapper.xml(映射文件)

2.2.1定义mapper映射文件UserMapper.xml,将UserMapper.xml接口的目录下,效果如下:

2.2.2UserMapper.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">

<!-- 写sql语句 -->

<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
	<!-- id:statement的id 或者叫做sql的id-->
	<!-- parameterType:声明输入参数的类型 -->
	<!-- resultType:声明输出结果的类型,应该填写pojo的全路径 -->
	<!-- #{}:输入参数的占位符,相当于jdbc的? -->
	
	<!-- 根据用户ID查询用户 -->
	<select id="findUserById" parameterType="Integer" resultType="User">
		SELECT * FROM `user` WHERE id  = #{V}
	</select>
	
	<!--根据应户名模糊查询  
	#{}    select * from user where id = ?    占位符  ? ==  '五'
	${}    select * from user where username like '%五%'  字符串拼接
	-->
	<select id="findUserByUserName" parameterType="String" resultType="User">
		SELECT * FROM `user` WHERE username like '%${value}%'
	</select>
	
	<!-- 保存用户 -->
	<insert id="insertUser" parameterType="User" >
		<selectKey keyProperty="id" resultType="Integer" order="AFTER">
			select LAST_INSERT_ID()
		</selectKey>
		insert into user (username,birthday,address,sex) 
		values (#{username},#{birthday},#{address},#{sex})
	</insert>
	
	<!-- 更新用户 -->
	<update id="updateUserById" parameterType="User">
		update user 
		set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
		where id = #{id}
	</update>
	
	<!-- 删除用户 -->
	<delete id="deleteUserById" parameterType="Integer">
		delete from user where id=#{v}
	</delete>
	
</mapper>

2.3接口文件

2.4加载UserMapper.xml文件

修改SqlMapConfig.xml文件,添加以下所示的内容:

2.5测试代码

/**
 * 使用mapper的方式
 */
public class MybatisDemo2 {

	//根据id查询用户
	@Test
	public void demo1() throws IOException {
		//加载核心配置文件
		String resource = "SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
				
		//SqlSession帮我生成一个实 现类  (给接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
				
		User user = userMapper.findUserById(10);
		System.out.println(user);		
	}
	
	//根据用户名模糊查询用户
	@Test
	public void demo2() throws IOException {
		//加载核心配置文件
		String resource = "SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		//SqlSession帮我生成一个实 现类  (给接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		
		List<User> list = userMapper.findUserByUserName("五");
		for (User user2 : list) {
			System.out.println(user2);		
		}
	}
	//保存用户
	@Test
	public void demo3() throws IOException {
		//加载核心配置文件
		String resource = "SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		//SqlSession帮我生成一个实 现类  (给接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		
		//创建一个用户
		User user=new User();
		user.setAddress("东莞");
		user.setBirthday(new Date());
		user.setSex("男");
		user.setUsername("猪老三");
		
		userMapper.insertUser(user);
		sqlSession.commit();
		
		System.out.println(user.getId());
	}
	//保存用户
	@Test
	public void demo4() throws IOException {
		//加载核心配置文件
		String resource = "SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//SqlSession帮我生成一个实 现类  (给接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		
		//创建一个用户
		User user=new User();
		user.setAddress("东莞33333333333");
		user.setBirthday(new Date());
		user.setId(28);
		user.setSex("女");
		user.setUsername("猪老22222222三");
		
		userMapper.updateUserById(user);
		sqlSession.commit();
	}
	//删除用户
	@Test
	public void demo5() throws IOException {
		//加载核心配置文件
		String resource = "SqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//SqlSession帮我生成一个实 现类  (给接口)
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		
		userMapper.deleteUserById(28);
		sqlSession.commit();
	}
	
}

小结:

  • selectOne和selectList

动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

  • namespace

mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

2.6 SqlMapConfig.xml配置文件

2.6.1配置内容

SqlMapConfig.xml中配置的内容和顺序如下:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

SqlMapConfig.xml配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<!-- 是用resource属性加载外部配置文件=================== -->
	<properties resource="jdbc.properties">
		<!-- 在properties内部用property定义属性 -->
		<!-- 如果外部配置文件有该属性,则内部定义属性被外部属性覆盖 -->
		<!-- <property name="jdbc.username" value="root123" />
		<property name="jdbc.password" value="root123" /> -->
	</properties>
	
	<!-- 别名定义========================================= -->
	<typeAliases>
		<!-- 单个别名定义 -->
		<typeAlias alias="User" type="com.itheima.mybatis.pojo.User" />
		<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
		<!-- <package name="com.itheima.mybatis.pojo" />
		<package name="其它包" /> -->
	</typeAliases>
	

	<!-- 和spring整合后 environments配置将废除 =====================-->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- Mapper的位置  Mapper.xml 写Sql语句的文件的位置================= -->
	<mappers>
		<!-- <mapper resource="sqlmap/User.xml"/>-->
		<!-- <mapper resource="com/itheima/mybatis/mapper/UserMapper.xml"/>  -->
		
		<!-- 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 -->
		<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->
		
		<!-- 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 -->
		<package name="com.itheima.mybatis.mapper"/>
	</mappers>
	
</configuration>

2.6.2mybatis支持别名:

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

map

Map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值