绝对干货!深度剖析Mybatis3操作数据库,带给你不一样的认知体验
本篇将和大家一起分享MyBatis 3框架,此框架的主要作用就是更加便携地操作数据库,比如将数据库返回的内容进行List或实体类的封装,将执行操作的SQL语句配置到XML文件中,这样做有利于代码的后期维护,使代码的分层更加明确。MyBatis 框架还具有优化查询效率的缓存等功能。那么在本篇中,大家应该会掌握如下内容:
- 使用基于Eclipse的MyBatis插件执行CURD增删改查操作;
- 使用MyBatis操作常用数据库Oracle、 MySQL、MsSQL;
- MyBatis框架中核心对象的生命周期;
- MyBatis结合ThreadLocal类进行CURD的封装。
MyBatis简介
为什么要使用MyBatis框架呢?举一个最简单的例子,在使用传统的JDBC代码时,需要写上必要的DAO层代码,在DAO层代码中将数据表中的数据封装到自定义的实体类中。这给代码的维护带来了问题。但MyBatis和Hibernate 解决了这样的问题,使用它们做查询时,可以自动地将数据表中的数据记录封装到实体或Map中,再将它们放入List中返回。这么常见的功能都可以由MyBatis 和Hibernate *方便地实现,可见,使用这两个框架开发应用软件会非常方便快捷。
MyBatis是一个持久化框架,它有不同的语言版本,比如.NET和Java都有MyBatis对应的类库;它有大多数ORM框架都具有的功能,比如程序员自定义的SQL语句、调用存储过程和一些高级的映射。但在这里需要说明的是,它是一种半自动化的ORM映射框架,所以使用方式和Hibernate有非常大的区别。它以SQL语句为映射基础,在使用MyBatis 框架时,可以将SQL语句灵活多变的特性融入项目开发中。
另外,如果使用MyBatis这个框架,还可以省略大多数的JDBC代码,因为它把常用的JDBC操作都进行了封装,可以加快开发效率。MyBatis可以使用XML或Annotations注解的方式将数据表中的记录映射成一个Map或Java POJO实体对象,这也是现在流行ORM的技术方向。比如Hibermate和大多数JPA规范实现者都可以使用Annotations注解的方式来设计程序。
MyBatis操作数据库的步骤
开门见山永远是快速学习一门技术最好的方式。
MyBatis框架的核心是SqlSessionFactory对象,从SqlSessionFactory类的名称来看,它是创建SqlSession对象的工厂。但SqISessionFactory对象的创建来自于SqlSessionFactoryBuilder类,也就是使用SqlSessionFactoryBuilder类创建SqlSessionFactory对象。
使用SqlSessionFactoryBuilder类创建SqlSessionFactory 对象的方式可以来自于一个XML配置文件,也可以来自于一个实例化的Configuration对象。
使用XML配置文件创建SqlSessionFactory对象
package test;
import java. io. IOException;
import java. io. InputStream;
import org .apache. ibatis. io.Resources;
import org. apache. ibatis. session. SqlSessionFactory;
import org. apache. ibatis.session.sqlSessionFactoryBuilder;
public class Test {
public static void main(String[] args) {
try {
String resource = "mybatis-config. xml";
InputStream inputStream = Resources . getResourceAsStream (resource) ;
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ()
. build (inputStream) ;
System. out.println (sqlSessionFactory) ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace () ;
}
}
}
上述代码的主要作用就是取得SqlSessionFactory工厂对象。下面测试代码是否能正常创建SqlSessionFactory类的实例。
其中mybatis-config. xml配置文件连接数据库的内容如下。
<?xml version="1.0" encoding= "UTE-8" ?>
<! DOCTYPE configuration
PUBLIC "-/ /mybatis.org//DTD Config 3.0//EN"
"http://mybatis. org/dtd/mybatis-3-config .dtd">
<configuration>
<envi ronments default= "deve lopment">
<envi ronment id= "development ">
<transactionManager type= "JDBC" />
<dataSource type= "POOLED">
<property name= "driver"
value= "com. microsoft.sqlserver. jdbc. sQLServerDriver" />
<property name= "url"
value= "jdbe:sqlserver ://localhost:1079;databaseName=ghydb" />
<property name= "username" value="sa" />
<property name= "password" value="" />
</dataSource>
</envi ronment>
</envi ronments>
</configuration>
配置文件mybatis-config.xml 中主要定义的就是如何连接数据库,以及连接数据库所必备的username和password及url 等参数。
加入当时最新版的MyBatis框架的jar包,如下图所示。
运行程序后并没有出现异常,输出的信息如下图所示。
到此,SqlSessionFactory 对象成功地从XML配置文件中创建。
SqlSessionFactoryBuilder和SqlSessionFactory类的结构
SqlSessionFactoryBuilder类的架构:
SqlSessionFactory类的结构:
从上面两个图可以看到,两者的类结构中基本上全是重载的方法,主要是为了取得SqlSessionFactory和SqlSession对象。
使用MyBatis针对3种数据库(0racle、MSSQL和MySQL)实现CURD
针对Oracle的CURD
创建userinfo数据表
创建userinfo数据表,表结构如下图所示。
从Eclipse产生逆向的实体类
在Eclipse中新建java项目,名称为oracleGenerator, 添加MyBatis配置文件generatorConfig.xml, 配置代码内容如下。
<?xml version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis
Generator
Configuration 1.0//EN" "http://mybatis. org/dtd/mybatis-generator-config_ 1 0.dtd" >
<generatorConfiguration>
<context id= "oracleGenerator">
<jdbcConnection driverClass= "oracle. jdbc. driver . OracleDriver"
connect ionURL= "jdbc:oracle: thin:@localhost: 1522:accp11g" userId= "ghy"
password="123" />
<j avaMode lGenerator targetPackage= "orm"
targetProject= "oracleGenerator" />
<sqlMapGenerator targetPackage= "orm" targetProject= "oracleGenerator" />
<javaCl ientGenerator targetPackage= "orm"
targetProject= "oracleGenerator" type= "XMLMAPPER" />
<table schema= "ghy" tableName= "userinfo">
<generatedKey column= "id" sqlStatement="select idauto.nextval from dual"
identity="false" />
</table>
</context>
</generatorConfiguration>
根据此配置文件会生成实体类Userinfo.java。
创建Web项目并配置基本开发环境
回到MyEclipse,创建- -个 Web项目,命名为mybatis _curd_ _oracle, 将Eclipse项目oracleGenerator中的m包中的Userinfojava 复制到MyEclipse项目中的src路径下,如下图所示。
实体类Userinfo,java 的类结构如下图所示。
在Web项目mybatis_ curd_ oracle 中的sre路径下创建连接数据库的配置文件mybatis-config.xml,代码如下。
<?xm1 version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-/ /mybatis.org//DTD Config 3.0//EN"
"mybatis-3-config .dtd">
<configuration>
<envi ronments default= "development ">
<environment id= "development ">
<transact ionManager type= "JDBC" />
<dataSource type= "POOLED">
<property name= "driver" value= "oracle. jdbc.driver. OracleDriver" />
<property name= "url" value= "jdbc:oracle: thin:@localhost:1522:accp11g" />
<property name= "username" value= "ghy" />
<property name= "password" value="123" />
</dataSource>
</envi ronment>
</envi ronments>
<mappers>
<mapper resource= "userinfoMapping. xm1" />
</mappers>
</configuration>
其中userinfoMapping.xml映射文件的内容如下。
<?xml version="1.0" encoding= "UTF-8" ?>
<! DOCTYPE mapper PUBLIC "-/ /mybatis.org//DTD Mapper 3.0//EN" "mybatis- 3-mapper . dtd">
<mapper namespace= "mybatis. testcurd">
<insert id= "insertUserinfo" parameterType= "orm. Userinfo">
<selectKey resultType= "java. lang. Long" keyProperty= "id"
order= "BEFORE">
select idauto. nextval from dual
</selectKey>
insert into
userinfo (id, username, password, age, insertDate)
values (#{id},#{username},#{password}, #(age},#{insertdate})
</insert>
<select id= "getUserinfoById" parameterType="int" resultType= "orm. Userinfo">
select from
userinfo where id=#{id}
</select>
<delete id= "dele teUserinfoById" parameterType= "int ">
delete f rom
userinfo where id=#{id}
</delete>
<select id= "getAl lUserinfo" resultType= "orm. Userinfo">
select * from userinfo
</select>
<update id= "upda teUserinfoById" pa rameterType= "orm. Userinfo">
update userinfo
set
username=# {username }, password= # {password} ,age=# {age}, insertDate=# {insertdate}
where id=#{id}
</update>
</mapper>
需要特别说明的是,如果SQL语句有一些特殊字段,则必须按照如下格式使用SQL语句。
<! [CDATA[ sql语句] ]>
其中配置代码如下所示。
<selectKey resultType= "java. lang. Long" keyProperty="id"
order= "BEFORE">
select idauto.nextval from dual
</selectKey>
主要的功能是根据序列对象生成- -个主键id值,并且此值还可以从代码中获取,也就是插入- -条记录后代码就可以获取刚才插入记录的id值。
属性parameterType定义参数的类型,属性resultType 定义返回值的类型。
继续创建测试用的Servlet 对象,完整的项目结构如下图所示。
上图中可以发现src路径下两2个dtd文件,这样为了在开发xml配置或xml映射文件时实现代码自动提示功能。
根据id值查询记录
创建Servlet,核心代码如下
public class getUserinfoById extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// TODO Auto-generated catch block
e.printStackTrace () ;
}
}
}
查询所有记录
创建Servlet,核心代码如下。
public class getAllUserinfo extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Sq1Session sqlSession = GetSqlSession. getSqlSession();
List<Userinfo> listUserinfo = sqlSession
. selectList ("mybatis. testcurd. getAllUserinfo");
for (int i = 0; i< listUserinfo.size(); i++) {
Userinfo userinfo = listUserinfo.get(i);
System. out. println (userinfo.getId() +""
+ userinfo.getUsername() + "”+ userinfo.getpassword(
+ ""+userinfo.getAge() +”"
+ userinfo.getInsertdate() . toLoealeString()) ;
sqlSession. commit() ;
sqlSession.close() ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace() ;
}
}
}
更新记录
创建Servlet,核心代码如下。
public class updateUserinfoById extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
SqlSession sqlSession = GetSqlSession. getSqlSession() ;
Userinfo userinfo = sqlSession.selectOne (
"mybatis. testcurd. getUserinfoById", 7) ;
userinfo. setUsername ("最新版高洪岩") ;
sqlSess ion. update ("mybatis. testcurd. updateUserinfoById", userinfo) ;
sqlSession. commit() ;
sqlSession.close() ;
) catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace() ;
}
}
}
删除记录
创建Servlet,核心代码如下。
public class deleteUserinfoById extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
SqlSession sqlSession = GetSqlSession. getSqlSession() ;
sqlSess ion.delete ("mybatis. testcurd. deleteUserinfoById", 6);
sqlSession. commit() ;
sqlSession.close() ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace() ;
}
}
}
针对MSSQL的CURD
操作MSSQL数据库和操作Oracle数据库的大体步骤相同,在SQL Server数据库中创建数据表,如下图所示。
使用Eclipse逆向实体类
用相同的方法在Eclipse中创建Java 项目,命名为mssqlGenerator,添加MyBatis生成文件,配置内容如下。
<?xml version="1.0" encoding= "UTF-8" ?>
< ! DOCTYPE
generatorConfiguration
PUBLIC
"-//mybatis.org//DTD
MyBatis
Generator
Configuration 1.0//EN" "http://mybatis . org/dtd/ mybatis-generator-config_ 1_ _0.dtd" >
<generatorConfiguration>
<context id= "mssq1Generator ">.
<jdbcConnection dr iverClass= "com.mi crosoft . sqlserver. jdbc . SQLServerDriver"
connect ionURL= "jdbc:sqlserver://localhost : 1079;databaseName=ghydb"
userId="sa" password="" />
<j avaModelGenerator targetPackage= "orm"
targetProject= "mssqlGenerator" />
<sqlMapGenerator targetPackage= "orm" targetProject= "mssqlGenerator" />
<javaCl ientGenerator targetPackage= "orm”
targetProject= "mssqlGenerator" type= "XMLMAPPER" />
<table schema= "dbo" tableName= "userinfo">
<generatedKey column= "id" sqlStatement= "sqlserver"
identity="true" />
</tab1e>
</ context>
</generatorConfiguration>
关键代码如下
<generatedKey column="id" sqlStatement= "sqlserver"
identity= "true' />
它的作用是定义userinfo数据表中的id字段是自增的,不需要显式地设置值。
创建Web项目并搭建基本的开发环境
在MyEclipse中创建Web项目,复制Userinfo.java到Web项目中,并且创建一个连接数据库的配置文件mybatis-config.xml,代码如下。
<?xml version="1.0" encoding= "UTF-8" ?>
<! DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"mybatis-3-config . dtd">
<configuration>
<envi ronments de fault= "devel opment ">
<envi ronment id= "devel opment ">
<transactionManager type= "JDBC" />
<dataSource type= "POOLED">
<property name= "driver"
value= "com. microsoft. sqlserver. jdbc. sQLServerDriver" />
<property name= "urI"
value= "jdbc:sqlserver://1ocalhost: 1079;databaseName =ghydb" />
<property name= "username" value="sa" />
<property name= "password" value="" />
</ dataSource>
</envi ronment>
</envi ronments>
<mappers>
<mapper resource= "userinfoMapping. xml" />
</mappers>
</ configuration>
还要创建sq1映射文件userinfoMapping.xml,代码如下。
<?xml version="I. 0" encoding= "UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis- 3-mapper . dtd">
<mapper namespace= "mybatis. testcurd">
<insert id= "insertUserinfo" parameterType= "orm. Userinfo"
useGeneratedKeys= "true" keyProperty= "id">
insert into
user info (username, password, age, insertDate)
values (# {username}, # {password},#{age}, #{insertdate})
</ insert>
<select id= "getUserinfoById" parameterType= "int" resultType= "orm. Userinfo">
select
from
userinfo where id=#{id}
</select>
<delete id= "deleteUserinfoById" parameterType= "int">
delete from
userinfo where id=#{id}
</delete>
<select id= "getAllUserinfo" resultType= "orm. Userinfo">
select * from userinfo
</select>
<update id= "upda teUserinfoById" parameterType= "orm. Userinfo">
update userinfo
set
username=# {username}, password= # {password} , age=# {age }, insertDate=# {insertdate}
where id=#{id}
</update>
</mapper>
添加记录并且返回主键值
创建Servlet对象,插入记录的代码和Oracle数据库对应的Servlet代码一致, 运行后在控制台输出3条记录的主键ID值,结果如下图所示。
针对MySQL的CURD
在MySQL数据库中创建数据表userinfo,表结构如下图所示。
一定要勾选Auto Increment复选框,以使字段id值实现自增的效果。
使用Eclipse逆向实体类
在Eclipse中创建Java 项目,添加逆向配置文件generatorConfig.xml,代码如下。
<?xml version= "1.0" encoding="UTF-8" ?>
< !DOCTYPE
generatorConfiguration
PUBLIC
"-//mybatis .org//DTD
MyBatis
Generator
Configuration 1.0//EN" "http://mybatis. org/dtd/mybatis-generator-config_ 1_ 0.dtd" >
<generatorConfiguration>
<context id= "mysqlGenerator">
<jdbcConnection driverClass= "com. mysq1. jdbc.Driver"
connect ionURL= "j dbc :mysql ://localhost: 3307/ghydb" userId= "root"
password= "123" />
<javaModelGenerator targetPackage= "orm"
targetProject= "mysqlGenerator" />
<sqlMapGenerator targetPackage= "orm" targetProject= "mysqlGenerator" />
<javaClientGenerator ta rgetPackage= "orm"
targetProject= "mysq1Generator" type= "XMLMAPPER" />
<table schema= "ghydb" tableName= "userinfo">
<generatedKey column= "id" sqlStatement= "mysql" identity="true" />
</table>
</context>
</generatorConfiguration>
创建Web项目并搭建基本的开发环境
在MyEclipse中创建Web项目,命名为mybatis_curd_ mysql, 复制Userinfojava实体类,并且创建一个连接数据库的配置文件mybatis-config.xml,代码如下。
<?xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"mybatis-3-config. dtd">
<configuration>
<envi ronments default= "deve lopment">
<envi ronment id= "development">
<transact ionManager type= "JDBC" />
<dataSource type= "POOLED">
<property name= "driver" value= "com . mysql. jdbc. Driver" />
<property name= "url" value= "jdbc:mysql ://1ocalhost :3307/ghydb" />
<property name= "username" value="root" />
<property name= "password" value="123" />
</dataSource>
</envi ronment>
</envi ronments>
<mappers>
<mapper resource= "userinfoMapping.xml" />
</mappers>
</ configuration>
还要创建SQL映射文件userinfoMapping.xml,代码如下。
<?xml version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis- 3-mapper.dtd">
<mapper namespace= "mybatis. testcurd">
<insert id="insertUserinfo" parameterType= "orm. Userinfo"
useGeneratedKeys= "true" keyProperty= "id">
insert into
user info (username , password, age, insertDate)
values (# {username}, # {password}, #{age}, #{insertdate})
</ insert>
<select id= "getUserinfoById" parameterType= "int" resultType= "orm. Userinfo">
select * from
userinfo where id=#{id}
</select>
<delete id= "deleteUserinfoById" parameterType="int ">
delete from .
userinfo where id=#{id}
</delete>
<select id= "getAllUserinfo" resultType= "orm. Userinfo">
select * from userinfo
</select>
<update id= "upda teUserinfoById" parameterType= "orm. Userinfo">
update userinfo
set
username=# {username }, password=# {password}, age=# {age} , insertDate=#{insertdate}
where id=#{id}
</update>
</mapper>
添加记录并且返回主键值
创建Servlet对象,插入记录的代码和Oracle数据库对应的Servlet代码一致, 运行后在控制台输出3条记录的主键ID值,结果如下图所示。
MyBatis 核心对象的生命周期与封装
在前面对3种数据库实现基本的CURD后,大家应该了解了MyBatis核心对象的使用,本节将会继续介绍这些核心对象的生命周期。
对象的生命周期也就是对象从创建到销毁的过程,但在此过程中,如果实现的代码质量不佳,那么很容易造成程序上的错误或效率的降低。
(1 ) SqlSessionFactoryBuilder对象可以被JVM虚拟机所实例化、使用或者销毁。一旦使用SqlSessionFactoryBuilder对象创建SqISessionFactory后,SqlSessionFactoryBuilder 类就不需要存在了,也就是,不需要保持此对象的状态,可以随意地任由JVM销毁。因此SqlSessioFactoryBuilder对象的最佳使用范围是方法之内,也就是说,可以在方法内部声明SqISessionFactoryBuilder对象来创建SqlSessionFactory对象。
(2) Sq[SessionFactory对象由SqlSessionFactoryBuilder对象创建。一旦创建SqlSessionFactory类的实例,该实例应该在应用程序执行期间都存在,根本不需要每一次操作数据库时都重新创建它,所以应用它的最佳方式就是写一个单例模式,或使用Spring 框架来实现单例模式对SqlSessionFactory对象进行有效的管理。
(3 ) SqlSession 对象由SqlSessionFactory 类创建,需要注意的是,每个线程都应该有它自己的Sq[Session实例。SqlSession的实例不能共享,它也是线程不安全的,所以千万不要在Servlet中声明该对象的一个实例变量。因为Servlet是单例的,声明成实例变量会造成线程安全问题,也绝不能将SqlSession实例的对象放在一个类的静态字段甚至是实例字段中,还不可以将SqlSession实例的对象放在任何类型的管理范围中,比如Servlet对象中的HttpSession 会话。在接收到HTTP请求时,可以打开一个SqlSession对象操作数据库,然后返回响应,就可以关闭它。关闭SqlSession 很重要,应该确保使用finally 块来关闭它。
以上就是笔者为大家整理的mybatis3操作数据库的步骤内容,码字不易,给个关注哦~~~
喜欢文章请多多点赞评论转发,关注笔者,你们的支持就是笔者最大的动力~~~
下一篇: pwn学习系列--任务4 pwn200