Spring之ORM[通俗易懂]

Spring之ORM[通俗易懂]Spring之ORM

大家好,又见面了,我是你们的朋友全栈君。

ORM: 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持久化呢?一种简单的方案是采用硬编码方式,为每一种可能的数据库访问操作提供单独的方法。

  • 这种方案存在以下不足:
    1.持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
    2.持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,毒药修改持久化曾的相关程序代码,增加了软件的维护难度。

ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。Java典型的ORM中间件有:Hibernate,ibatis,speedframework。

  • ORM的方法论基于三个核心原则:
      · 简单:以最基本的形式建模数据。
      · 传达性:数据库结构被任何人都能理解的语言文档化。
      · 精确性:基于数据模型创建正确标准化了的结构。
    代码展示:
    目录结构:
    在这里插入图片描述pom.xml
<?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>groupId</groupId>
    <artifactId>Demo01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

    </dependencies>

</project>

User.java

package com.xbj.po;

public class User { 
   
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    //get set toString
    }

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--导入配置文件-->
    <context:property-placeholder location="classpath:db.properties" />

    <!--1.数据源-->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
     </bean>
    <context:component-scan base-package="com.xbj.dao.impl" />
    <!--1. 配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 通知 映射到上面的事务管理器-->
    <tx:advice transaction-manager="transactionManager" id="transactionInterceptor">
        <tx:attributes>
            <tx:method name="add*" />
            <tx:method name="insert*"/>
            <tx:method name="save*"/>
            <tx:method name="update*"/>
            <tx:method name="change*" />
            <tx:method name="del*"/>
            <tx:method name="remove*"/>
            <tx:method name="drop*"/>
        </tx:attributes>
    </tx:advice>
    <!-- aop切面并配置切入点入进行事物管理 指向上面的映射 -->
    <aop:config>
        <aop:advisor advice-ref="transactionInterceptor" pointcut="execution(* com.xbj.service.impl.*.*(..))" />
    </aop:config>
</beans>

db.properties

jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root

UserDAO.java

package com.xbj.dao;
import com.xbj.po.User;
import java.util.List;

public interface UserDAO { 
   
    void addUser(User user);
    void delUser(Integer id);
    void updateUser(User user);
    User findUserById(Integer id);
    List<User> findAll();

    User findUserById2(Integer id);
}

UserDAOImpl.java

package com.xbj.dao.impl;


import com.xbj.dao.UserDAO;
import com.xbj.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@Repository
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO { 
   

    @Resource
   public void init(DataSource dataSource){ 
   
       super.setDataSource(dataSource);
   }

    public void addUser(User user) { 
   
        //String sql, @Nullable Object... args
        String sql = "INSERT INTO t_user VALUES (NULL,?,?,?)";
        this.getJdbcTemplate().update(sql, user.getUsername(), user.getPassword(), user.getAge());
    }

    public void delUser(Integer id) { 
   
        String sql = "DELETE FROM t_user WHERE id=?";
        this.getJdbcTemplate().update(sql, id);
    }

    public void updateUser(User user) { 
   
        String sql = "UPDATE t_user SET username=? ,password=?,age=? WHERE id=?";
        this.getJdbcTemplate().update(sql, user.getUsername(), user.getPassword(), user.getAge(), user.getId());
    }
    //自动映射,但要保证User类中的字段名与数据库的要一致
    public User findUserById(Integer id) { 
   
        String sql = "SELECT * FROM t_user WHERE id=?";
        List<User> list = this.getJdbcTemplate().query(sql, new BeanPropertyRowMapper<User>(User.class), id);
        return list.size() > 0 ? list.get(0) : null;
    }

    public List<User> findAll() { 
   
        String sql = "SELECT * FROM t_user";
        return this.getJdbcTemplate().query(sql, new BeanPropertyRowMapper<User>(User.class));
    }
    //手动映射
    public User findUserById2(Integer id) { 
   
        String sql = "SELECT * FROM t_user WHERE id=?";
        return  this.getJdbcTemplate().query(sql, new ResultSetExtractor<User>() { 
   
            public User extractData(ResultSet rs) throws SQLException, DataAccessException { 
   
                User user=new User();
                if(rs.next()){ 
   
                    user.setId(rs.getInt("id"));
                    user.setUsername(rs.getString("username"));
                    user.setPassword(rs.getString("pwd"));
                    user.setAge(rs.getInt("age"));
                }
                return user;
            }
        }, id);
    }
}

