为什么会产生 Hibernate Mybatis 这类的dao层框架

传统的jdbc 虽然执行速度很快,但是开发效率很低,随着面向对象开发的设计思想,在面向对象编程中 将对象 进行持久化,存入关系型的数据库时,由于关系型数据库的设计思想是数学思维,在持久化时,必须要对象拆分各个属性值,才可存入数据库;传统的jdbc 持久化时 对象持久化时 ,取出对象的一个一个属性,过去繁琐,并且不便于维护,而市场上的面向对象的数据库还并不成熟,所以为了调节面向对象设计的开发思想与落后的关系型数据库之间持久化时繁琐的问题,产生了一种新的设计规范

ORM (Object Relation Mapping) 

对象关系映射,是一种规范,调节目前面向对象的程序设计与主流的关系型数据库之间 发展不同步的问题,
关系 到对象的映射;
让编程时 可以全身心的用面向对象的设计思想去编程,用对象映射关系数据表,在持久化时,可以直接操作对象进行持久化。
优点:
开发效率高;
可维护性高;
缺点:
高效率的开发 对应也要失去性能,处理复杂关系时,性能会变差;
 

Spring对数据库的操作在jdbc上面做了深层次的封装,也就是工具类 jdbcTemplate

先看一下jdbcTemplate的大致流程图

作用:

1: 它提供了AOP式的事务管理

AOP式的事物管理:在以前的事务管理是要融合在逻辑代码中的,在逻辑代码中决定事务是否提交或者回滚,这样很容易造成代码难以维护,代码冗余
但是使用spring的声明式事务后,只需要在数据库处理方法上注解事务,就可以对操作进行管理,事务的设置和逻辑代码分开,容易维护。

不修改原有代码 重新封装现有的组件
类似于: FileWrite fw = new FileWrite();
PrintWrinter pw = new Prinwriter(fw);
2:spring 提供了统一的异常处理,框架处理了异常。
不论Dao层运用什么技术实现 出现的错误全部封装成了DatyaAccessException
如何使用 
1 引入相应spring jar包 + 数据库驱动包
2  在spring的主配置文件中配置 jdbcTemplate
  1. <!-- 定义template组件 -->
  2. <bean id="template"
  3. class="org.springframework.jdbc.core.JdbcTemplate">
  4. <!-- 注入连接信息 -->
  5. <property name="dataSource" ref="bonecp">
  6. </property>
  7. </bean>

定义组件时 template需要一个数据连接池 来管理数据库连接

数据连接池 有很多种 这里用的是

  1. com.alibaba.druid.pool.DruidDataSource
  1. <!-- DataSource 数据源 连接池 存储管理大量的链接 流行的 dbcp c3p0,proxool -->
  2. <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
  3. <bean id="bonecp" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  4. <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
  5. <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  6.  
  7. <!-- 基本属性 url、user、password -->
  8. <property name="url" value="jdbc:mysql://localhost:3306/medicine?useUnicode=true&amp;characterEncoding=utf-8" />
  9. <property name="username" value="root" />
  10. <property name="password" value="root" />
  11.  
  12. <!-- 配置获取连接等待超时的时间 -->
  13. <property name="maxWait" value="60000" />
  14.  
  15. <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
  16. <property name="timeBetweenEvictionRunsMillis" value="60000" />
  17.  
  18. <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
  19. <property name="minEvictableIdleTimeMillis" value="300000" />
  20.  
  21. <property name="testWhileIdle" value="true" />
  22. <property name="testOnBorrow" value="false" />
  23. <property name="testOnReturn" value="false" />
  24.  
  25. <!-- 配置监控统计拦截的filters -->
  26. <property name="filters" value="stat" />
  27. </bean>

下一部是根据表 编写实体类

实体类

  1. package com.mxp.jdbc.entity;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class User implements Serializable {
  6.  
  7. /**
  8. *
  9. */
  10. private static final long serialVersionUID = 1L;
  11. private String id;
  12. private String userName;
  13. public String getId() {
  14. return id;
  15. }
  16. public void setId(String id) {
  17. this.id = id;
  18. }
  19. public String getUserName() {
  20. return userName;
  21. }
  22. public void setUserName(String userName) {
  23. this.userName = userName;
  24. }
  25.  
  26. }

还需要根据实体类写一个rowmapper

注意这里要继承

  1. org.springframework.jdbc.core.RowMapper,然后重写maprow方法
  1. package com.mxp.jdbc.entity;
  2.  
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5.  
  6. import org.springframework.jdbc.core.RowMapper;
  7.  
  8. /**
  9. * 每个实体类都有这个封装组件
  10. * 将User记录封装成 User对象
  11. * @author Administrator
  12. *
  13. */
  14. public class UserRowMapper implements RowMapper<User>{
  15.  
  16. /**
  17. * arg1:第几行记录
  18. */
  19. @Override
  20. public User mapRow(ResultSet arg0, int arg1) throws SQLException {
  21. User user = new User();
  22. user.setId(arg0.getString("id"));
  23. user.setUserName(arg0.getString("user_name"));
  24. return user;
  25. }
  26.  
  27. }

