MyBatis
本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。 目前mybatis在github上托管。git(分布式版本控制,当前比较流程)
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
1、mapper代理方法:程序员只需要些mapper接口(相当于dao接口),mybatis自动根据mapper接口和mapper接口对应的statement自动生成代理对象(接口实现类对象)。
开发需要遵循规则 :
- mapper.xml 中namespaec是mapper接口的权限定名
- mapper.xml 中statement的id为mapper接口方法名
- mapper.xml 中statement的输入映射类型(parameterType)和mapper接口方法输入参数类型一致
- mapper.xml 中statement的输出类型(resultType)和mapper接口方法返回类型一致。
resultType 和 resultMap 都可以完成输出映射:
- resultType 映射要求sql查询的列名和输出映射pojo类型的属性名一致
- resultMap映射时对sql查询 的类名和输出映射pojo类型名作对应关系
实现用户查询:
- 根据用户id(主键)查询用户信息(单条记录)
- 根据用户名称模糊查询用户信息(多条记录)
* 用户添加
* 用户删除
* 用户修改
从mybatis官网下载(地址:https://github.com/mybatis/mybatis-3/releases)
# Global logging configuration,建议开发环境中要用debug
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
通过SqlMapConfig.xml加载mybatis运行环境
<configuration>
<properties resource="db.properties">
properties>
<typeAliases>
<package name="cn.itcast.mybatis.po"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="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>
<mappers>
<mapper resource="sqlmap/User.xml" />
<package name="cn.itcast.mybatis.mapper"/>
mappers>
configuration>
public class User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
}
建议命名规则: 表名+mapper.xml
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM USER WHERE id= #{id}
select>
mapper>
创建SqlSessionFactory
public class MybatisFirst {
// 会话工厂
private SqlSessionFactory sqlSessionFactory;
// 创建工厂
@Before
public void init() throws IOException {
// 配置文件(SqlMapConfig.xml)
String resource = "SqlMapConfig.xml";
// 加载配置文件到输入 流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
// 测试根据id查询用户(得到单条记录)
@Test
public void testFindUserById() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
// 第一个参数:statement的位置,等于namespace+statement的id
// 第二个参数:传入的参数
User user = null;
try {
user = sqlSession.selectOne("test.findUserById", 2);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println(user);
}
}
根据用户名称模糊查询用户信息可能返回多条记录。
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
select * from user where username like '%${value}%'
select>
// 测试根据id查询用户(得到单条记录)
@Test
public void testFindUserByName() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
// 第一个参数:statement的位置,等于namespace+statement的id
// 第二个参数:传入的参数
List list = null;
try {
list = sqlSession.selectList("test.findUserByName", "小明");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println(list.get(0).getUsername());
}
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
select * from user where username like '%${value}%'
select>
向用户表插入一条记录
<insert id="insertUser" parameterType="cn.ty.mybatis.po.User" >
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
insert>
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
delete>
<update id="updateUser" parameterType="cn.ty.mybatis.po.User" flushCache="false">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
update>
// 测试根据id删除用户(得到单条记录)
@Test
public void testDeleteUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
try {
sqlSession.delete("test.deleteUser", 35);
// 需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
// 测试根据id更新用户(得到单条记录)
@Test
public void testUpdateUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
// 创建更新数据对象,要求必须包括 id
User user = new User();
user.setId(35);
user.setUsername("");
user.setAddress("河南郑州");
// user.setBirthday(new Date());
user.setSex("1");
try {
sqlSession.update("test.updateUser", user);
// 需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println("用户的id=" + user.getId());
}
企业开发进行技术选型,考虑mybatis与hibernate 使用场景。
mybatis 适合开发需求变更频繁 的系统,比如:互联网项目
hibernate: 入门门开高,如果用hibernate写出高性能的程序不容易。hibernate不用写sql语句,是一个ORM框架。
表示一个占位符,向占位符输入参数,mybatis自动进行java类型和jdbc类型的转换。
程序员不需要考虑参数的类型,比如:纳入字符串,mybatis最终凭借好的sql就是参数两边加单引号。
#{}
接收pojo数据,可以使用OGNL解析出pojjo的属性值
表示sql的拼接,通过 接收参数,将参数的内容不加修饰拼接在sql中, 接 收 参 数 , 将 参 数 的 内 容 不 加 修 饰 拼 接 在 s q l 中 , {}也可以接收pojo数据,可以使用OGNL解析出pojo的属性值
缺点: 不能防止sql注入