mybatis学习笔记(二)

目录

 

一、输入映射和输出映射

1.1 输入映射

1.2 resultType(输出类型)

二、动态sql

2.1 if标签

2.2 where标签

2.3 foreach标签

2.4 Sql片段

三、整合spring

3.1 整合思路

3.2 整合所需要的jar包

3.3 创建工程

四、总结


一、输入映射和输出映射

1.1 输入映射

1.1.1 传递简单类型

使用#{}占位符,或者用${}进行sql拼接。

1.1.2 传递pojo对象

mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

1.1.3 传递pojo包装对象

开发中通过可以使用pojo传递查询条件。

查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

包装对象:Pojo类中的一个属性是另外一个pojo。

需求:根据用户名模糊查询用户信息,查询条件放到QueryVo的user属性中。

编写QueryVo

package com.baidu.domain;

public class QueryVo {

	private User user;

	public User getUser() {
		return user;
	}

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

UserMapper.xml中添加如下内容

<select id="getUserByQueryVo" parameterType="QueryVo" resultType="User">
	select* from users where name like '%${user.name}%'
</select>

关键代码:

SqlSession session = sessionFactory.openSession();        
                                                          
UserMapper mapper = session.getMapper(UserMapper.class);  
User user = new User();                                   
user.setName("1");                                        
QueryVo vo = new QueryVo();                               
vo.setUser(user);      
                                   
System.out.println(mapper.getUserByQueryVo(vo));          
session.close();                                          

执行结果

1.1.4 传递其他映射类型

<select id="getUserCount" parameterMap="getUserCountMap" statementType="CALLABLE">
	CALL mybatis.ges_user_count(?, ?)                                             
</select>                                                                         
  参数类型为map,调用存储过程                                                                                
<parameterMap type="java.util.Map" id="getUserCountMap">                          
	<parameter property="sexid" mode="IN" jdbcType="INTEGER"/>                    
	<parameter property="usercount" mode="OUT" jdbcType="INTEGER"/>               
</parameterMap>                                                                   

关键代码

String sql = "com.baidu.mapper.UserMapper.getUserCount";          
Map<String,Integer> paramterMap = new  HashMap<String, Integer>();
paramterMap.put("sexid", 1);                                      
paramterMap.put("usercount", -1);                                 
sqlSession.selectOne(sql, paramterMap);                           
Integer result = paramterMap.get("usercount");                    
sqlSession.close();                                               
System.out.println(result);                                       

1.2 resultType(输出类型)

可以输出简单类型,pojo对象,pojo列表,参考上一篇内容。

1.2.1 resultMap(输出类型映射)

resultMap可以将查询结果映射为指定类型,但是需要pojo的属性名和sql查询的列明保持一致方可映射成功,如果不一致,可以通过resultMap将字段名和属性名作为一个对应关系,还可以通过配置将结果映射为复杂类型的,比如一对一和一对多查询。

创建class、student表和teacher表

添加相关类

package com.baidu.domain;

public class Student {

	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString(){
		return "Student [id=" + id + ", name=" + name + "]";
	}
}


package com.baidu.domain;

import java.util.List;

public class Classes {
	private int id;
	private String name;
	
	private Teacher teacher;
	private List<Student> students;
	
	public List<Student> getStudents() {
		return students;
	}

	public void setStudents(List<Student> students) {
		this.students = students;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Teacher getTeacher() {
		return teacher;
	}

	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	
	@Override
	public String toString(){
		return "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher+ ",students"+students+"]";
	}
}
package com.baidu.domain;

public class Teacher {

	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString(){
		return "Teacher [id=" + id + ", name=" + name + "]";
	}
}

添加ClassMapper.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">

<!-- 
	为这个mapper 指定一个唯一的namespace,习惯上设置成包名+sql映射文件名,这样就能够保持唯一了
 -->
<mapper namespace="com.baidu.mapper.ClassMapper">
	<select id="getClass" parameterType="int" resultMap="ClassResultMap">
		select * from class c,teacher t where c.teacher_id = t.t_id and c.c_id = #{id}
	</select>
	
	<resultMap type="com.baidu.domain.Classes" id="ClassResultMap">
		<id property="id" column="c_id" />
		<result property="name" column="c_name"/>
		<association property="teacher" javaType="com.baidu.domain.Teacher" >
			<id property="id" column="t_id" />
			<result property="name" column="t_name"/>
		</association>
	</resultMap>	
	