下面可以编写dao了 编写之前我们在spring的主配置文件中要把spring的扫描组件启动

  1. <!-- spring组件扫描 -->
  2. <context:component-scan base-package="com.mxp">
  3. </context:component-scan>

dao

  1. package com.mxp.jdbc.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7. import org.springframework.stereotype.Repository;
  8.  
  9. import com.mxp.jdbc.entity.User;
  10. import com.mxp.jdbc.entity.UserRowMapper;
  11.  
  12. @Repository
  13. public class ItinerantDAO {
  14. @Autowired
  15. private JdbcTemplate template;//注入的方式
  16. public void save(User user){
  17. String sql = "insert into test_user" +
  18. "(id,user_name) values (?,?)";
  19. Object[] params = {
  20. user.getId(),user.getUserName()
  21. };
  22. template.update(sql, params);
  23. }
  24. public List<User> findAll(){
  25. String sql ="select * from test_user";
  26. UserRowMapper rowMapper = new UserRowMapper();
  27. List<User> list = template.query(sql, rowMapper);
  28. return list;
  29. }
  30.  
  31. }

那现在就可以写测试方法

  1. package test;
  2.  
  3. import java.io.IOException;
  4.  
  5. import java.util.List;
  6.  
  7. import org.apache.ibatis.session.SqlSession;
  8.  
  9. import org.springframework.context.ApplicationContext;
  10. import org.springframework.context.support.ClassPathXmlApplicationContext;
  11.  
  12. import com.mxp.ControllerQW;
  13.  
  14. import com.mxp.jdbc.dao.ItinerantDAO;
  15. import com.mxp.jdbc.entity.User;
  16. import com.mxp.mybatis.util.MybatisUtil;
  17.  
  18. public class Test {
  19. public static void main(String[] args) {
    //spring的主配置文件名
  20. String conf = "spring-context.xml";
  21. ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
  22. ItinerantDAO dao = ac.getBean("itinerantDAO",ItinerantDAO.class);
  23. User user = new User();
  24. user.setId("1455");
  25. user.setUserName("文森特");
  26. dao.save(user);
  27. }
  28.  
  29. @org.junit.Test
  30. public void test(){
  31. String conf = "spring-context.xml";
  32. ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
  33. ItinerantDAO dao = ac.getBean("itinerantDAO",ItinerantDAO.class);
  34. List<User> list = dao.findAll();
  35. for(User u:list){
  36. System.out.println(u.getUserName());
  37. }
  38.  
  39. }
  40.  
  41. }

这jdbcTemplate 见的次数很少 至今为止 还没有见到用的 

Mybatis

原来在我们使用jdbc的问题

1 对数据库的连接 使用时就创建连接,不使用就立即释放,对数据库进行频繁连接开启和关闭,造成数据库的资源浪费,影响数据库的性能;

解决办法:使用数据库连接池,管理数据库的连接。

2 将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护,

解决办法:把sql语句I定义到xml配置文件里;

3 在向statement中设置参数,对站位符位置和设置参数数值,硬编码到java代码中,

4 从result结果集中遍历数据时,存在硬编码,讲获取表的字段名硬编码,不便于维护,

讲结果集 自动映射成java对象

mybatis的架构

是一个持久层的项目,是阿帕奇的顶级项目,

通过 mybatis提供的映射方式,半自动的生成sql,大部分还是需要程序员编写sql

核心:输入映射:可以将statement中的输入参数自动输入到映射 通过ongl表达式,将查询的结果集灵活映射成为java对象(输出映射)

mybatis的结构
那么说一下myabtis的大致工作流程

1、  mybatis配置

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2、  通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3、  由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、  mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5、  Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

6、  Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7、  Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

 
第一步主配置文件
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
  3. <configuration>
  4. <environments default="environment">
  5. <environment id="environment">
  6. <transactionManager type="JDBC" />
  7. <!-- mybatis 自带连接池 -->
  8. <dataSource type="POOLED">
  9. <property name="driver" value="com.mysql.jdbc.Driver"/>
  10. <property name="url" value="jdbc:mysql://localhost:3306/medicine?useUnicode=true&amp;characterEncoding=utf-8" />
  11. <property name="username" value="root" />
  12. <property name="password" value="root" />
  13. </dataSource>
  14. </environment>
  15. </environments>
  16. <!-- 定义sqlMapper文件位置的 -->
  17. <mappers>
  18. <mapper resource="com/mxp/mybatis/entity/UserMapper.xml" />
  19. </mappers>
  20. </configuration>

