原生JDBC(操作数据库)
public static void main(String[] args) {Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
//连接数据库
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",root", "root");
//发送SQL语句到数据库
String sql = "select * from user where username = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, "王五");
//接收数据库执行SQL语句的结果
resultSet = statement.executeQuery();
while(resultSet.next()){
System.out.println(resultSet.getString("id") + "-" + resultSet.getString("username"));
}
} catch (Exception e) {
}finally {
try {
if(connection != null){
connection.close();
}
if(statement != null){
statement.close();
}
if(resultSet != null){
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
问题总结
1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。
设想:使用数据库连接池管理数据库连接
2、将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护。
设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码重新编译。
3、向prepareStatement中设置参数,对占位符位置和设置参数值,硬编码在java代码中,不利于系统维护
设想:将sql语句及占位符和参数全部设置在xml中
4、从resultSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护
设想:将查询的结果集,自动映射成java对象
mybatis框架
1、SqlMapConfig.xml(是mybatis的全局配置文件),配置了数据源、事务等mybatis运行环境配置映射文件(配置sql语句)。
——mapper.xml(映射文件)、mapper.xml...
2、SqlSessionFactory(会话工厂):作用:创建SqlSession
3、SqlSession(会话),是一个接口,面向用户(程序员)的接口:作用:操作数据库(发出sql增删改查)
4、Executor(执行器),是一个接口(基本执行器、缓存执行器):作用:SqlSession内部通过执行器操作数据库
5、mappedStatement(底层封装对象):作用:对操作数据库存储封装,包括sql语句,输入参数,输出结果类型
6、输入参数类型:java简单类型、hashmap、pojo自定义
7、输出参数类型:java简单类型、hashmap、pojo自定义
mybatis框架执行过程:
1.配置mybatis的配置文件,sqlMapConfig.xml(名称不固定)
2.通过配置文件,加载mybatis运行环境,创建SqlSessionFactory会话工厂。SqlSessionFactory在实际使用时按单例方式。
3.通过SqlSessionFactory创建SqlSession: SqlSession是一个面向用户的接口(提供操作数据库方法),实现对象是线程不安全的,建议SqlSession应用场合在方法体内。
4.调用SqlSession的方法去操作数据: 如果需要提交事务,需要执行SqlSession的commit()方法。
5.释放资源,关闭SqlSession.
SqlMapConfig.xml
1.配置mybatis的运行环境,数据源、事务等
<?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>
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务由mybatis控制 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
查询
1.根据用户id主键查询用户信息
1.pojo类
public class User{
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
}
2.映射文件(User.xml,mapper代理开发映射文件名称为UserMapper.xml)
在映射文件中配置sql语句
<?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进行分类管理,理解sql隔离。
注意:使用mapper代理方法开发,namespace有特殊重要的作用 -->
<mapper namespace="test">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 通过select执行数据库查询。
id:标识映射文件的sql,称为statement的id,将语句封装到mappedStatement对象中,所以将id称为statement的id。
parameterType:指定參數的類型,这里指定int类型。
#{}表示一个占位符号。
#{id}:其中的id表示接收输入的参数,参数名称就是id,如果参数是简单类型,#{}中的参数名可以任意,可以value或其它名称。
resultType指定sql输出结果的所映射的java对象类型,
select指定resultType表示将单条记录映射成的java对象.
-->
<select id="findUserById" parameterType="int">
select * from user where id = #{value}
</select>
</mapper>
#{}和${}
#{}表示一个占位符
${}表示一个拼接符号,会引用sql注入,所以不建议使用
selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个表(多条记录)。如果使用selectList查询多条记录,不能使用selectOne。
注意:如果返回多条数据使用selectOne就会报异常:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
新增一条数据
1.User.xml
<insert id="insertUser" parameterType="cn.chx.mybatis.po.User">
insert into User(username, birthday, sex, address) values(#{username},
#{birthday}, #{sex}, #{address})
</insert>
2.测试
// mybatis配置文件
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 通过会话工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setSex("0");
user.setAddress("广东省");
user.setBirthday(new Date());
user.setUsername("陈宏鑫");
sqlSession.insert("test.insertUser", user);
// 事务提交
sqlSession.commit();
sqlSession.close();
自增主键返回
mysql自增主键,执行insert提交之前自动生成一个自增主键.
通过mysql函数获取到刚插入记录的自增主键:
LAST_INSERT_ID();是insert之后才调用函数的.
非自增主键返回(使用uuid())
使用mysql的uuid
<!-- 使用mysql的uuid()生成主键。
执行过程:首先通过uuid()得到主键,将主键设置到User对象的id属性中,其次在insert执行时,从user对象中取出id属性值 -->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
select uuid()
</selectKey>
insert into User(id, username, birthday, sex, address) values(#{id}, #{username},#{birthday}, #{sex}, #{address})
mybatis和hibernate本质区别和应用场景
hibernate:
是一个标准ORM框架(对象关系映射)。入门门槛高,不需要程序写sql,sql语句自动生成。对sql语句进行优化、修改比较困难。
应用场景:适用与需求变化不多的中小型项目,比如后台管理系统,erp、orm、oa.
mybatis:
专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全的orm框架,虽然程序员自己写sql,mybatis也可以实现映射(输入映射、输出映射)。
应用场景:适用与需求变化较多的项目,比如:互联网项目。
企业进行技术类型,以低成本高回报作为技术选型的原则,根据项目组的技术力量进行选择。
SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例管理SqlSessionFactoryBuilder,在需要创建SqlSessionFactory时候,只需要newy一次SqlSessionFactoryBuilder即可。
SqlSessionFactory
通过SqlSessionFactory创建SqlSession。使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例),将来mybatis和spring整合后,使用单例模式管理SqlSessionFactory。
SqlSession
SqlSession是一个面向用户的接口。SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象),selectList(返回单个或多个对象)。SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
SqlSession最佳应用场合在方法内,定义局部变量使用。
原始dao开发方法(程序员需要写dao接口和dao实现类)
思路:
程序员需要写dao接口和dao实现类
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession
dao接口
public interface UserDao {
User findUserById(Integer id);
void insertUser(User user);
}
dao接口实现
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
测试代码
private UserDaoImpl userDaoImpl;
@Before
public void setUp() throws IOException {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
userDaoImpl = new UserDaoImpl(sqlSessionFactory);
}
// 根据id查询用户信息,得到一条记录信息
@Test
public void findUserByIdTest() throws IOException {
User user = userDaoImpl.findUserById(1);
System.out.println(user);
}
}
总结原始dao开发问题
1.dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量.
2.调用SqlSession方法时statement的id硬编码了(spring和mybatis整合后不用写statement的id,可以直接调用).
3.调用SqlSession方法时传入的变量,由于SqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发.
mapper代理方法(程序员只需要mapper接口(相当于dao接口))
程序员编写mapper接口(相当于dao接口),程序员还需要编写mapper.xml映射文件,mybatis可以自动生成mapper接口实现类代理对象。
开发规范:
1、在mapper.xml映射文件中namespace等于mapper接口空间地址。
<!-- namespace命名空间,对sql进行分类管理,理解sql隔离。注意:使用mapper代理方法开发,namespace有特殊重要的作用 -->
<mapper namespace="cn.chx.mybatis.mapper.UserMapper">
2、mapper.java接口的方法名和mapper.xml的statement的id一致
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致
4、mapper.java接口中的方法返回类型和mapper.xml中的resultType的类型一致
/**
* UserMapper
* mapper接口,相当于dao的接口
* @author chenhongxin
*
*/
public interface UserMapper {
User findUserById(Integer id);
void insertUser(User user);
}
配置SqlMapConfig.xml加载mapper
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
测试
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws IOException {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
SqlMapConfig.xml
mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandles(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
properties
需求:
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值
在SqlMapConfig.xml中就不需要对数据库参数硬编码。
将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties
<properties resource="db.properties" />
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务由mybatis控制 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.jdbcUrl}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
注意:MyBatis将按照下面的顺序加载属性
1、在properties元素体内定义的属性首先被读取
2、然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性
3、最后读取parameterType传递的属性,它会覆盖已读取的同名属性
因此,通过parameterType传递的属性具有最高优先级,resource和url加载的属性次之,最低优先级的是properties元素体内定义的属性.
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如:属性名.属性名
typeAliases
在mapper.xml中,定义很多statement,statement需要paramterType指定输入参数的类型、需要resultType指定输出结果的映射类型
1.SqlMapConfig.xml配置文件
<typeAliases>
<!--
批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<package name="cn.chx.mybatis.po"/>
</typeAliases>
2.Mapper.xml映射文件
<select id="findUserById" parameterType="int" resultType="User">
select * from user where id = #{value}
</select>
mappers(映射配置)
1.<mapper resource="mapper/UserMapper.xml"/>
2.<package name="cn.chx.mybatis.mapper"/> // 加载映射文件的包
测试:
public void testFindUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型
6.1.传递pojo的包装对象
6.1.1.需求
完成用户信息的综合查询,需要传入查询条件很复杂(可能包括用户信息、其它信息,比如商品、订单)
6.1.2.定义包装类型pojo
针对上边的需求,建议使用自定义的包装类型的pojo
在包装类型的pojo中复杂的查询条件包装进去
/**
* 用户扩展类
* @author chenhongxin
*/
public class UserCustomer extends User {
}
public class UserQueryVo {
// 在这里包装所需要的查询条件
// 用户查询条件private UserCustomer userCustomer;
public void setUserCustomer(UserCustomer userCustomer) {
this.userCustomer = userCustomer;}
public UserCustomer getUserCustomer() {
return userCustomer;
}
// 可以包装其它的查询条件,订单、商品
// ...
}
mapper.xml
在UserMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂关联查询).
<!-- 用戶信息綜合查詢 -->
<select id="findUserList" parameterType="cn.chx.mybatis.po.UserQueryVo" resultType="cn.chx.mybatis.po.UserCustomer">
select * from user where user.sex = #{userCustomer.sex} and user.username like '%${userCustomer.username}%'
</select>
mapper.java
List<UserCustomer> findUserList(UserQueryVo userQueryVo);
测试:
@Test
public void testFindUserList() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustomer user = new UserCustomer();
user.setSex("1");
user.setUsername("张三丰");
userQueryVo.setUserCustomer(user);
List<UserCustomer> userCustomers = userMapper.findUserList(userQueryVo);
System.out.println(userCustomers);
sqlSession.close();
}
resultType
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
如果查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象
输出简单类型
需求
用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页
mapper.xml
<!-- 用户信息综合查询总数 -->
<select id="findUserCount" parameterType="cn.chx.mybatis.po.UserQueryVo"
resultType="int">
select count(*) from user where user.sex =
#{userCustomer.sex} and
user.username like '%${userCustomer.username}%'
</select>
mapper.java
int findUserCount(UserQueryVo userQueryVo);
测试:
@Test
public void testFindUserCount() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustomer user = new UserCustomer();
user.setSex("1");
user.setUsername("张三丰");
userQueryVo.setUserCustomer(user);
int count = userMapper.findUserCount(userQueryVo);
System.out.println(count);
sqlSession.close();
}
7.2 resultMap使用
mybatis中使用resultMap完成高级输出结果映射
7.2.1 resultMap使用方法
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
1、定义resultMap
2、使用resultMap作为statement的输出映射类型
7.2.2 将下边的sql使用UserCustomer完成映射
select id id_, username _username from user;
userCustomer类中属性名和上边查询列名不一致。
定义resultMap
<!-- 定义resultMap
select id id_, username _username from user 和User类中的属性作为一个映射关系
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查询结果集中唯一标识
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property作为一个映射关系(对应关系)
-->
<id property="id" column="id_"/>
<result property="username" column="_username" />
</resultMap>
<!-- 使用resultMap进行映射
resultMap:指定定义的resultMap的id,如果这个resultMap在其它的mapper文件,前边需要加namespace
-->
<select id="findUserResultMap" resultMap="userResultMap">
select id id_, username _username from user;
</select>
测试:
@Test
public void testFindUserResultMap() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.findUserResultMap();
System.out.println(users);
sqlSession.close();
}
8.动态sql
8.1.什么是动态sql
mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装
8.2.需求
用户信息综合信息和用户信息查询列表总数这两个statement的定义使用动态sql
对查询条件进行判断,如果输入不为空,就对sql进行拼接
mapper.xml
<!-- 用戶信息綜合查詢 -->
<select id="findUserList" parameterType="cn.chx.mybatis.po.UserQueryVo"
resultType="cn.chx.mybatis.po.UserCustomer">
select * from user
<!-- where可以自动去掉条件中的第一个and -->
<where>
<if test="userCustomer != null">
<if test="userCustomer.sex != null and userCustomer.sex != ''">
and user.sex = #{userCustomer.sex}
</if>
<if test="userCustomer.username != null and userCustomer.username != ''">
and user.username like '%${userCustomer.username}%'
</if>
</if>
</where>
</select>
测试代码:
@Test
public void testFindUserList() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustomer user = new UserCustomer();
user.setSex("1");
user.setUsername("张三丰");
userQueryVo.setUserCustomer(user);
List<UserCustomer> userCustomers = userMapper.findUserList(null); // 如果不设置数据的话就不筛选数据
System.out.println(userCustomers);
sqlSession.close();
}
8.3.sql片段
8.3.1需求
将上边实现的动态sql判断代码抽取出来,组成一个sql片段。其它的statment中可以引用该sql片段
mapper.xml
定义sql片段
<!--
id:sql片段的唯一标识
经验:是基于单表来定义sql片段,这样的话这个sql片段可重用性才高
在sql片段中不要包括where
-->
<sql id="query_user_where">
<if test="userCustomer != null">
<if test="userCustomer.sex != null and userCustomer.sex != ''">
and user.sex = #{userCustomer.sex}
</if>
<if test="userCustomer.username != null and userCustomer.username != ''">
and user.username like '%${userCustomer.username}%'
</if>
</if>
</sql>
引用sql片段
<!-- 用戶信息綜合查詢 -->
<select id="findUserList" parameterType="cn.chx.mybatis.po.UserQueryVo"
resultType="cn.chx.mybatis.po.UserCustomer">
select * from user
<!-- where可以自动去掉条件中的第一个and -->
<where>
<include refid="query_user_where" />
</where>
</select>
9.foreach
向sql传递数组或List,mybatis使用foreach遍历
9.1.需求
在用户查询列表和查询总数的statement中增加多个id输入查询
sql语法如下:
两种方法:
select * from user where id = 1 or id = 10 or id = 16
select * from user where id in(1, 10, 16)
9.2.pojo分装
public class UserQueryVo {
// 在这里包装所需要的查询条件
// 传入多个id
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
9.3.mapper.xml
<if test="ids != null">
<!-- 使用foreach遍历传入的ids
collection:指定要遍历的集合属性
item:遍历生成每个对象
open:开始遍历拼接的串
close:结束遍历拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<!-- 第一种方法 -->
<!-- <foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach> -->
<foreach collection="ids" item="id" open="and id in(" close=")" separator=",">
#{id}
</foreach>
</if>
测试代码:
@Test
public void testFindUserList() {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustomer user = new UserCustomer();
user.setSex("1");
// user.setUsername("张三丰");
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
userQueryVo.setIds(ids);
userQueryVo.setUserCustomer(user);
List<UserCustomer> userCustomers = userMapper.findUserList(userQueryVo);
System.out.println(userCustomers);
sqlSession.close();
}
mybatis是什么?
mybatis是一个持久层框架,mybatis是一个不完全的ORM框架。sql语句需要程序员自己开发,但是mybatis也有映射(输入映射、输出映射)。
mybatis入门门槛不高,学习成本高,让程序员把精力放在sql语句上,对sql语句优化非常方便,适用与需求变化较多项目,比如互联网项目。
mybatis让程序将主要精力放在sql上,通过mybatis提供的映射放射,自动灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
mybatis可以将向prepareStatement中的输入参数自动进行输入映射(statement.setString(1, "王五")),将查询结果集灵活映射成java对象(输出映射(resultSet.getString("id")))。
mybatis开发dao的方法:
1.原始dao的方法
需要程序员编写mapper接口(就是dao接口)
程序员在编写mapper.xml(映射文件)和mapper.java需要遵循一个开发规范
1.mapper.xml中namespace就是mapper.java的类全路径
2.mapper.xml中statement的id和mapper.java中方法名一致
3.mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入参数类型一致
4.mapper.xml中statement的returnType指定输出结果的类型和mapper.java的方法返回类型一致
SqlMapConfig配置文件,可以配置properties属性、别名、mapper加载...
输入映射
parameterType:指定输入参数类型可以简单类型、pojo、hashmap...
对于综合查询,建议parameterType使用包装的pojo,有利于系统扩展
输出映射
resultType:
查询到的列名和resultType指定的pojo的属性名一致,才能映射成功
resultMap:
可以通过resultMap完成一些高级映射。
如果查询到的列名和映射的pojo的属性名不一致时,通过resultMap设置列名和属性名之间的对应关系(映射关系)。可以完成映射。
高级映射:
将关联查询的列映射到一个pojo属性中。(一对一)
将关联查询的列映射到一个list<pojo>中。(一对多)