Mybaits框架_day02

输入映射和输出映射

 了解概念  

POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其getter setter方法的类,没有业务逻辑,有时可以作为VO(value -object)或dto(Data Transform Object)来使用.当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也不能携带有connection之类的方法。


EJB是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序。简单来说就是把已经编写好的程序(即:类)打包放在服务器上执行。凭借java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台。EJB (Enterprise JavaBean)是J2EE(javaEE)的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。 在J2EE里,Enterprise Java Beans(EJB)称为Java 企业Bean,是Java的核心代码,分别是会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。在EJB3.0推出以后,实体Bean被单独分了出来,形成了新的规范JPA

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。[1] 
Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。


输入参数值POJO包装类

java 序列化的概念

 什么是序列化, ?  在java中,如果我在我自己的电脑上封装一个对象,然后存入内存中,这个过程叫做对象的序列化

如果我把对象发送给了张三,然后对象通过网路,存入了张三的内存中,如果张三使用和调用这个对象,就要实现java的反序列化

远程OBC调用,就要用到序列化, 牵扯到集群(多台电脑),

包装类必须实现 序列化接口

   所谓的Serializable,就是java提供的通用数据保存和读取的接口。至于从什么地方读出来和保存到哪里
去都被隐藏在函数参数的背后了。这样子,任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送
到别的地方。也可以用管道来传输到系统的其他程序中。这样子极大的简化了类的设计。只要设计一个保存一个读取功能就能解决上面说得
所有问题。

      java的"对象序列化"能让你将一个实现了Serializable接口的对象转换成一组byte,这样日后要用这个对象时候,你就能把这些byte数
据恢复出来,并据此重新构建那个对象了。

      工作流当中流程变量的几种数据类型:string integer short long double boolean date binary serializable,这就是为什么要将
javabean实现序列化的原因,因为你将对象设置到流程变量中必须要实现序列化,否则会在设置流程变量的时候报错找不到该类型

      java对象序列化机制就是把内存中的Java对象(User之类的JavaBean)转换成二进制流。java对象序列化后可以很方便的存储或者在网络
中传输。Java的序列化机制是通过运行时判断类的序列化ID(serialVersionUID)来判定版本的一致性。在反序列化时,java虚拟机会通过二
进制流中的serialVersionUID与本地的对应的实体类进行比较,如果相同就认为是一致的,可以进行反序列化,正确获得信息,否则抛出序列
化版本不一致的异常。所以涉及到数据传输或者存储的类,严格意义上来说都要加上序列化ID,这也是一种良好的编程习惯。

序列号的意义 :     private static final long serialVersionUID = 1L;

serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

 代码

创建包装类

package com.itheima.mybatis.pojo;

import java.io.Serializable;

public class QueryVo implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private User user  ;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	} 
	
	
	
	
}

配置sqlmap .xml 配置文件

  <!-- 通过包装类进行模糊查询   这里的参数用ogl 表达式-->
	<select id="findUserByQueryVo"  parameterType="com.itheima.mybatis.pojo.QueryVo" resultType="com.itheima.mybatis.pojo.User">
		select * from user where username like "%"#{user.username}"%" 
	</select> 

junit 测试

@Test
	public  void testfindUserByQueryVo(){
		// 0. 记载配置文件
		InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml"); 
		// 1. 创建sessionFactory 工厂类
		SqlSessionFactory  sf = new SqlSessionFactoryBuilder().build(in); 
		// 打开session 
		SqlSession session = sf.openSession();
		// 执行sql 语句
		Usermapper mapper = session.getMapper(Usermapper.class); 
		QueryVo queryVo = new QueryVo()  ; 
		User user = new User()  ;
		user.setUsername("五");
		queryVo.setUser(user);
		List<User> list = mapper.findUserByQueryVo(queryVo) ; 
		System.out.println(list);
	}
输出参数之简单类型

接口中定义

public Integer findCount(); 

写sqlmap.xml 配置文件

	<select id="findCount" resultType="Integer">
		select count(*) from user; 
	</select>

测试

	@Test
	public  void testfindCount(){
		// 0. 记载配置文件
		InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml"); 
		// 1. 创建sessionFactory 工厂类
		SqlSessionFactory  sf = new SqlSessionFactoryBuilder().build(in); 
		// 打开session 
		SqlSession session = sf.openSession();
		// 执行sql 语句
		Usermapper mapper = session.getMapper(Usermapper.class); 
		Integer jj = mapper.findCount() ; 
		System.out.println(jj);
	}