	<select id="getClassStudents" parameterType="int" resultMap="ClassStudentsResultMap">
	 	select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
	</select>
	<resultMap type="com.baidu.domain.Classes" id="ClassStudentsResultMap">
		<id property="id" column="c_id"/>
		<result property="name" column="c_name"/>
		<association property="teacher" column="teacher_id" javaType="com.baidu.domain.Teacher">
			<id property="id" column="t_id"/>
			<result property="name" column="t_name"/>
		</association>
		
		<collection property="students" ofType="com.baidu.domain.Student">
			<id property="id" column="s_id"/>
			<result property="name" column="s_name"/>
		</collection>
	</resultMap>
	
</mapper>

这个是一对一(一个班级对应一个老师)和一对多(一个班级对应多个学生)的查询

其中getClass返回的结果集比较复杂,所有resultMap要重新定义一个新的结果集映射,这里设置为ClassResultMap

添加一个resultMap,id为ClassResultMap,与上边的结果对应,type类型为我们的javabean的Classes
<resultMap type="com.baidu.domain.Classes" id="ClassResultMap">
            实体的id属性property对应sql查出列c_id,用id标签映射主键
		<id property="id" column="c_id" />
            用result标签映射其他属性,对象的属性名name映射查出来的列c_name
		<result property="name" column="c_name"/>
            关联属性teacher映射
		<association property="teacher" javaType="com.baidu.domain.Teacher" >
			<id property="id" column="t_id" />
			<result property="name" column="t_name"/>
		</association>
</resultMap>	

getClassStudent来映射一对多的集合

	<select id="getClassStudents" parameterType="int" resultMap="ClassStudentsResultMap">
	 	select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
	</select>
	<resultMap type="com.baidu.domain.Classes" id="ClassStudentsResultMap">
		<id property="id" column="c_id"/>
		<result property="name" column="c_name"/>
		<association property="teacher" column="teacher_id" javaType="com.baidu.domain.Teacher">
			<id property="id" column="t_id"/>
			<result property="name" column="t_name"/>
		</association>
		学生集合属性映射
		<collection property="students" ofType="com.baidu.domain.Student">
			<id property="id" column="s_id"/>
			<result property="name" column="s_name"/>
		</collection>
	</resultMap>

二、动态sql

通过mybatis提供的各种标签实现动态拼接sql

需求 根据年龄或者姓名查询用户,如果有年龄就根据年龄,如果有名字就根据名字

2.1 if标签

UserMapper.xml中添加如下select标签

<select id="getUserByNameOrAge" parameterType="User" resultType="User">
	SELECT id, name,age FROM `user`                                    
	WHERE 1=1                                                          
	<if test="age != null and age != ''">                              
		AND age = #{age}                                               
	</if>                                                              
	<if test="name != null and name != ''">                            
		AND name LIKE                                                  
		'%${name}%'                                                    
	</if>                                                              
</select>                                                              

关键代码

SqlSession session = sessionFactory.openSession();        
UserMapper mapper = session.getMapper(UserMapper.class);  
User user = new User();                                   
user.setAge(23);                                          
//user.setName("张");                                      
System.out.println(mapper.getUserByNameOrAge(user));      

当设置name或者不设置name的时候结果是不一样的,就满足了我们的需求。

2.2 where标签

上边的sql有where 1=1 这样的语句 感觉很别扭麻烦,我们可以使用where标签进行改造

<select id="getUserByNameOrAge" parameterType="User" resultType="User">  
	SELECT id, name,age FROM `user`                                      
	<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->                      
	<where>                                                              
		<if test="age != null and age != ''">                            
			AND age = #{age}                                             
		</if>                                                            
		<if test="name != null and name != ''">                          
			AND name LIKE                                                
			'%${name}%'                                                  
		</if>                                                            
	</where>	                                                         
</select>                                                                

2.3 foreach标签

向sql传递数组或者List,mybatis使用foreach解析,如根据多个id查询用户信息的时候  SELECT * FROM user WHERE id IN (1,10,24),我们改造QueryVo

package com.baidu.domain;

import java.util.List;

public class QueryVo {

	private User user;

	private List<Integer> ids;
	
	public List<Integer> getIds() {
		return ids;
	}

	public void setIds(List<Integer> ids) {
		this.ids = ids;
	}