第二步 实体类及其sqlmap映射文件

  1. package com.mxp.mybatis.entity;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class User implements Serializable {
  6.  
  7. /**
  8. *
  9. */
  10. private static final long serialVersionUID = 1L;
  11. private String id;
  12. private String userName;
  13. public String getId() {
  14. return id;
  15. }
  16. public void setId(String id) {
  17. this.id = id;
  18. }
  19. public String getUserName() {
  20. return userName;
  21. }
  22. public void setUserName(String userName) {
  23. this.userName = userName;
  24. }
  25.  
  26. }
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.mxp.mybatis.entity.UserMapper">
  4.  
  5. <sql id="userColumns">
  6. a.id AS "id",
  7. a.user_name AS "userName"
  8. </sql>
  9.  
  10. <select id="findAll" resultType="com.mxp.mybatis.entity.User" >
  11. SELECT <include refid="userColumns"/>
  12. FROM test_user a
  13. </select>
  14.  
  15. <select id="findLikeName" parameterType="string" resultType="com.mxp.mybatis.entity.User" >
  16. SELECT <include refid="userColumns"/>
  17. FROM test_user a
  18. <where>
  19. a.user_name like #{name}
  20. </where>
  21.  
  22. </select>
  23.  
  24. </mapper>

第三部 获取sqlsession

  1. package com.mxp.mybatis.util;
  2.  
  3. import java.io.InputStream;
  4.  
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  8. public class MybatisUtil {
  9.  
  10. public static SqlSession getInsertance(){
  11. SqlSessionFactoryBuilder builder =
  12. new SqlSessionFactoryBuilder();
  13. //这是读取文件后 形成一个输入流 涨知识了
  14. //Test 其实就是一个类型 写自己的什么类型都行 主要是为了获取到getClassLoader().getResourceAsStream
  15. InputStream reader = MybatisUtil.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
  16. //获取sqlsessionFactory
  17. SqlSessionFactory factory = builder.build(reader);
  18. //获取session
  19. SqlSession session = factory.openSession();
  20. return session;
  21. }
  22.  
  23. }

第四部 写测试类

  1. package test;
  2.  
  3. import java.io.IOException;
  4.  
  5. import java.util.List;
  6.  
  7. import org.apache.ibatis.session.SqlSession;
  8. import com.mxp.mybatis.util.MybatisUtil;
  9.  
  10. public class Test {
  11.  
  12. @org.junit.Test
  13. public void getSqllSession() throws IOException{
  14.  
  15. SqlSession session = MybatisUtil.getInsertance();
  16. System.out.println("获取session");
  17. session.close();
  18. }
  19. @org.junit.Test
  20. public void findall(){
  21. SqlSession sqlsession = MybatisUtil.getInsertance();
  22. List<com.mxp.mybatis.entity.User> list = sqlsession.selectList("findAll");
  23. for(com.mxp.mybatis.entity.User u:list){
  24. System.out.println(u.getUserName());
  25. }
  26. sqlsession.close();
  27.  
  28. }
  29. @org.junit.Test
  30. public void findLike(){
  31. SqlSession sqlsession = MybatisUtil.getInsertance();
  32. List<com.mxp.mybatis.entity.User> list = sqlsession.selectList("findLikeName","%文%");
  33. for(com.mxp.mybatis.entity.User u:list){
  34. System.out.println(u.getUserName());
  35. }
  36. sqlsession.close();
  37.  
  38. }
  39. }

Mybatis的

Mapper映射器接口规则,会自动生成接口实现类。

修饰public

a.根据sqlMapper定义的id属性当接口方法名

b 根据sqlMapper定义的parameterType类型定义参数类型

c 根据sqlMapper定义的resultType的类型 定义方法的返回类型

(多行使用list<泛型(resultType的类型)>,单行使resultType的类型)

d 将sqlMapper的namespace属性指定成为 包名.接口名字,就是接口的位置,

如何取到接口实现类呢

从sqlsession中获取

sqlsession.getMapper(接口的class对象);

mybatis替我生成实现类,在实现类中把sqlsession.select*的各种操作封装起来

首先实现 d

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.mxp.mybatis.dao.UserDao">
  4.  
  5. <sql id="userColumns">
  6. a.id AS "id",
  7. a.user_name AS "userName"
  8. </sql>
  9.  
  10. <select id="findAll" resultType="com.mxp.mybatis.entity.User" >
  11. SELECT <include refid="userColumns"/>
  12. FROM test_user a
  13. </select>
  14.  
  15. <select id="findLikeName" parameterType="string" resultType="com.mxp.mybatis.entity.User" >
  16. SELECT <include refid="userColumns"/>
  17. FROM test_user a
  18. <where>
  19. a.user_name like #{name}
  20. </where>
  21.  
  22. </select>
  23.  
  24. </mapper>

 a b c

  1. package com.mxp.mybatis.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import com.mxp.mybatis.entity.User;
  6.  
  7. public interface UserDao {
  8. public List<User> findAll();
  9. public List<User> findLikeName(String name);
  10. }