输出类型resultMap
  <resultMap type="Orders" id="orders">
	  	<!-- 只配置不一样的就行了 -->
	  	<result column="user_id" property="userId"/>
	  </resultMap>
	  
	  <select id="selectOrdersList" resultMap="orders">
	  		SELECT id, user_id, number, createtime, note FROM orders 
	  </select>

动态sql


if  where 

<select id="findUserBySexAndUsername" parameterType="User" resultType="User">
		select * from user 
	 <where> 
		 	<if test="sex!=null and sex!=''">
		 		 and sex=#{sex} 
		 	</if>
		 	<if test="username != null and username != ''">
			 	 and username=#{username}
		 	</if>
	 </where> 
	</select>

@Test
	public  void testfindUserBySexAndUsername(){
		// 0. 记载配置文件
		InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml"); 
		// 1. 创建sessionFactory 工厂类
		SqlSessionFactory  sf = new SqlSessionFactoryBuilder().build(in); 
		// 打开session 
		SqlSession session = sf.openSession();
		// 执行sql 语句
		Usermapper mapper = session.getMapper(Usermapper.class); 
		User u = new User() ; 
		u.setSex("1");
		u.setUsername("eric");
		List<User> users = mapper.findUserBySexAndUsername(u); 
		for (User user : users) {
			
			System.out.println(user);
		}
	}
where 标签取出前边的and

sql片段

多吃出现相同的sql 标签片段, 使用这个方法

<!-- sql片段 -->
	<sql id="selectto">
		select * from  user 
	</sql>
<!--	根据性别和名字查询用户  where 可以去掉第一个前ANd   -->
	<select id="findUserBySexAndUsername" parameterType="User" resultType="User">
		<include refid="selectto"></include>
	 <where> 
		 	<if test="sex!=null and sex!=''">
		 		 and sex=#{sex} 
		 	</if>
		 	<if test="username != null and username != ''">
			 	 and username=#{username}
		 	</if>
	 </where> 
	</select>

Foreach

        list

	<!-- 通过id 查询多个用户 -->
	<select id="findUserByIDs" parameterType="QueryVo" resultType="User">
		<include refid="selectto"></include>
		<where>
		<foreach collection="idList" item="id" open="id in("  close=")" separator="," > 	
			#{id}
		</foreach>
		</where>
	</select>	
	
	public List<User> findUserByIDs(QueryVo v); 
