需求:idea下新建工作空间,连接oracle数据库,使用持久层框架mybatis实现数据库dept表的增删改查。
第一步:创建项目
项目创建完成之后的初始状态
注意
此处点击import change 引入的改变就是导入了一个测试的依赖jar包。应该只有junit的依赖,拉图的 时候多拉了一个。不好意思。
- junit:通过@test注解,可以快速完成单元测试。
第一步已经完成,项目初始状态已经创建成功。
第二步:导入依赖的jar包
- 首先导入mybatis的依赖
进入网站https://mvnrepository.com/artifact/org.mybatis/mybatis/3.4.6
复制以下代码到<dependency标签里
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
点击import changes 引入依赖
引入mybatis依赖成功
第三步:mybatis的项目构建
在main文件包下新建三个directory文件夹,右键MysecondMaven–>New–>Directory,分别新建三个文件夹
- java:以后存放java代码
- resources:存放配置文件
- test:放测试类(可有可无)
- 修改三个文件夹的属性。
- 点击Project Structure
- 分别选中变色(更改文件夹属性)
- 变完色,就可以ok了
配置mybatis
- 在resourcses文件夹下新建一个xml文件,文件名可以叫mybatis-config.xml[可以随便起,最好见名知意啦啦~]
- 进入mybatis官网:http://www.mybatis.org/mybatis-3/zh/getting-started.html
- 复制以下代码
<?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">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
配置文件代码解释:
- environments \transactionManager
<!--环境配置,可以配置多个环境链接不同的数据源-->
<environments default="development">
<!--事务管理器 JDBC 自定处理事务 MANAGERD 事务交给容器管理-->
<transactionManager type="JDBC"/>
- dataSource -->property \ mappers
- 这里我们主要关注连接数据库4要素&mappers
<!--数据源配置,链接数据库的4要素 POOLED 使用链接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
这个是官网dome的xml,跟本项目无关
<!--mappers 元素则是包含一组 mapper 映射器
(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息)-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
- 该复制的代码已经复制好了,下面我们就来更改连接数据库4要素和mappers
- 首先更改username和password(挑软柿子捏,因为他俩最简单),将oracle的用户名和密码填进去。
- 其次更改url,oracle的url为:jdbc:oracle:thin:@localhost:1521:orcl。
- thin是oracle的一种驱动模式 它还有别的驱动模式 比如oci(到网上找的解释,和计算机网络只是有关,我也看不懂,懂的人滴滴我。)
- 再其次更改driver,oracle的driver为: **oracle.jdbc.driver.OracleDriver ** (这个可以找到,等一会导入Oracle的依赖之后我在找一下,暂时写上去。)
- 展示一下4要素最后的结果:
<!--数据源配置,链接数据库的4要素 POOLED 使用链接池-->
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="username" value="scott"/>
<property name="password" value="luruihua"/>
</dataSource>
- 最后mapper也是这几个里面最麻烦的,听我慢慢道来~
第四步:实体类的配置
- 在resources文件夹下新建mapper文件夹 --》然后改变mapper的属性为resources(参考上面变颜色)–》新建一个xml文件DeptDaoImplMapper.xml
- 解释:每张表对应一个xml文件,对这张表的增删改查都可以写入这个xml文件夹中,我的demo主要实现dept表的增删该查,也可以看作一个dao的实现类,所以起名字为DeptDaoImplMapper.xml
- 同样进入mybatis官网:http://www.mybatis.org/mybatis-3/zh/getting-started.html
- 复制以下代码,注释是我自己加的。
<?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="org.mybatis.example.BlogMapper">
<!--属性id必写,查有resultType(返回结果)和parameterType(参数类型)-->
<!--增删改没有返回结果-->
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
- 经过听课,我的个人理解,每个表就相当于一个实体类,表中的每个字段都对应这个实体类中的一个私有属性,在这个实体类中可以生成构造方法或者get&set方法来传入值和取值。所以我现在要在java包下创建一个实体类,名字叫Dept,对应的是我的oracle数据库中的dept表。
select 标签的id写的是查的方法名,resultType写的是返回结果的全类名。
开始了~
- 新建实体类:
- 位置如下:
- 代码如下:
package com.aaa.mb.entity;
/**
* className:Dept
* discription:芦瑞华
* author:luRuiHua
* createTime:2018-11-13 16:37
*/
public class Dept {
private Integer deptno;
private String dname;
private String loc;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
- 创建dao层接口
位置如下:
代码如下:
package com.aaa.mb.dao;
import com.aaa.mb.entity.Dept;
import java.util.List;
/**
* className:DeptDao
* discription:
* author:luRuiHua
* createTime:2018-11-13 16:53
*/
public interface DeptDao {
/**
* 查询方法
* @return
*/
public List<Dept> getList();
/**
* 增加的方法
* @param dept
* @return
*/
public int insertDept(Dept dept);
}
- SqlSessionFactoryUtil
位置如下:
代码如下:
package com.aaa.mb.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* className:SqlSessionFactoryUtil
* discription:该工具类创建 SqlSessionFactory(官网建议单例模式)并生成 SqlSession
* author:ZhangSenYao
* createTime:2018-11-13 09:13
*/
public class SqlSessionFactoryUtil {
/**
* 私有构造,防止在其他类实例化对象
*/
private SqlSessionFactoryUtil() {}
/**
* 私有的,静态的属性
*/
private static SqlSessionFactory sqlSessionFactory;
/**
* 静态代码块根据配置文件创建 SqlSessionFactory
* 没有名字是为了保证其他地方不能调用,伴随类的产生执行一次
*/
static {
try {
//使用Mybatis提供给我们的类Resources加载主配置文件,生成字节流
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//使用生成的字节流和SqlSessionFactoryBuilder构建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 提供一个对外开放的方法,生成 SqlSession
*/
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}
代码理解:这里是重点。
- SqlSessionFactory这里引用官网。
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用
SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory
被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory
的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
我不太能看懂,我理解的意思,就是需要一个SqlSessionFactory,而且保证这个类是用单例模式,因为单例模式在整个项目的作用域中只加载一个,不用重复加载。
-
单例模式的一种方式:私有构造,私有属性,对外开放一个方法返回需要接收的类(SqlSession)。
-
目的是获取SqlSession对象,那么如何获得?
使用Mybatis框架提供的给我们的类Resources加载主配置文件,生成字节流对象,使用生成的字节流和SqlSessionFactoryBuilder构建SqlSessionFactory,使用SqlSessionFactory生成SqlSession对象,哦呦,竟然获得了,美滋滋~。 -
现在就可以配置我们的DeptDaoImplMapper的mapper标签里的内容了,终于到这一步了。
-
DeptDaoImplMapper.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="com.aaa.mb.dao.DeptDao">
<!--属性id必写,查有resultType(返回结果)和parameterType(参数类型)-->
<!--增删改没有返回结果-->
<select id="getList" resultType="com.aaa.mb.entity.Dept" >
select deptno, dname, loc from dept ;
</select>
<!--增,没有返回结果,有携带参数类型-->
<insert id="insertDept" parameterType="com.aaa.mb.entity.Dept">
insert into dept values (#{deptno}, #{dname}, #{loc})
</insert>
</mapper>
- 这个时候就可以配置mybatis-config.xml里面的<mapper的标签了(我都准备测试了报错后才想起来。这步不能忘,主要是离前面太远了,写写写忘了。略略略~)
<!--mappers 元素则是包含一组 mapper 映射器(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息)-->
<mappers>
<mapper resource="mapper/DeptDaoImplMapper.xml"/>
</mappers>
好了,万事具备只欠oracle的jar包依赖了!
第五步:Oracle的jar包导入依赖
- 这里比较扯,因为oracle的版权问题,付费的我的dome承受不起,下面用一种老师教的野方法来导入依赖。
找到这个jar包,安装oracle的时候里面就有。把他复制到D盘的根目录下。
- 打开黑窗口,复制下面这段dos命令。
- Dfile=路径名(绝对路径)
- 包名,项目名,版本,文件类型。按需下载,我发这个就可以。
mvn install:install-file -Dfile=D:\ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.4.0 -Dpackaging=jar
运行结果:
- success成功!本地仓库已经有这个jar包了,oracle的jar包已经安装好了。这个时候可以导入依赖了。
- 复制以下代码到pom.xml文件的dependencies标签里面
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4.0</version>
</dependency>
import changes引入改变。
引入成功。
最后一步:编写测试类
- 这个时候刚开始导入的junti依赖派上用场。
- 类的位置
- 先上代码:
package com.aaa.mb.test;
import com.aaa.mb.dao.DeptDao;
import com.aaa.mb.entity.Dept;
import com.aaa.mb.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* className:DeptTest
* discription:
* author:luruihua
* createTime:2018-11-13 11:09
*/
public class DeptTest {
/**
* 查询的
*/
@Test
public void testSelect() {
SqlSession sqlSession = SqlSessionFactoryUtil.getSession();
DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
//循环遍历
List<Dept> deptList = deptDao.getList();
if (deptList != null && deptList.size() > 0) {
for (Dept dept : deptList) {
System.out.println("部门名称:" + dept.getDname());
}
}
}
/**
* 增加的
*/
@Test
public void insertDept() {
//
SqlSession sqlSession = null;
try {
//使用SqlSessionFactoryUtil的工具类获取session
sqlSession = SqlSessionFactoryUtil.getSession();
//使用sqlSession来获取接口的实现类
DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
//---------模拟set数据------------------------
Dept dept = new Dept();
dept.setDeptno(67);
dept.setDname("马马勋部");
dept.setLoc("mama楼");
//-------------------------------------------
int i = deptDao.insertDept(dept);
if (i > 0) {
System.out.println("添加成功!");
sqlSession.commit();
} else {
System.out.println("添加失败!");
sqlSession.rollback();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭session域
if(sqlSession != null) {
sqlSession.close();
}
}
}
- 代码解释
//使用SqlSessionFactoryUtil的工具类获取session
sqlSession = SqlSessionFactoryUtil.getSession();
//使用session来获取接口的实现类
DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
引用官网:
SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession
的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession
实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如
Servlet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP
请求对象相似的作用域中。换句话说,每次收到的 HTTP 请求,就可以打开一个
SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。
总的意思就是每个sqlSession都需要关闭。
执行
- 添加的结果
- 查询的结果
结束。
如有问题多多指正!谢谢!