三层架构
- 软件开发常用的架构是三层架构,三层架构可以清晰的划分不同层次的开发任务。
- 三层架构一般包括以下三层:
- 持久层:主要完成与数据库相关的操作,即对数据库的增删改查。因为数据库访问的对象一般称为Data Access Object(简称DAO),所以也有把持久层叫做DAO层。
- 业务层:主要根据功能需求完成业务逻辑的定义和实现。业务层主要是为上层提供服务的,所以把业务层叫做Service层
- 表现层:主要完成与最终软件使用用户的交互,需要有交互界面(UI),即把表现层称之为web层
- 三层架构之间调用关系为:表现层调用业务层,业务层调用持久层,一般使用Java实体对象在在各层之间传递数据。
什么是框架?
- 框架就是一套规范,使用这个框架就要遵守这个框架所规定的约束。框架可以理解为半成品软件,框架封装好了一些冗余,且重用率低的代码。框架做好以后,接下来在它基础上进行开发。
常见的框架
- Java的框架非常的多,每一个框架都是为了解决某一部分或某些问题而存在的。流行的几种框架(解决不同层次问题的)。
- 持久层框架:专注于解决数据持久化的框架。有mybatis,spring,jdbc等等。
- 表现层框架:专注于解决与用户交互的框架。有spring mvc。
- 全栈框架: 能在各层都给出解决方案的框架。比较著名的就是spring。
原始jdbc操作存在的问题
- MyBatis 属于持久层框架,Mybatis和jdbc有很大的区别,完整的使用jdbc操作数据如下:
public static void main(String[] args) throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db4", "root", "123456");
//3.获取语句执行平台对象
Statement statement = con.createStatement();
//4.执行查询操作 使用executeQuery()
String sql = "SELECT * FROM jdbc_user;";
//resultSet 是结果集对象
ResultSet resultSet = statement.executeQuery(sql);
//通过while循环 遍历获取 resultSet中的数据
while(resultSet.next()){
//获取id
int id = resultSet.getInt("id");
//获取姓名
String username = resultSet.getString("username");
//获取密码
String password = resultSet.getString("password");
//获取生日
Date birthday = resultSet.getDate("birthday");
System.out.println(id+" : " + username+" : " + password + " : " + birthday);
}
//5.关闭流操作
resultSet.close();
statement.close();
con.close();
}
- 在使用原始jdbc操作数据库时,存在如下问题:
- 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
- sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变java代码。
- 查询操作时,需要手动将结果集中的数据手动封装到实体中。
- 在Mybatis中,可以将sql语句写在xml配置文件中,并且Mybatis可以将实体跟表之间进行属性和字段的自动映射
MyBatis—ORM思想
- MyBatis是一个优秀的基于ORM的半自动轻量级持久层框架。MyBatis对jdbc的操作数据库的过程进行封装,在使用MyBatis进行开发时只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码
- ORM思想:ORM(Object Relational Mapping)对象关系映射
- O(对象模型):实体对象,即在程序中根据数据库表结构建立的实体javaBean
- R(关系型数据库的数据结构):关系数据库领域的Relational(建立的数据库表)
- M(映射):从R(数据库)到O(对象模型)的映射,可通过XML文件映射
- 实现流程:
- 让实体类和数据库表进行一一对应关系,先让实体类和数据库表对应,再让实体类属性和表里面字段对应。
- 不需要直接操作数据库表,直接操作表对应的实体类对象
- ORM作为是一种思想帮助我们跟踪实体的变化,并将实体的变化翻译成sql脚本,执行到数据库中去,也就是将实体的变化映射到了表的变化。
- mybatis采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,可以不用再通过jdbc api 就可以完成对数据库的持久化操作
MyBatis_CRUD
-
entity :User实体类,
@Data @AllArgsConstructor @NoArgsConstructor @ToString public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; }
-
Mapper映射文件:UserMapper.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="userMapper"> <!-- namespace : 命名空间:与id属性共同构成唯一标识 namespace.id: user.findAll resultType: 返回结果类型(自动映射封装):要封装的实体的全路径 --> <!-- 查询User所有用户信息 --> <select id="findAll" resultType="com.code.entity.User"> select * from user </select> </mapper>
-
MyBatis核心文件
<?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> <!--加载properties文件--> <properties resource="jdbc.properties"></properties> <!--设置别名--> <typeAliases> <!--方式一:给单个实体起别名--> <!-- <typeAlias type="com.code.entity.User" alias="user"></typeAlias>--> <!--方式二:批量起别名 别名就是类名,且不区分大小写--> <package name="com.code.entity"/> </typeAliases> <!--环境配置--> <environments default="development"> <!--使用MySQL环境--> <environment id="development"> <!--使用JDBC类型事务管理器--> <transactionManager type="JDBC"></transactionManager> <!--使用连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--加载映射配置--> <mappers> <mapper resource="mapper/UserMapper.xml"></mapper> </mappers> </configuration>
-
编写Java测试类
@Test public void testFindAll() throws Exception { // 加载核心配置文件 InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml"); // 获取SqlSessionFactory工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); // 获取SqlSession会话对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 执行sql List<User> list = sqlSession.selectList("userMapper.findAll"); for (User user : list) { System.out.println(user); } // 释放资源 sqlSession.close(); }
MyBatis_新增
-
新增User用户的映射文件UserMapper.xml
<!--在User表中新增用户数据--> <!-- #{} : mybatis中的占位符,等同于JDBC中的 ? parameterType :指定接收到的参数类型 --> <insert id="saveUser" parameterType="com.code.entity.User"> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert>
-
测试类:
/*测试新增User用户*/ @Test public void testSave() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(true); User user = new User(); user.setUsername("jack111"); user.setBirthday(new Date()); user.setSex("男"); user.setAddress("北京海淀"); // 插入操作使用的API是sqlSession.insert(“命名空间.id”,实体对象); // 涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession.commit() sqlSession.commit(); sqlSession.insert("userMapper.saveUser", user); sqlSession.close(); }
MyBatis_修改
-
修改User用户数据,映射文件UserMapper.xml
<!--修改User表中用户数据信息--> <update id="updateUser" parameterType="com.code.entity.User"> update user set username = #{username},birthday = #{birthday},sex = #{sex},address = #{address} where id = #{id} </update>
-
测试类
/*测试在User表中修改用户数据*/ @Test public void testUpdate() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setId(5); user.setUsername("lucy"); user.setBirthday(new Date()); user.setSex("女"); user.setAddress("北京朝阳"); sqlSession.update("userMapper.updateUser", user); // 手动提交事务 sqlSession.commit(); sqlSession.close(); }
MyBatis_删除
-
删除User表中用户数据,映射文件UserMapper.xml
<!--删除User表中用户数据信息--> <!--Sql语句中使用#{任意字符串}方式引用传递的单个参数(最好使用规范名称)--> <delete id="deleteUser" parameterType="com.code.entity.User"> delete from user where id = #{id} </delete>
-
测试类
/*测试在User表中删除用户数据*/ @Test public void testDelete() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); // 删除操作使用的API是sqlSession.delete(“命名空间.id”,Object); sqlSession.delete("userMapper.deleteUser", 5); sqlSession.commit(); sqlSession.close(); }