	public User getUser() {
		return user;
	}

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

UserMapper.xml添加如下标签

<select id="getUserByQueryVo" parameterType="QueryVo" resultType="User">  
	SELECT * FROM `user`                                                  
	<where>                                                               
		<!-- foreach标签,进行遍历 -->                                           
		<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->                        
		<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->                         
		<!-- open:在前面添加的sql片段 -->                                         
		<!-- close:在结尾处添加的sql片段 -->                                       
		<!-- separator:指定遍历的元素之间使用的分隔符 -->                                
		<foreach collection="ids" item="item" open="id IN (" close=")"    
			separator=",">                                                
			#{item}                                                       
		</foreach>                                                        
	</where>                                                              
                                                                          
</select>                                                                 

关键代码

SqlSession session = sessionFactory.openSession();      
UserMapper mapper = session.getMapper(UserMapper.class);
QueryVo vo = new QueryVo();                             
List<Integer> ids = new ArrayList<Integer>();           
ids.add(1);                                             
ids.add(3);                                             
ids.add(4);                                             
vo.setIds(ids);                                         
System.out.println(mapper.getUserByQueryVo(vo));        

2.4 Sql片段

sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。可以把上边例子中的id,name,age提取出来,作为sql片段

<select id="getUserByNameOrAge" parameterType="User" resultType="User">  
	SELECT <include refid="userFields" /> FROM `user`                    
	<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->                      
	<where>                                                              
		<if test="age != null and age != ''">                            
			AND age = #{age}                                             
		</if>                                                            
		<if test="name != null and name != ''">                          
			AND name LIKE                                                
			'%${name}%'                                                  
		</if>                                                            
	</where>	                                                         
</select>                                                                
                                                                         
<!-- 声明sql片段 -->                                                         
<sql id="userFields">                                                    
	id, name, age                                                        
</sql>                                                                   

三、整合spring

3.1 整合思路

1.SqlSessionFactory对象应该放到spring容器中作为单例存在。

2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象。

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

4.数据库的连接一级数据库连接池事务管理都交给spring容易来完成。

3.2 整合所需要的jar包

3.3 创建工程

3.3.1 创建一个web工程

添加一个source folder config,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>
	<!-- 设置别名 -->
	<typeAliases>
		<!-- 2. 指定扫描包,会把包内所有的类都设置别名,别名的名称就是类名,大小写不敏感 -->
		<package name="cn.itcast.pojo" />
	</typeAliases>
</configuration>

添加applicatinContext.xml 是spring的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties" />

	<!-- 数据库连接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive" value="10" />
		<property name="maxIdle" value="5" />
	</bean>

	<!-- 配置SqlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 配置mybatis核心配置文件 -->
		<property name="configLocation" value="classpath:SqlMapConfig.xml" />
		<!-- 配置数据源 -->
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<!-- Mapper代理的方式开发方式二,扫描包方式配置代理 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 配置Mapper接口 -->
		<property name="basePackage" value="cn.itcast.mapper" />
	</bean>
	
</beans>

添加db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

添加log4j.properties

# 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

配置文件的最终效果

添加mapper.xml

package cn.itcast.mapper;

import cn.itcast.pojo.User;

public interface UserMapper {
	
	User getUser(int id);

	void saveUser(User user);
	
	void updateUserById(int id);
	
	void deleteUserById(int id);
	
}
<?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">

<!-- 
	为这个mapper 指定一个唯一的namespace,习惯上设置成包名+sql映射文件名,这样就能够保持唯一了
 -->
<mapper namespace="cn.itcast.mapper.UserMapper">
	<select id="getUser" parameterType="int" resultType="User">
		select* from user where id = #{id}
	</select>
	
	<!-- 保存用户 -->
	<insert id="saveUser" parameterType="User">
		INSERT INTO `user`
		(name,age) VALUES
		(#{name},#{age})
	</insert>
	
	<!-- 更新用户 -->
	<update id="updateUserById" parameterType="User">
		UPDATE `user` SET
		name = #{name},age = #{age} WHERE id = #{id}
	</update>
	
	<!-- 删除用户 -->
	<delete id="deleteUserById" parameterType="int">
		delete from user where
		id=#{id}
	</delete>
	
	
</mapper>

关键测试代码

package cn.itcast.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.itcast.mapper.UserMapper;
import cn.itcast.pojo.User;

public class TestMain {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		UserMapper userMapper = context.getBean(UserMapper.class);
		User user = userMapper.getUser(1);
		System.out.println(user);
	}
}

四、总结

整合之后我们的开发就方便的多,开发和维护起来都很方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值