原生测试方法:

package com.xbj;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test01 { 
   

    @Test
    public void t1() throws Exception { 
   
        Class.forName("com.mysql.jdbc.Driver");
        //DriverManager JDBC大管家
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
        PreparedStatement psmt=connection.prepareStatement("SELECT * from t_user WHERE age > ?");
        psmt.setInt(1,33);
        ResultSet rs=psmt.executeQuery();
        while (rs.next()){ 
   
          Integer id=  rs.getInt("id");
          String username=rs.getString("username");
          System.out.println(id+"--"+username);
        }
    }
}

Spring测试方法;

package com.xbj;


import com.xbj.dao.UserDAO;
import com.xbj.po.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 
   "classpath:applicationContext.xml"})
public class Test02 { 
   
    @Autowired
    private UserDAO userDAO;
    @Test
    public void t1(){ 
   
        List<User> users=userDAO.findAll();
        for (User user:users){ 
   
            System.out.println(user);
        }
    }
    @Test
    public void t2(){ 
   
        User user=userDAO.findUserById(8);
        System.out.println(user);
    }
    @Test
    public void t3(){ 
   
        User user=new User();
        user.setUsername("hanmeimei");
        user.setPassword("ok");
        user.setAge(16);
        userDAO.addUser(user);
    }
    @Test
    public void t4(){ 
   
        User user=userDAO.findUserById(5);
        user.setUsername("HMM");
        userDAO.updateUser(user);
    }
    @Test
    public void t5(){ 
   
        userDAO.delUser(5);
    }

    @Test
    public void t6(){ 
   
       User user= userDAO.findUserById2(2);
       System.out.println(user);
    }


}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106632.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • TinyXml高速入门(一)

    TinyXml高速入门(一)

    2021年12月9日
    64
  • C++有序双向链表

    C++有序双向链表

    2021年8月20日
    60
  • intlij 激活插件破解方法

    intlij 激活插件破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    48
  • Python表白代码:太秀了,用过的人都找到了对象…【满屏玫瑰盛开】

    Python表白代码:太秀了,用过的人都找到了对象…【满屏玫瑰盛开】导语暗恋让人受尽委屈!一开始,你是我的秘密,我怕你知道,又怕你不知道,又怕你知道装作不知道!这大概就是暗恋的感受吧,可若是双向奔赴,那简更是甜蜜度爆表,快同小编吃下这波狗粮!跟着上一期的玫瑰花花样表白之后,小编新出了2款新型升级之后的表白代码!花样表白总有一款是你喜欢的!效果满分~正文还是熟悉的配方!熟悉的味道!盛开的蓝玫瑰效果如下:附源码:t.setup(800,800)t.hideturtle()t.speed(11)t.penup().

    2022年5月5日
    98
  • Ajaxpro组件

    Ajaxpro组件这一篇我们来看一个开源的组件:ajaxpro。虽然这是一个比较老的组件,不过实现思想和源码还是值得我们学习的。通过上一篇的介绍,我们知道要调用页面对象的方法,就是靠反射来实现的,关键是整个处理过程,包括反射调用方法、参数映射等。ajaxpro不仅在后台帮我们实现了这个过程,在前台也封装了请求调用的方法,例如ajax的相关方法,用ajaxpro的方法就可以发送异步请求了,不需要自己封装js或者使用j…

    2022年7月12日
    15
  • 内存映射文件「建议收藏」

    内存映射文件「建议收藏」在做科研,实现一些大数据的算法的时候,经常要调用一些文件的I/O函数,在数据量很大的时候,除了设计的算法和数据结构的耗时以外,其实主要的耗时还是文件的I/O。因为一般常规的方法就是先读出磁盘文件的内容到内存中,然后修改,最后写回到磁盘上。读磁盘文件是要经过一次系统调用,先将文件的内容从磁盘拷贝到内核空间的一个缓冲区,然后再将这些数据拷贝到用户空间,实际上是两次数据拷贝。写回同样也需要经过两次数据拷

    2022年6月17日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号