Mapper动态代理:
Mapper接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
通过mapper代理模式:
创建的usermapper接口:有四个原则: 采用mapper动态代理的方式开发时使用,在namespace中指定mapper的类路径。 同时要遵循以下原则:
1.id与接口中的方法名一致;2.输入参数类型一致,3.返回类型一致
4。在namaspace中指定mapp类路径
接口中需要声明的方法和映射的id相同,参数,返回值,配置文件
package com.leo.mapper;
/**
* mapper动态代理
* @author leoi555
*
*/
import java.util.List;
import com.leo.domain.QueryVo;
import com.leo.domain.User;
public interface UserMapper {
//遵循四个原则
//接口方法名==user.xml中的id名
//返回类型要与map.xml返回一致
//参数类型也要一致
//在配置的xml文件namspace要写这个类名
public User selectid(Integer id);
public User selectlist(String username);
//通过
public List<User> findUserByQueryVo(QueryVo vo);
//根据性别和名字查询用户
public List<User> selectUserBysexAndname(User user);
//根据多个id来查询:通过数组,通过list,通过代理的对象
public List<User> selectUserByIdsByInteger(Integer[] ids);
public List<User> selectUserByIdsByList(List<Integer> ids);
public List<User> selectUserByIdsByQueryVo(QueryVo ids);
}
<?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="com.leo.mapper.OrderMapper">
<select id="listOrder" resultType="com.leo.domain.Orders">
select id,user_id,number,createtime,note from orders
</select>
<!-- 使用Map -->
<resultMap type="com.leo.domain.Orders" id="myMap">
<!-- 这个字段映射到哪个类型-->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
</resultMap>
<select id="listOrderByMap" resultMap="myMap">
select id,user_id,number,createtime,note from orders
</select>
</mapper>
输入参数类型parameterType:
1.基本类型:
parameterType="Integer" ,String,double,...八大基本数据类型
<select id="selectid" parameterType="Integer" resultType="com.leo.domain.User">
select * from user where id= #{v}
</select>
2.pojo类型:
<!-- 添加
<selectKey>是获得当前的id
select Last_INSERT_ID():mysql提供的
keyProperty="id" :返回值放到的user中id属性
resultType="Integer" ,id的属性是
order="AFTER":主键自增的mysql为after,oracle是before
-->
<insert id="insertuser" parameterType="com.leo.domain.User">
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select Last_INSERT_ID()
</selectKey>
insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 修改操作 -->
<update id="updateuser" parameterType="com.leo.domain.User">
update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address}
where=#{id}
</update>
<!-- 删除 -->
<delete id="deleteUser" parameterType="Integer">
delete from user where id=#{id}
</delete>
3.带有包装类型的即一个类中引入了另一个类:
通过mapper代理模式:
创建的usermapper接口:有四个原则:
采用mapper动态代理的方式开发时使用,在namespace中指定mapper的类路径:
同时要遵循以下原则:
1.id与接口中的方法名一致;2.输入参数类型一致,3.返回类型一致
4。在namaspace中指定mapp类路径
在接口中声明:
public List<User> findUserByQueryVo(QueryVo vo);
包装类:
public class QueryVo implements Serializable{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
配置映射文件:
<?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">
<!-- namespace,命名空间用于隔离SQL,防止出现在id相同的xml文件
2.采用mapper动态代理的方式开发时使用,在namespace中指定mapper的类路径:
同时要遵循以下原则:
1.id与接口中的方法名一致;2.参数类型一致,3.返回类型一致
-->
<mapper namespace="com.leo.mapper.UserMapper">
<!-- 根据包装对象类型进行查询,这里的输入参数为对象类型要全路径,你所使用的参数是user对象中的所以要近一步的调用 -->
<select id="findUserByQueryVo" parameterType="com.leo.domain.QueryVo" resultType="com.leo.domain.User">
select * from user where username like "%"#{user.username}"%"
</select>
</mapper>
测试:
@Test
public void test1() throws IOException {
// TODO Auto-generated method stub
//加载核心配置文件
String resource="sqlMapConfig2.xml";
InputStream in= Resources.getResourceAsStream(resource);
//创建SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过代理mapper获取,sqlsession生成接口的实现类
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
QueryVo vo=new QueryVo();
User user=new User();
user.setUsername("明");
vo.setUser(user);
List<User> list=mapper.findUserByQueryVo(vo);
for(User u:list) {
System.out.println(u);
}
}
输出参数类型
1.resultType:
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
使用别名:
<typeAlias type="com.leo.domainl.User" alias="User"/>
<!-- In SQL Mapping XML file -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
返回自增的主键
<selectKey>是获得当前的id
select Last_INSERT_ID():mysql提供的
keyProperty="id" :返回值放到的user中id属性
resultType="Integer" ,id的属性是
order="AFTER":主键自增的mysql为after,oracle是before
直接返回封装后的pojo
<!-- 模糊查询用户
#{}表示的为占位符。占位符?两边已经加上过''后了,,#{}括号内可以为任意字符
也可用"%"#{value}"%"可以防止sql注入
${}字符串拼接,${}两边必须加上'',中间只能为{value}
-->
<select id="selectlist" parameterType="String" resultType="com.leo.domain.User">
select * from user where username like '%${value}%'
</select>
2.resultMap:
sql查询的字段名和你pojo类型字段不一致的情况下用 resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询
<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->
<!-- id:设置ResultMap的id -->
<resultMap type="order" id="orderResultMap">
<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
<!-- property:主键在pojo中的属性名 -->
<!-- column:主键在数据库中的列名 -->
<id property="id" column="id" />
<!-- 定义普通属性 -->
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</resultMap>
例子:
同样可以使用mapper代理模式
<!-- 使用Map ;先使用resultMap标签 中的id 对相应的是执行语句返回的resultMap
在标签内使用的column是对应的数据库的属性,property指的是映射到的对象中的属性值
可以只写子段名与数据库名不一致的子段,其他相同的字段mybatis会进行自动化得装配
-->
<mapper namespace="com.leo.mapper.OrderMapper">
<resultMap type="com.leo.domain.Orders" id="myMap">
<!-- 这个字段映射到哪个类型-->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
</resultMap>
<select id="listOrderByMap" resultMap="myMap">
select id,user_id,number,createtime,note from orders
</select>
</mapper>
标签:
sql:提取相同的sql语句 用的时候方法:<include refid="id">就可以;
where:条件用时要把条件包含到里面
if:判断一些字段
<!-- 提取相同的sql语句 用的时候方法:<include refid="id">就可以 -->
<sql id="selectsql1" >
select *from user
</sql>
<!-- 直接把条件包含到<where>标签,多条件中间用and连接-->
<select id="selectUserBysexAndname" parameterType="com.leo.domain.User" resultType="com.leo.domain.User">
<!-- 引入sql片段 -->
<include refid="selectsql1"></include>
<where>
<if test="sex !=null and sex!='' ">
sex=#{sex}
</if>
<if test="username != null and username!='' ">
and username=#{username}
</if>
</where>
</select>
foreach:
接口中的
//根据多个id来查询:通过数组,通过list,通过代理的对象
public List<User> selectUserByIdsByInteger(Integer[] ids);
public List<User> selectUserByIdsByList(List<Integer> ids);
public List<User> selectUserByIdsByQueryVo(QueryVo ids);
<!-- 用代理的 要代理的是对类型的引用必须和这里的collection的引用必须一致-->
<select id="selectUserByIdsByQueryVo" parameterType="com.leo.domain.QueryVo" resultType="com.leo.domain.User">
<!-- 引入sql片段 -->
<include refid="selectsql1"></include>
<where>
<!-- id in 1,2,3-->
<foreach collection="list" item='id' separator="," open="id in (" close=")">
#{id}
</foreach>
</where>
</select>
<!-- 用数组的形式没有用自己设置的对象而是直接用collection=array 不用自己设置的字段 -->
<select id="selectUserByIdsByInteger" parameterType="com.leo.domain.QueryVo" resultType="com.leo.domain.User">
<!-- 引入sql片段 -->
<include refid="selectsql1"></include>
<where>
<!-- id in 1,2,3-->
<foreach collection="array" item='id' separator="," open="id in (" close=")">
#{id}
</foreach>
</where>
</select>
<!-- 用list 中 collection="list" 未与其他字段相对应,只是书写为list即可 -->
<select id="selectUserByIdsByList" parameterType="com.leo.domain.QueryVo" resultType="com.leo.domain.User">
<!-- 引入sql片段 -->
<include refid="selectsql1"></include>
<where>
<!-- id in 1,2,3-->
<foreach collection="list" item='id' separator="," open="id in (" close=")">
#{id}
</foreach>
</where>
</select>