@Test
	public  void testfindByDIs(){
		// 0. 记载配置文件
		InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml"); 
		// 1. 创建sessionFactory 工厂类
		SqlSessionFactory  sf = new SqlSessionFactoryBuilder().build(in); 
		// 打开session 
		SqlSession session = sf.openSession();
		// 执行sql 语句
		Usermapper mapper = session.getMapper(Usermapper.class); 
		List<Integer> list = new ArrayList<Integer>() ; 
		
		list.add(1); 
		list.add(16); 
		list.add(26); 
		QueryVo vo = new QueryVo(); 
		vo.setIdList(list); 
		List<User> users = mapper.findUserByIDs(vo); 
		for (User user : users) {
			System.out.println(user);
			
		}
    Array
	<!-- 通过id 查询多个用户 -->
	<select id="findUserByIDs" parameterType="QueryVo" resultType="User">
		<include refid="selectto"></include>
		<where>
		<foreach collection="array" item="id" open="id in("  close=")" separator="," > 	
			#{id}
		</foreach>
		</where>
	</select>	

这里的 Collection 一定要用array 

一对一关联

这里我们拿 user 和order 表进行举例说明  :

一个用户可以又多个订单    many-to-many

但是一个订单只能是一个人   one-to-one

xml result  不可以省略在多表查询中, 

	//一对一关联 查询  以订单为中心 关联用户
	public List<Orders> selectOrders();
	 -->
	 <resultMap type="Orders" id="order">
	 	<result column="id" property="id"/>
	 	<result column="user_id" property="userId"/>
	 	<result column="number" property="number"/>
	 	<result column="createtime" property="createtime"/>
	 	<result column="note" property="note"/>
	 	<!-- 一对一 -->
	 	<association property="user" javaType="User">
	 		<id column="user_id" property="id"/>
	 		<result column="username" property="username"/>
	 	</association>
	 </resultMap>
	 <select id="selectOrders" resultMap="order">
	 	SELECT 
	 	o.id,
	    o.user_id, 
	    o.number,
	 	o.createtime,
	 	u.username 
	 	FROM orders o 
	 	left join user u 
	 	on o.user_id = u.id
	 </select>
	 

多对多  (one-to-many)

xml配置文件如下

  <resultMap type="User" id="user">
		<id column="user_id" property="id"/>
		<result column="username" property="username"/>
		<collection property="ordersList" ofType="Orders">
			<id column="user_id" property="id"/>
		<result column="number" property="number"/>
		</collection> 	
	  </resultMap>
	  
	  
	  
	  <!-- 一对多查询 -->
	<select id="selectUserList" resultMap="user">
		SELECT  
		u.id,u.address,u.birthday,u.sex,u.username,o.createtime,o.user_id
		FROM USER u LEFT JOIN orders o 
		ON o.user_id= u.id; 
	</select>

一对一的话, 直接引用对方的 对象 

如果是many-to-one 的话,用带有对方泛型的 集合引用 

多的一方用集合

Mybatis 整合Spring 

这里我们要明白, 不管是 hibernate 还是mybatis 中的sessionFactory 都是单实例 的,也就是说只有一个工厂, 但是session不能是但实例的, session 要多实例, 与线程绑定

我们整合就是让sessionFactory 交给spring 进行创建session 管理 维护session 对象 ,所谓的dao层的框架和spring 结合其实都是把ssessionFactory 和session 的创建交给spring 容器管理 ,

整合思想

 1 .sqlsessionFactory  对象,应该放在spring 容器中作为单实例存在

2. 从spring 中获取多实例的 sqlsession 对象

3 .mapper 代理形式中,应该从spring 容器中获取mapper 对象,

4.数据库的链接以及事务的管理都交给spring 容器完成

Mybatis Mapper 动态代理开发

mapper 工厂创建 接口的实现类, 在spring 中,

	<!-- Mapper动态代理开发 -->
	<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
		<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
		<property name="mapperInterface" value="com.itheima.mybatis.mapper.UserMapper"/>
	</bean>

需要传递session 工厂和,接口

配置文件的书写和之前的mybatis 一样

@Test
	public void test() {
		// 加载spring 容器配置文件
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 
		UserMapper uMapper = ac.getBean(UserMapper.class); 
		User user= uMapper.findUserById(29); 
		System.out.println(user);
		
	}
直接扫描包
	 <!--  上面的是要一个一个接口 -->
	<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 会自动扫面mapper包下的接口和子 包下的接口 -->
		<property name="basePackage" value="com.itheima.mybatis.mapper"></property>
	</bean>
	
Mybatis 逆向工程

1. 下载逆向工程软件, 直接从网上下载就行了, generatorSqlmapCustom 这是这个名字,

2. 配置文件配置   注意  :

这里配置文件的路径一定要写对, 不然麻烦很大

3. 直接把生成的代码 进行cope 就行了

4.书写test测试类进行测试

	/**
	 * 用带条件的 bean  进行操作数据库
	 */
	@Test
	public void test2(){
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 
		UserMapper uMapper = ac.getBean(UserMapper.class); 
		// 创建 OrderExample 
		UserExample example  = new UserExample(); 
		// 创建条件
		example.createCriteria().andSexEqualTo("1"); 
		int co = uMapper.countByExample(example); 
		System.out.println("报告大王一共有:"+co);
	}
	
	
	/**
	 * 多个条件的 
	 */
	@Test
	public void test3(){
		ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 
		UserMapper uMapper = ac.getBean(UserMapper.class); 
		// 创建 OrderExample 
		UserExample example  = new UserExample(); 
		// 创建条件
		String username= "明";  
		example.createCriteria().andSexEqualTo("1").andUsernameLike("%"+username+"%"); 
		
		example.setOrderByClause("id desc");   /*排序 */
		int co = uMapper.countByExample(example); 
		System.out.println("报告大王一共有:"+co);
		
		
		/*通过条件*/
		List<User> users = uMapper.selectByExample(example); 
		for (User user : users) {
			System.out.println(user.getId());
		}
		
		
		

生成的 user  和 userExample   userExample 就是添加条件的pojo 对象, 具体的操纵方法很简单, 自己想想就知道了, 参考上文

























猜你喜欢

转载自blog.csdn.net/qq_39148187/article/details/80000847