目录
- 一、三层架构
- Java中的三层架构指
- (1)三层对应的包
- (2)三层中类的交互
- (3)三层对应的处理框架
- (4)使用三层架构有点
- (5)缺点
- 二、MyBATis
- 1、官方简介
- 2、百度基本信息
- 3、JDBC
- 三、MyBatis入门SqlSession
- 总结
一、三层架构
Java中的三层架构指
1、界面层(User Interface layer;表示层,视图层):接受用户的数据,显示请求的处理结果。使用 web 页面或者手机 app和 用户交互
2、业务逻辑层(Business Logic Layer):接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据
3、数据访问层(Data Access layer):与数据库打交道;主要实现对数据的增、删、改、查。将存储在数据库中的数据提交 给业务层,同时将业务层处理的数据保存到数据库
(1)三层对应的包
界面层: controller包 (servlet)
业务逻辑层: service 包(XXService类)
数据访问层: dao包(XXDao类)
(2)三层中类的交互
用户使用界面层----> 业务逻辑层----->数据访问层(持久层)---->数据库(mysql,oracle等)
(3)三层对应的处理框架
界面层---servlet---springmvc(框架)
业务逻辑层---service类--spring(框架)
数据访问层---dao类--mybatis(框架)
(4)使用三层架构有点
【1】结构清晰、耦合度低, 各层分工明确
【2】可维护性高,可扩展性高
【3】有利于标准化
【4】开发人员可以只关注整个结构中的其中某一层的功能实现
【5】有利于各层逻辑的复用
(5)缺点
【1】降低了系统的性能。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,三层架构必须通过中间层来完成
【2】导致级联的修改。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码
框架( Framework )是构成一类特定软件可复用设计的一组相互协作的类。框架规定了你的应用的体系结构。
它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象怎么协作,以及控制流程。
框架预定义了这些设计参数,以便于应用设计者或实现者能集中精力于应用本身的特定细节
二、MyBatis
1、官方简介
MyBatis官网中文
MyBatis在github地址
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
java bean,pojo,vo,entity,domain可参考
2、百度基本信息
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁 移到了 google code,并且改名为 MyBatis 。
2013 年 11 月迁移到 Github。 iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。
iBATIS 提供的 持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)
3、JDBC
JDBC代码如下
- (1)注册驱动
- (2)获取连接
- (3)获取数据库操作对象
- (4)执行SQL语句
- (5)处理查询结果集
- (6)释放资源
这些导致
- (1)代码比较多,开发效率低
- (2)需要关注 Connection ,Statement, ResultSet 对象创建和销毁
- (3)对 ResultSet 查询的结果,需要自己封装为 List
- (4)重复的代码比较多些
- (5)业务代码和数据库的操作混在一起
String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/mydb"; String user = "root"; String pwd = "123456"; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { //1、注册驱动(连接的数据库) Class.forName(driver); //2、获取连接 conn = DriverManager.getConnection(url,user,pwd); //3、获取数据库操作对象(专门执行sql语句的对象) stmt = conn.createStatement(); //4、执行SQL语句(DQL DML....) String sql = "select empno,empname as name,sal from emp2 where empno=7369"; rs = stmt.executeQuery(sql); //5、处理查询结果集(只有当第四步执行的是select语句的时候,才有处理查询结果集) while (rs.next()){ /* (1)下标取值;下标从 1 开始 */ String empno = rs.getString(1); String empname = rs.getString(2); String sal = rs.getString(3); System.out.println(empno + " " + empname + " " + sal); /* (2)数据类型取值 */ int empno1 = rs.getInt(1); String empname1 = rs.getString(2); Double sal1 = rs.getDouble(3); System.out.println(empno1 + " " + empname1 + " " + sal1); /* (3)字段名取值 */ String empno2 = rs.getString("empno"); //如果执行的SQL语句中有别名,需要使用别名字段取值 String empname2 = rs.getString("name"); String sal2 = rs.getString("sal"); System.out.println(empno2 + " " + empname2 + " " + sal2); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } finally { //6、释放资源;从小到大关闭 if (rs != null) { try { rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (stmt != null) { try { stmt.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (conn != null) { try { 编程客栈 conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } }
MyBatis 是一个基于 java 的持久层ORM( Object Relational Mapping,对象关系映射)框架,内部封装了 jdbc,开发者只需要关注 sql 语句 本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。
MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的 动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回
mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架)
(1)sql mapper:sql映射
把数据库表中的一行数据 映射为 一个java对象
一行数据可以看做是一个java对象;操作这个对象,就相当于操作表中的数据
(2)Data Access Objects(DAOs):数据访问 , 对数据库执行增删改查
MyBatis框架
【1】提供了创建和销毁、关闭Connection ,Statement, ResultSet等对象能力
【2】提供了执行sql语句的能力
【3】提供了循环sql, 把sql的结果转为java对象, List集合的能力
三、MyBatis入门SqlSession
首先以SqlSession的方式使用mybatis框架
首先我们先设置一下maven的本地仓库
1、新建一个数据库,以及一张表user
CREATE TABLE `user` ( `user_id` int(10) NOT NULL COMMENT '用户名ID', `user_name` varchar(100) DEFAULT NULL COMMENT '用户名', `email` varchar(80) DEFAULT NULL COMMENT '用户邮箱', `age` int(5) DEFAULT NULL COMMENT '年龄', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、创建maven的普通Java工程,加入maven的mybatis坐标,mysql驱动坐标
其中,pom.xm开发者_C学习l文件如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany</groupId> <artifactId>mybatis-1</artifactId> <version>1.0.0</version> <properties> <!-- 项目构建使用的编码,避免中文乱码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 源码编译 jdk 版本 --> <maven.compiler.source>1.8</maven.compiler.source> <!-- 运行代码的 jdk 版本 --> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- 单元测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory><!--所在的目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <!-- filtering 选项 false 不启用过滤器, *.property 已经起到过滤的作用了 --> <filtering>false</filtering> </resource> </resources> </build> </project>
3、创建Java实体类User--保存表中的一行数据
package com.mycompany.domain; public class User { private int userId; private String userName; private String email; private int age; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { retur编程客栈n userName; } public void setUserName(String userName) { this.userName = userName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
4、创建持久层的dao接口,定义操作数据库的方法
package com.mycompany.dao; import com.mycompany.domain.User; import java.util.List; public interface UserDao { /** * 查询user列表 * @param user 单个user用户 * @return user的list */ List<User> selectUserList(User user); /** * 插入user * @param user * @return */ int insertUser(User user); }
5、创建一个mybatis使用的配置文件 SQL映射文件
编写SQL语句,一般一个表对应一个SQL映射文件,这个文件就是xml文件
sql映射文件(sql mapper):编写SQL语句,mybatis负责执行这些SQL语句
1.指定约束文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- mybatis-3-mapper.dtd:约束文件名称
2.约束文件作用:限制,检查当前文件中出现的标签,属性必须符合mybatis的要求
3.<mapper>:当前文件根标签(必须的)
- namesace:命名空间(唯一值,自定义字符串;要求使用dao接口的全限定名称)
- 全限定类名:就是类名全称,带包路径的用点隔开,如: java.lang.String
- 即全限定名 = 包名 + 类型
- 非限定类名也叫短名,就是我们平时说的类名,不带包的,如:String
4.数据库增删改查特定标签
- <select>:查询,select语句
- <update>:更新,update语句
- <insert>:插入,insert语句
- <delete>:删除,delete语句
<?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"> <!-- sql映射文件(sql mapper):编写SQL语句,mybatis负责执行这些SQL语句 1、指定约束文件 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> mybatis-3-mapper.dtd:约束文件名称 2、约束文件作用:限制,检查当前文件中出现的标签,属性必须符合mybatis的要求 3、<mapper>:当前文件根标签(必须的) namespace:命名空间(唯一值,自定义字符串;要求使用dao接口的全限定名称) 全限定类名:就是类名全称,带包路径的用点隔开,如: java.lang.String 即全限定名 = 包名 + 类型 非限定类名也叫短名,就是我们平时说的类名,不带包的,如:String 4、数据库增删改查特定标签 <select>:查询,select语句 <update>:更新,update语句 <insert>:插入,insert语句 <delete>:删除,delete语句 --> <mapper namespace="com.mycompany.dao.UserDao"> <!-- <select>标签:查询操作 id:执行SQL语法的唯一标识,mybatis会根据这个id的值来找到要执行的SQL语句 可以自定义,一般要求使用接口中的方法名称 resultType:表示结果类型,SQL语句执行后得到ResultSet结果集,遍历这个结果集得到的Java对象类型 值写Java对象的全限定名称 --> <select id="selectUserList" resultTjavascriptype="com.mycompany.domain.User"> select user_Id,user_Name,email,age from user order by user_Id asc </select> <!--插入操作,字段名和Java实体类中字段保持一致--> <insert id="insertUser"> insert into user values(#{userId},#{userName},#{email},#{age}) </insert> </mapper>
6、创建mybatis的主配置文件 一个项目一个主配置文件
主配置文件提供了数据库的连接信息和SQL映射文件的位置信息
<?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"> <!-- mybatis的主配置文件:主要定义了数据库的配置信息,SQL映射文件的位置 1、约束文件 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> mybatis-3-config.dtd:约束文件名称 2、configuration:根标签 --> <configuration> <!-- settings:mybatis全局行为 --> <settings> <!-- 设置mybatis输出日志 --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> <!-- 环境配置:数据库的连接信息 default:必须和某个environment的id值一样 告诉mybatis使用哪个数据库的连接信息(访问哪个数据库) --> <environments default="development"> <!-- environment:一个数据库的配置,环境 id:一个唯一值(可自定义,表示环境的名称) --> <environment id="development"> <!-- transactionManaer:mybatis的事务类型 type:JDBC(表示使用JDBC中的Connection对象的commit,rollback做事务处理) --> <transactionManager type="JDBC"/> <!-- dataSource:表示数据源,连接数据库的 type:表述数据源的类型,POOLED表示使用连接池 --> <dataSource type="POOLED"> <!-- driver, user, username, password 是固定的,不能自定义。 --> <!-- 数据库驱动类名 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- 连接数据库的URL字符串 --> <property name="url" value="jdbc:mysql://localhost:3306/ssm"/> <!-- 访问数据库的用户名 --> <property name="username" value="root"/> <!-- 访问数据库的密码 --> <property name="password" value="123456"/> </dataSource> </environment> <!--表示线上的数据库,是项目真实使用的库--> <environment id="online"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/> &lwww.devze.comt;property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- sql mapper(SQL映射文件)的位置 --> <mappers> <!-- 一个mapper标签指定一个文件的位置 从类路径开始的路径信息(target/classes)类路径 --> <mapper resource="com/mycompany/dao/UserDao.xml"/> </mappers> </configuration>
7、创建使用mybatis测试类(通过mybatis访问数据库)
public class TestMyBatis { /** * 查询user列表 */ @Test public void testSelectUserList(){ try { //访问mybatis读取user数据 //1、定义mybatis主配置文件名称,从类路径的根开始(target/clasess) String config = "mybatis-config.xml"; //2、读取config表示的文件 InputStream in = Resources.getResourceAsStream(config); //3、创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //4、创建SqlSessionFactory对象 SqlSessionFactory factory = builder.build(in); //5、获取SqlSession对象,从SqlSessionFactory中获取SqlSession(非自动提交事务,如果增删改需要手动提交事务) SqlSession sqlSession = factory.openSession(); //6、指定要执行的SQL语句标识;sql映射文件中的 namespace + "." + 标签的id值 String sqlId = "com.mycompany.dao.UserDao.selectUserList"; //7、执行sql语句,通过sqlId找到语句 List<User> userList = sqlSession.select编程客栈List(sqlId); //8、输出结果 for (User user:userList){ System.out.println("查询用户="+user); } //9、关闭SQLSession对象 sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 查询user列表 */ @Test public void testMyBatisUtil(){ try { SqlSession sqlSession = MyBatisUtil.getSqlSession(); String sqlId = "com.mycompany.dao.UserDao.selectUserList"; //7、执行sql语句,通过sqlId找到语句 List<User> userList = sqlSession.selectList(sqlId); //8、输出结果 for (User user:userList){ System.out.println("查询用户="+user); } //9、关闭SQLSession对象 sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 插入 */ @Test public void testInsertUser(){ SqlSession sqlSession = null; try { sqlSession = MyBatisUtil.getSqlSession(); String sqlId = "com.mycompany.dao.UserDao.insertUser"; //7、执行sql语句,通过sqlId找到语句 User user = new User(); user.setUserId(5); user.setUserName("zhangfei"); user.setEmail("zangfei@163.com"); user.setAge(16); int nums = sqlSession.insert(sqlId,user); //mybatis默认不是自动提交事务的, 所以在insert ,update ,delete后要手工提交事务 sqlSession.commit(); System.out.println("更新用户条数="+nums); //9、关闭SQLSession对象 sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } }
我们将SqlSession提取为工具类MyBatisUtil
public class MyBatisUtil { public MyBatisUtil() { } public static SqlSession getSqlSession() throws IOException { String config = "mybatis-config.xml"; InputStream ins = Resources.getResourceAsStream(config); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(ins); SqlSession sqlSession = factory.openSession(); return sqlSession; } }
(1)Resources
mybatis中的一个类, 负责读取主配置文件
//1、定义mybatis主配置文件名称,从类路径的根开始(target/clasess) String config = "mybatis-config.xml"; //2、读取config表示的文件 InputStream in = Resources.getResourceAsStream(config);
(2)SqlSessionFactoryBuilder :
创建SqlSessionFactory对象
//3、创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //4、创建SqlSessionFactory对象 SqlSessionFactory factory = builder.build(in);
(3)SqlSessionFactory
重量级对象, 程序创建一个对象耗时比较长,使用资源比较多;在整个项目中,有一个就够用
SqlSessionFactory
:接口 ,接口实现类: DefaultSqlSessionFactorySqlSessionFactory
作用:获取SqlSession对象
SqlSession sqlSession = factory.openSession();
openSession()方法
【1】openSession() :无参数的, 获取是非自动提交事务的SqlSession对象
【2】openSession(boolean):
openSession(true)
获取自动提交事务的SqlSessionopenSession(false)
非自动提交事务的SqlSession对象
(4)SqlSession
SqlSession接口 :定义了操作数据的方法
例如 selectOne() ,selectList() ,insert(),update(),delete(),commit(),rollback()
SqlSession接口的实现类DefaultSqlSession。
使用要求: SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。
在执行完sql语句后,需要关闭它,执行SqlSession.close();这样能保证他的使用是线程安全的
9、整个mybatis框架的maven模块目录如下
10、常见报错问题
(1)找不到mybatis-config.xml文件或者对应的dao以及SQL映射文件
有如下三种解决方案
【1】clean一下,然后compile一下,会重新生成target目录
【2】Rebuild Project,再重新运行,就会在target目录下出现mybatis-config.xml文件
【3】以上两种方式不行,直接手动将src/resources/mybatis-config.xml文件拷贝至target/classes目录下
(2)dao接口的 方法 和 dao.xml映射文件中的 id 要保持一致
(3)数据库表中的列名,要和Java实体类中的字段,dao.xml映射文件的属性字段保持一致
11、 junit : 单元测试
- junit:单元测试, 一个工具类库,做测试方法使用的。
- 单元:指定的是方法, 一个类中有很多方法,一个方法称为单元
使用单元测试
(1)需要加入junit依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
(2)创建测试类
src/test/java目录中创建类
(3)创建测试方法
【1】public 方法
【2】没有返回值 void
【3】方法名称自定义,建议名称是test + 测试方法名称
【4】方法没有参数
【5】方法的上面加入 @Test ,方法可以单独执行;不用使用main方法
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。
精彩评论