一、什么是MyBatis
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
MyBatis可以使用简单的XML或註解来配置和映射原生信息,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成资料库中的记录。它对jdbc的操作资料库的过程进行封装,使程式设计师只需要关注SQL
本身,而不需要花费精力去处理例如註册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
二、MyBatis框架
mybatis配置:SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息;mapper.xml文件即sql映射文件,文件中配置了操作资料库的sql语句。此文件需要在SqlMapConfig.xml中加载。
通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
由会话工厂创建sqlSession即会话,操作资料库需要通过sqlSession进行。
mybatis底层自定义了Executor执行器接口操作资料库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
MappedStatement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是Mappedstatement的id。
MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
三.入门程序
需求
根据用户id(主键)查询用户信息
根据用户名称模煳查询用户信息
添加用户
删除用户
更新用户
2.所需jar包
MyBatis下载
mybatis-3.4.4.jar:核心包
mysql-connector-java-5.1.jar:mysql的驱动包
3.工程结构
4.log4j.properties
#Globalloggingconfiguration
#在开发的环境下,日志级别要设置成DEBUG,生产环境设置成info或error
log4j.rootLogger=DEBUG,stdout
#Consoleoutput...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p[%t]-%m%n
5.SqlMapConfig.xml
MyBatis核心配置文件,配置MyBatis的运行环境,数据源、事务等。
6.根据用户id(主键)查询用户信息
1)创建po类
ViewCodepackagejoanna.yan.mybatis.entity;
importjava.sql.Date;
publicclassUser{
//属性名称和资料库栏位名称保持一致
privateintid;
privateStringusername;
privateDatebirthday;
privateStringsex;
privateStringaddress;
publicUser(Stringusername,Datebirthday,Stringsex,Stringaddress){
super();
this.username=username;
this.birthday=birthday;
this.sex=sex;
this.address=address;
}
publicUser(intid,Stringusername,Datebirthday,Stringsex,
Stringaddress){
super();
this.id=id;
this.username=username;
this.birthday=birthday;
this.sex=sex;
this.address=address;
}
publicintgetId(){
returnid;
}
publicvoidsetId(intid){
this.id=id;
}
publicStringgetUsername(){
returnusername;
}
publicvoidsetUsername(Stringusername){
this.username=username;
}
publicStringgetSex(){
returnsex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
publicStringgetAddress(){
returnaddress;
}
publicvoidsetAddress(Stringaddress){
this.address=address;
}
publicDategetBirthday(){
returnbirthday;
}
publicvoidsetBirthday(Datebirthday){
this.birthday=birthday;
}
@Override
publicStringtoString(){
return"User[id="+id+",username="+username+",sex="+sex
+",address="+address+",birthday="+birthday+"]";
}
}
2)映射文件
映射文件命名:
User.xml(原始的ibatis的命名方式),mapper代理开发映射文件名称叫XXXMapper.xml,比如:UserMapper.xml、ItemsMapper.xml。
在映射文件中配置sql语句。
select*fromuserwhereid=#{id}
3)在SqlMapConfig.xml中加载映射文件
4)程序编写
publicclassMybatisFirst{
@Test
publicvoidfindUserByIdTest(){
//mybatis的配置文件
Stringresource="SqlMapConfig.xml";
InputStreaminputStream=null;
SqlSessionsqlSession=null;
try{
inputStream=Resources.getResourceAsStream(resource);
//1.创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂得到SqlSession
sqlSession=factory.openSession();
//3.通过SqlSession操作资料库
//参数一:映射文件中的statement的id,等于namespace+"."+statement的id;
//参数二:指定和映射文件中所匹配的parameterType类型的参数;
//sqlSession.selectOne结果是与映射文件所匹配的resultType类型的对象;
//selectOne:查询一条结果
Useruser=sqlSession.selectOne("test.findUserById",1);
System.out.println(user.toString());
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
if(inputStream!=null){
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
}
7.根据用户名称模煳查询用户信息
1)映射文件
使用User.xml,添加根据用户名称模煳查询用户信息的sql语句。
select*fromuserwhereusernameLIKE'%${value}%'
2)程序编写
@Test
publicvoidfindUserByNameTest(){
//mybatis的配置文件
Stringresource="SqlMapConfig.xml";
InputStreaminputStream=null;
SqlSessionsqlSession=null;
try{
inputStream=Resources.getResourceAsStream(resource);
//1.创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂得到SqlSession
sqlSession=factory.openSession();
//3.通过SqlSession操作资料库
//参数一:映射文件中的statement的id,等于namespace+"."+statement的id;
//参数二:指定和映射文件中所匹配的parameterType类型的参数;
//sqlSession.selectOne结果是与映射文件所匹配的resultType类型的对象;
//list中的user和resultType类型一致
Listlist=sqlSession.selectList("test.findUserByName","小明");
System.out.println(list);
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
if(inputStream!=null){
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
8.添加用户
1)映射文件
在User.xml配置添加用户的statement(多个sql)。
insertintouser(username,sex,address,birthday)values(#{username},#{sex},#{address},#{birthday})
2)程序编写
@Test
publicvoidinsertUserTest(){
//mybatis的配置文件
Stringresource="SqlMapConfig.xml";
InputStreaminputStream=null;
SqlSessionsqlSession=null;
try{
inputStream=Resources.getResourceAsStream(resource);
//1.创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂得到SqlSession
sqlSession=factory.openSession();
Useruser=newUser("yan",newDate(System.currentTimeMillis()),"女","上海");
//3.通过SqlSession操作资料库
//参数一:映射文件中的statement的id,等于namespace+"."+statement的id;
//参数二:指定和映射文件中所匹配的parameterType类型的参数;
sqlSession.insert("test.insertUser",user);
//提交事务
sqlSession.commit();
System.out.println(user.getId());
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
if(inputStream!=null){
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
3)自增主键返回
mysql自增主键:执行insert提交之前自动生成一个自增主键。
通过Mysql函数获取到刚插入记录的自增主键:LAST_INSERT_ID()
是insert之后调用此函数。
修改insertUser定义:
selectlast_insert_id()
insertintouser(username,sex,address,birthday)values(#{username},#{sex},#{address},#{birthday})
4)非自增主键返回(使用uuid())
使用mysql的uuid()函数生成主键,需要修改表中id栏位类型为String,长度设置为35位。
执行思路:
先通过uuid()查询到主键,将主键输入到sql语句中。
执行uuid()语句顺序相对于insert语句之前执行。
selectuuid()
insertintouser(id,username,sex,address,birthday)values(#{id},#{username},#{sex},#{address},#{birthday})
通过oracle的序列生成主键:
SELECT序列名.nextval()
insertintouser(id,username,birthday,sex,address)value(#{id},#{username},#{birthday},#{sex},#{address})
9.删除用户和更新用户
1)映射文件
deletefromuserwhereid=#{id}
updateusersetusername=#{username},sex=#{sex},address=#{address},birthday=#{birthday}whereid=#{id}
2)程序编写
@Test
publicvoiddeleteUserTest(){
//mybatis的配置文件
Stringresource="SqlMapConfig.xml";
InputStreaminputStream=null;
SqlSessionsqlSession=null;
try{
inputStream=Resources.getResourceAsStream(resource);
//1.创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂得到SqlSession
sqlSession=factory.openSession();
//3.通过SqlSession操作资料库
//参数一:映射文件中的statement的id,等于namespace+"."+statement的id;
//参数二:指定和映射文件中所匹配的parameterType类型的参数;
sqlSession.delete("test.deleteUser",3);
//提交事务
sqlSession.commit();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
if(inputStream!=null){
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
@Test
publicvoidupdateUserTest(){
//mybatis的配置文件
Stringresource="SqlMapConfig.xml";
InputStreaminputStream=null;
SqlSessionsqlSession=null;
try{
inputStream=Resources.getResourceAsStream(resource);
//1.创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂得到SqlSession
sqlSession=factory.openSession();
Useruser=newUser(2,"yan",newDate(System.currentTimeMillis()),"女","上海");
//3.通过SqlSession操作资料库
//参数一:映射文件中的statement的id,等于namespace+"."+statement的id;
//参数二:指定和映射文件中所匹配的parameterType类型的参数;
//根据id更新用户
sqlSession.update("test.updateUser",user);
//提交事务
sqlSession.commit();
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(sqlSession!=null){
sqlSession.close();
}
if(inputStream!=null){
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
四、总结
1.parameterType
在映射文件中通过parameterType指定输入参数的类型。
2.resultType
在映射文件中通过resultType指定输出结果的类型
3.#{}和${}
#{}表示一个占位符,#{}接收输入参数。#{}可以有效防止sql注入。类型可以是简单类型,pojo、hashmap。如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,拼接sql串,会引起sql注入存在安全隐患,所以不建议使用${}。${}接收输入参数,类型可以是简单类型,pojo、hashmap。如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
4.selectOne和selectList
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException:Expectedoneresult(ornull)tobereturnedbyselectOne(),butfound:3
atorg.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
selectList可以查询一条或多条记录。
5.MyBatis和Hibernate本质区别和应用场景
1)hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高,不需要程式设计师写sql,sql语句自动生成了。对sql语句进行优化、修改比较困难。
应用场景:使用于需要变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。。
2)mybatis:专注是sql本身,需要程式设计师之家编写sql语句,sql修改、优化比较方便。mybatis是一个不完全的ORM框架,虽然程式设计师自己写sql,mybatis也可以实现映射(输入映射、输出映射)。
应用场景:适用与需求变化较多的项目,比如:网际网路项目。
感谢您耐心阅读,如果此文对您有帮助,请点个赞或转发~