Java三大框架之Mybatis
三大框架之Mybatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
Mybatis架构
初步接触Mybatis
mybatis下载:mybaits的代码由github.com管理,Mybatis下载地址
导入jar包 :加入mybatis核心包、依赖包、数据驱动包。junit-4.9.jar这个包是为测试方便加入的
创建配置文件 :在classpath下创建config目录(source folder类型)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作为输出日志信息。
第一个mybatis程序
在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>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/db_test1?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
创建一个User实体类
private int id;
private String name;
private String password;
private String sex;
private int age;
sql映射文件User.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="test">
</mapper>
namespace :命名空间,用于隔离sql语句,后面会讲另一层非常重要的作用。
**mybatis框架需要加载映射文件,将User.xml添加在SqlMapConfig.xm
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
在User.xml配置根据id获取用户信息
<select id="findUserById" parameterType="int" resultType="com.yun.mybatis.domain.User">
select * from user where id=#{id}
</select>
parameterType:
定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。resultType:定义结果映射类型。
测试程序(新建一个测试类)
public class MyTest {
SqlSessionFactory ssf = null;
@Before
public void creatFactory(){
InputStream input = null;
try {
input = Resources.getResourceAsStream("SqlMapConfig.xml");
} catch (IOException e) {
e.printStackTrace();
}
ssf = new SqlSessionFactoryBuilder().build(input);
}
/** 通过id查找*/
@Test
public void testFindUserById(){
SqlSession session =ssf.openSession();
//System.out.println(session);
User user = session.selectOne("test.findUserById", 8);
System.out.println(user);
session.close();
}
}
根据用户名查询
<select id="findUserByName" parameterType="string" resultType="com.yun.mybatis.domain.User">
select * from user where name like "%${value}%"
</select>
parameterType:定义输入到sql中的映射类型,{value}替换,做字符串的拼接。
注意:如果是取简单数量类型的参数,括号中的值必须为value
resultType:定义结果映射类型。
测试代码
@Test
public void testFindUserByName(){
SqlSession session =ssf.openSession();
List<User> userList = session.selectList("test.findUserByName", "xiao");
System.out.println(userList);
session.close();
}
#{}和${}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。一般用在=之后。
{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, {}括号中只能是value。一般用在like之后。
5.6.2parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。
5.6.3selectOne和selectList
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
selectList可以查询一条或多条记录
添加用户
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
@Test
public void testInsert() {
// 数据库会话实例
SqlSession sqlSession = null;
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 添加用户信息
User user = new User();
user.setUsername("张小明");
user.setAddress("河南郑州");
user.setSex("1");
user.setPrice(1999.9f);
sqlSession.insert("test.insertUser", user);
//提交事务
sqlSession.commit();
}
mysql自增主键返回
- 通过修改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) values(#{username},#{birthday},#{sex},#{address});
</insert>
- 添加selectKey实现将主键返回
keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
resultType:返回的主键是什么类型
LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。
Mysql使用 uuid实现主键
需要增加通过select uuid()得到uuid值
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
select uuid()
</selectKey>
insert into user(id,username,birthday,sex,address)values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
注意这里使用的order是“BEFORE”
删除用户
- 映射文件
<!-- 删除用户 -->
<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>
- 5.8.2测试程序
// 根据id删除用户
@Test
public void testDelete() {
// 数据库会话实例
SqlSession sqlSession = null;
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 删除用户
sqlSession.delete("test.deleteUserById",18);
// 提交事务
sqlSession.commit();
sqlSession.close();
}
修改用户
- 映射文件
<!-- 更新用户 -->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
- 测试程序
public void testUpdate() {
// 数据库会话实例
SqlSession sqlSession = null;
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 添加用户信息
User user = new User();
user.setId(16);
user.setUsername("张小明");
user.setAddress("河南郑州");
user.setSex("1");
user.setPrice(1999.9f);
sqlSession.update("test.updateUser", user);
// 提交事务
sqlSession.commit();
sqlSession.close();
}
1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
上一篇: php中使用zip 博客分类: PHP phpzip
下一篇: 爬虫大框架之 - Scrapy(三)
推荐阅读
-
Java三大框架之Mybatis
-
Java学习笔记-Day75 MyBatis 框架(二)
-
系统学习JavaEE的ORM框架之Mybatis入门案例
-
疯子在思考之从零说MVC-2 博客分类: JAVA mvcstruts开源框架spring mvc3
-
框架设计之注解 博客分类: 架构 框架java工作企业应用
-
框架设计之注解 博客分类: 架构 框架java工作企业应用
-
《易道客》源码剖析之四:页面多次跳转的记忆 博客分类: 易道客 java易道客页面跳转开源框架
-
Java使用JDBC或MyBatis框架向Oracle中插入XMLType数据
-
Java持久层框架MyBatis简单实例
-
java持久层框架mybatis防止sql注入的方法