序号 | Mybatis | hibernate |
---|---|---|
iBatis SSI 2002年诞生 Cliton begin | 2001年 Given King | |
2010年5月由apache投奔google | Jboss,apache | |
基于SQL 面向结果集 | 基于面向对象 HQL | |
效率高 | 效率低 | |
SqlSessionFactory | SessionFactory | |
SqlSession | Session | |
sqlMapConfig.xml | Hibernate.cfg.xml | |
userMapper.xml | 映射文件 user.hbm.xml |
Hibernate面向对象,它使用HQL,可以无需写SQL语句。全自动ORM。
Mybatis面向对象,它使用SQL语句,很依赖于SQL语句。半自动ORM。
1、 mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、 mybatis底层自定义了Executor接口操作数据库,Executor接口有两个实现,一个是基本实现、一个是缓存实现。
5、 Mapped Statement也是mybatis一个底层对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
使用eclipse创建java工程,jdk使用1.6。
加入mybatis核心包、依赖包、数据驱动包。
在classpath下创建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
mybatis默认使用log4j作为输出日志信息。
在classpath下创建SqlMapConfig.xml,如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEconfiguration
PUBLIC"-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--<properties resource=""></properties> -->
<environmentsdefault="development">
<environmentid="development">
<transactionManagertype="JDBC"/>
<dataSourcetype="POOLED">
<propertyname="driver"value="com.mysql.jdbc.Driver"/>
<propertyname="url"value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
<propertyname="username"value="root"/>
<propertyname="password"value="mysql"/>
</dataSource>
</environment>
</environments>
</configuration>
SqlMapConfig.xml是mybatis核心配置文件,上边文件的配置内容为数据源、事务管理。
Po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java如下:
publicclass User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 出生日期
private String address;// 地址
private String detail;// 详细信息
private Float score;// 成绩
get/set……
在classpath下的sqlmap目录下创建sql映射文件User.xml:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapper
PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="test">
<!--根据id获取用户信息 -->
<selectid="selectUserById" parameterType="int"resultType="cn.itcast.mybatis.po.User">
select * from user where id = #{id}
</select>
<!--获取用户列表 -->
<selectid="selectUserList" resultType="cn.itcast.mybatis.po.User">
select * from user
</select>
<!--添加用戶 -->
<insertid="insertUser" parameterType="cn.itcast.mybatis.po.User">
insert into user(username,birthday,sex,address,detail,score)
values(#{username},#{birthday},#{sex},#{address},#{detail},#{score})
</insert>
<!--更新用戶 -->
<updateid="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address},detail=#{detail},score=#{score}
where id=#{id}
</update>
<!--刪除用戶 -->
<deleteid="deleteUser" parameterType="cn.itcast.mybatis.po.User">
delete from user where id=#{id}
</delete>
</mapper>
namespace :命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。
parameterType:定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。id是实体类的属性名
resultType:定义结果映射类型。
在SqlMapConfig.xml中添加mappers如下:
<mappers>
<mapperresource="sqlmap/user.xml"/>
</mappers>
这里即告诉mybatis Sql映射文件在哪里。
/**
* 第一个mybatis程序
*
* @authorThinkpad
*
*/
publicclass Mybatis_select {
publicstaticvoid main(String[] args) throws IOException {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder()
.build(inputStream);
//通过session工厂获取一个Sqlsession,sqlsession中包括了对数据库操作的sql方法
SqlSession session = sqlSessionFactory.openSession();
try {
//通过sqlsession调用selectOne方法获取一条结果集
//参数1:指定定义的statement的id,参数2:指定向statement中传递的参数
User user = session.selectOne("test.selectUserById", 1);
System.out.println(user);
} finally{
session.close();
}
}
}
public class Mybatis_insert {
publicstaticvoid main(String[] args) throws IOException {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder()
.build(inputStream);
//通过session工厂获取一个Sqlsession,sqlsession中包括了对数据库操作的sql方法
SqlSession session = sqlSessionFactory.openSession();
try {
User user = newUser();
user.setUsername("张三");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
user.setDetail("好同志");
user.setScore(99.8f);
session.insert("test.insertUser", user);
session.commit();
} finally{
session.close();
}
}
}
通过修改sql映射文件,可以将mysql自增主键返回:
<insert id="insertUser"parameterType="cn.itcast.mybatis.po.User">
<!-- selectKey将主键返回,需要再返回 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address,detail,score)
values(#{username},#{birthday},#{sex},#{address},#{detail},#{score});
</insert>
添加selectKey实现将主键返回
keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
resultType:返回的主键是什么类型
LAST_INSERT_ID():是mysql的函数
Oracle可采用序列完成:
首先自定义一个序列且于生成主键,selectKey使用如下:
<selectKey resultType="java.lang.Integer" order="BEFORE"
keyProperty="id">
SELECT 自定义序列.NEXTVAL FROM DUAL
</selectKey>
注意这里使用的order是“BEFORE”
public class Mybatis_delete {
publicstaticvoid main(String[] args) throws IOException {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder()
.build(inputStream);
//通过session工厂获取一个Sqlsession,sqlsession中包括了对数据库操作的sql方法
SqlSession session = sqlSessionFactory.openSession();
try {
session.delete("test.deleteUser", 4);
session.commit();
} finally{
session.close();
}
}
}
public class Mybatis_update {
public static void main(String[] args) throws IOException {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder()
.build(inputStream);
//通过session工厂获取一个Sqlsession,sqlsession中包括了对数据库操作的sql方法
SqlSession session = sqlSessionFactory.openSession();
try {
User user = newUser();
user.setId(4);
user.setUsername("李四");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
user.setDetail("好同志");
user.setScore(99.8f);
session.update("test.updateUser", user);
session.commit();
} finally{
session.close();
}
}
}
命名空间除了对sql进行隔离,mybatis中对命名空间有特殊的作用,用于定义mapper接口地址。
没有使用接口编程,java是面向接口编程语言,对数据库的操作应该定义一些操作接口,如:用户添加、用户删除、用户查询等,调用dao接口完成数据库操作。
public interface UserDao {
public User getUserById(int id) throws Exception;
public void insertUser(User user) throws Exception;
}
public class UserDaoImpl implements UserDao {
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.setSqlSessionFactory(sqlSessionFactory);
}
private SqlSessionFactory sqlSessionFactory;
@Override
public User getUserById(int id) throws Exception {
SqlSession session = sqlSessionFactory.openSession();
User user = null;
try {
//通过sqlsession调用selectOne方法获取一条结果集
//参数1:指定定义的statement的id,参数2:指定向statement中传递的参数
user = session.selectOne("selectUserById", 1);
System.out.println(user);
//获取List
List<User> list = session.selectList("selectUserList");
System.out.println(list);
} finally{
session.close();
}
return user;
}
@Override
publicvoid insertUser(User user) throws Exception {
SqlSession session = sqlSessionFactory.openSession();
try {
session.insert("insertUser", user);
session.commit();
} finally{
session.close();
}
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
publicvoid setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
}
第一个例子中,在访问sql映射文件中定义的sql时需要调用sqlSession的selectOne方法,并将sql的位置(命名空间+id)和参数传递到selectOne方法中,且第一个参数是一个长长的字符串,第二个参数是一个object对象,这对于程序编写有很大的不方便,很多问题无法在编译阶段发现。
虽然上边对提出的面向接口编程问题进行解决,但是dao实现方法中仍然是调用sqlSession的selectOne方法,重复代码多。
Mapper.xml文件不变还用原来的。
/**
* 用户管理mapper
* @authorThinkpad
*
*/
public interface UserMapper {
public User selectUserById(int id) throws Exception;
public List<User> selectUserList() throws Exception;
public void insertUser(User user) throws Exception;
public void updateUser(User user) throws Exception;
public voiddeleteUser(int id) throws Exception;
}
接口定义有如下特点:
1、 Mapper接口方法名和mapper.xml中定义的每个sql的id相同
2、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
3、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml映射文件中的namepace改为如下:
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
修改后namespace即是mapper接口的地址。
public class UserMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
protected void setUp() throws Exception {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public void testSelectUserById() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获取mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//通过mapper接口调用statement
User user = userMapper.selectUserById(1);
System.out.println(user);
//关闭session
session.close();
}
public void testSelectUserList() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获取mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//通过mapper接口调用statement
List<User>list = userMapper.selectUserList();
System.out.println(list);
//关闭session
session.close();
}
public void testInsertUser() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//要添加的数据
User user = newUser();
user.setUsername("张三");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
user.setDetail("好同志");
user.setScore(99.8f);
//通过mapper接口添加用户
userMapper.insertUser(user);
//提交
session.commit();
//关闭session
session.close();
}
public void testUpdateUser() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//要更新的数据
User user = newUser();
user.setId(7);
user.setUsername("李四");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
user.setDetail("好同志");
user.setScore(99.8f);
//通过mapper接口调用statement
userMapper.updateUser(user);
//提交
session.commit();
//关闭session
session.close();
}
public void testDeleteUser() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//通过mapper接口删除用户
userMapper.deleteUser(6);
//提交
session.commit();
//关闭session
session.close();
}
}
session.getMapper(UserMapper.class)生成一个代理对象作为UserMapper的接口实现对象。
使用mapper接口不用写接口实现类即可完成数据库操作,简单方便,此方法为官方推荐方法。
使用mapper接口调用必须具备如下条件:
1、 Mapper接口方法名和mapper.xml中定义的每个sql的id相同
2、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
3、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
4、 Mapper.xml文件中的namespace即是mapper接口的类路径。
至此,mybatis的mapper包括mapper.xml和mapper接口两种文件。
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
SqlMapConfig.xml可以引用java属性文件中的配置信息如下:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=mysql
SqlMapConfig.xml引用如下:
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transaction Managertype="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>
别名 | 映射的类型 |
---|---|
_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 |
<typeAliases>
<!--单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!--批量别名定义,扫描整个包下的类 别名默认为类名首字母小写-->
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
类型处理器在将java类型和sql映射文件进行映射时使用,如下:
<select id="selectUserById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
parameterType:指定输入数据类型为int,即向statement设置值
resultType:指定输出数据类型为自定义User,即将resultset转为java对象
mybatis自带的类型处理器基本上满足日常需求,不需要单独定义。
mybatis支持类型处理器:
类型处理器 | Java类型 | JDBC类型 |
---|---|---|
BooleanTypeHandler | Boolean,boolean | 任何兼容的布尔值 |
ByteTypeHandler | Byte,byte | 任何兼容的数字或字节类型 |
ShortTypeHandler | Short,short | 任何兼容的数字或短整型 |
IntegerTypeHandler | Integer,int | 任何兼容的数字和整型 |
LongTypeHandler | Long,long | 任何兼容的数字或长整型 |
FloatTypeHandler | Float,float | 任何兼容的数字或单精度浮点型 |
DoubleTypeHandler | Double,double | 任何兼容的数字或双精度浮点型 |
BigDecimalTypeHandler | BigDecimal | 任何兼容的数字或十进制小数类型 |
StringTypeHandler | String | CHAR和VARCHAR类型 |
ClobTypeHandler | String | CLOB和LONGVARCHAR类型 |
NStringTypeHandler | String | NVARCHAR和NCHAR类型 |
NClobTypeHandler | String | NCLOB类型 |
ByteArrayTypeHandler | byte[] | 任何兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB和LONGVARBINARY类型 |
DateTypeHandler | Date(java.util) | TIMESTAMP类型 |
DateOnlyTypeHandler | Date(java.util) | DATE类型 |
TimeOnlyTypeHandler | Date(java.util) | TIME类型 |
SqlTimestampTypeHandler | Timestamp(java.sql) | TIMESTAMP类型 |
SqlDateTypeHandler | Date(java.sql) | DATE类型 |
SqlTimeTypeHandler | Time(java.sql) | TIME类型 |
ObjectTypeHandler | 任意 | 其他或未指定类型 |
EnumTypeHandler | Enumeration类型 | VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)。 |
Mapper配置的几种方法:
使用相对于类路径的资源
如:<mapper resource="sqlmap/user.xml" />
使用完全限定路径
如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\user.xml" />
使用mapper接口类路径
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
注册指定包下的所有mapper接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。
#{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符即?。
<!--根据id查询用户信息 -->
<select id="selectUserById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
使用占位符#{}可以有效防止sql注入,在使用时不需要关心参数值的类型,mybatis会根据参数值的类型调用不同的statement设置参数值的方法。可以想象为:如果参数值是一个字符串则自动映射生成的sql中参数值两边自动有单引号,如果参数值是一个数字型则自动映射生成的sql中参数值两边没有单引号。
注意:当传递单个值时#{}中的参数名称通常和mapper接口的形参名称相同,也可以设置成任意值。
${}和#{}不同,${}是将参数值不加修饰的拼在sql中,相当中用jdbc的statement拼接sql,使用${}不能防止sql注入,但是有时用${}会非常方便,如下的例子:
<!--根据名称模糊查询用户信息 -->
<select id="selectUserByName" parameterType="string" resultType="user">
select * from user where username like '%${value}%'
</select>
如果本例子使用#{}则传入的字符串中必须有%号,而%是人为拼接在参数中,显然有点麻烦,如果采用${}在sql中拼接为%的方式则在调用mapper接口传递参数就方便很多。
再比如order by排序,如果将列名通过参数传入sql,根据传的列名进行排序,应该写为:
ORDER BY ${columnName}
如果使用#{}将无法实现此功能。
注意:{}不能防止sql注入,对系统安全性有很大的影响,如果使用{}建议传入参数尽量不让用户自动填写,即使要用户填写也要对填写的数据进行校验,保证安全性。
另外,当传递单个值时${}中填写的参数名称经过测试填写value不报错。
Mybatis提供使用ognl表达式动态生成sql的功能。
<!--传递pojo综合查询用户信息 -->
<select id="selectUserByUser" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
注意要做不等于空字符串校验。
上边的sql也可以改为:
<select id="selectUserByUser" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
<where />可以自动处理第一个and。
向sql传递数组或List,mybatis使用foreach解析,如下:
传递List类型在编写mapper.xml没有区别,唯一不同的是只有一个List参数时它的参数名为list。
如下:
<select id="selectUserByList" parameterType="java.util.List"resultType="user">
select * from user
<where>
<!--传递List,List中是pojo -->
<if test="list!=null">
<foreach collection="list" item="item" open="and id in(" separator="," close=")">
#{item.id}
</foreach>
</if>
</where>
</select>
<!--传递数组综合查询用户信息 -->
<select id="selectUserByArray" parameterType="Object[]" resultType="user">
select * from user
<where>
<!--传递数组 -->
<if test="array!=null">
<foreach collection="array" index="index" item="item" open="and id in(" separator="," close=")">
#{item.id}
</foreach>
</if>
</where>
</select>
sql只接收一个数组参数,这时sql解析参数的名称mybatis固定为array,如果数组是通过一个pojo传递到sql则参数的名称为pojo中的属性名。
index:为数组的下标。
item:为数组每个元素的名称,名称随意定义
open:循环开始
close:循环结束
separator:中间分隔输出
如果数组中是简单类型则写为#{item},不用再通过ognl获取对象属性值了。
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:
<!--传递pojo综合查询用户信息 -->
<select id="selectUserByUser" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
<select id="selectUserByUser" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:
<include refid="namespace.sql片段”/>
当输出pojo的字段和sql查询出来的字段名称不对应时而还想用这个pojo类作为输出类型这时就需要使用resultMap了。
另外,resultMap也解决了一对一关联查询、一对多关联查询等常见需求。
Public class Person {
privateint id;
private String name;// 用户姓名,名称和User表的字段名称不一样
private String sex;// 性别
private Date birthday;// 出生日期
private String addr;// 地址,名称和User表的字段名称不一样
private String detail;// 详细信息
private Float score;// 成绩
get/set。。。。
在mapper.xml文件中定义resultMap:
<!-- resultMap定义 -->
<resultMap type="cn.itcast.mybatis.po.Person" id="personmap">
<id property="id" column="id"/>
<result property="name" column="username"/>
<result property="addr" column="address"/>
</resultMap>
<id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。
Property:表示person类的属性。
Column:表示sql查询出来的字段名。
Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
<result />:普通结果,即pojo的属性。
这里只将sql查询出来的字段与pojo属性名不一致的进行了定义,通过后边的测试pojo属性名和sql字段相同的自动进行映射。
<!--获取用户列表返回resultMap -->
<select id="selectUserListResultMap" resultMap="personmap">
select * from user
</select>
使用resultMap指定上边定义的personmap。
public List<Person> selectUserListResultMap() throws Exception;
实际返回的类型是Person类型。
Public void testselectUserListResultMap() throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = newUser();
user.setUsername("管理员");
//查询用户列表返回resultMap
List<Person> list = userMapper.selectUserListResultMap();
System.out.println(list);
//关闭session
session.close();
}