测试生成的映射器接口实现类

  1. @org.junit.Test
  2. public void testMapper(){
  3. SqlSession sqlsession = MybatisUtil.getInsertance();
  4. UserDao dao = sqlsession.getMapper(UserDao.class);
  5. List<com.mxp.mybatis.entity.User> os = dao.findAll();
  6. for(com.mxp.mybatis.entity.User u:os){
  7. System.out.println(u.getUserName());
  8. }
  9. sqlsession.close();
  10.  
  11. }

谈jdbcTemplate与mybatis的更多相关文章

  1. 【Spring】事务(transactional) - REQUIRES_NEW在JdbcTemplate、Mybatis中的不同表现

    环境 数据库: oracle 11g JAR: org.springframework:spring-jdbc:4.3.8.RELEASE org.mybatis:mybatis:3.4.2 概念 R ...

  2. JdbcTemplate 、Mybatis、ORM 、Druid 、HikariCP 、Hibernate是什么?它们有什么关系?

    JdbcTemplate .Mybatis.ORM .Druid .HikariCP .Hibernate是什么?它们有什么关系? 学完Spring和SpringMVC之后,就急于求成的开始学习起Sp ...

  3. JDBC、JDBCTemplate、MyBatis、Hiberante 比较与分析

    JDBC (Java Data Base Connection,java数据库连接) JDBC(Java Data Base Connection,java数据库连接)是一种用于执行SQL语句的Jav ...

  4. 08.@Scheduled定时任务、整合jdbcTemplate、mybatis区分多数据源

    @Scheduled注解执行定时任务 import org.springframework.scheduling.annotation.Scheduled; import org.springfram ...

  5. SpringBoot初学(4)– JdbcTemplate和Mybatis

    前言 github: https://github.com/vergilyn/SpringBootDemo 代码位置: 一.Spring Boot集成JdbcTemplate或NamedParamet ...

  6. [原创]Spring Boot + Mybatis 简易使用指南(一)基础环境搭建

    前言 作者: Ant QQ:517377100 相对于使用JdbcTemplate,Mybatis可自动建立pojo类型与数据库列的映射关系,数据库访问层的开发简单了许多 所有数据库访问操作,均封装在 ...

  7. Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源

    多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...

  8. Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源

    关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...

  9. Spring Boot入门系列(十四)使用JdbcTemplate操作数据库,配置多数据源!

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查.如何实现事物控制.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/c ...

随机推荐

  1. Cesium Workshop

    参考资料: https://cesiumjs.org/tutorials/Cesium-Workshop/ https://github.com/geoadmin/workshop-cesium3d ...

  2. 加了https,为什么网站的有些网页是安全的,有些网页不完全安全

    加了https,为什么网站的有些网页是安全的,有些网页不完全安全 一.总结 一句话总结: 这里原因:这里出现的问题是 网站上的图片删了没找到 原因:用了http地址(自己的或者别人的)的资源 避免这类 ...

  3. Python 死循环

    while True: try: x=int(input("Please enter a number:")) break except ValueError: print(&qu ...

  4. 微信小程序里自定义组件,canvas组件没有效果

    methods: { /** * el:画圆的元素 * r:圆的半径 * w:圆的宽度 * 功能:画背景 */ drawCircleBg: function (el, r, w) { const ct ...

  5. scope.row中属性值展示

    <el-table-column align="> <template slot-scope="scope"> {{ scope.$index } ...

  6. SQL注入自学[第一学:一个简单的注入环境的编写]

    /* 转载请注明出处 ID:珍惜少年时 */ CODE区域: /*注:现在mysql_connect的这种连接方式已经被放弃了,也就是说不用了,老夫也是新手上路故,下载了一个wampserver2.2 ...

  7. 自定义控件之Region区域

    构造Region 直接构造 public Region(Region region) //复制一个同样的Region变量 public Region(Rect r) public Region(int ...

  8. 【leetcode_easy_$】577. Employee Bonus

    problem 577. Employee Bonus 参考 1. Leetcode_easy_$_577. Employee Bonus; 2. https://www.cnblogs.com/li ...

  9. Docker从入门到动手实践

    一些理论知识,我这里就不累赘了 docker 入门资料,参考:https://yeasy.gitbooks.io/docker_practice/content/ Dockerfile常用命令,图片来 ...

  10. Docker Swarm 集群(十七)

    目录 一.Docker Swarm 概念 1.集群 2.Docker Swarm 3.重要概念 swarm node service 二.创建 Swarm 集群 1.环境准备 2.创建 swarm 3 ...