资讯专栏INFORMATION COLUMN

谈谈Spring-Data的那些事儿

chinafgj / 1130人阅读

摘要:什么是呢全称,是提出的一个对象持久化规范,各应用服务器自主选择具体实现。仅仅只是一个规范,而不是产品使用本身是不能做到持久化的。只要提供了持久化类与表的映射关系,框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。

我们在进行事务处理往往需要和数据库进行交互,这其中有关系型数据库(MySql,Sql Server,Oracle)或者是非关系型数据库(Redis,Hadhoop),常见的操纵数据库的方式就有JDBC和Spring JdbcTemplate,而这两种处理方式其实很繁琐而且代码复用率也比较低。另外使用这这种方式进行实际开发时效率也比较低,今天我们使用Spring Data进行开发。在进行开发之前我们首先介绍一下什么是Spring-Data,以及如何使用JDBC和Spring JDBCTemplate方式进行常用的CRUD功能的开发。

SpringData相关概念:
SpringData是Spring基于ORM框架、JPA规范封装的一套JPA应用框架,它提供了包括增删改查在内的常用功能,且易于扩展,可使开发者用极简的代码实现对数据库的访问和操作。
什么是JPA呢?
JPA全称Java Persistence API,是sun提出的一个对象持久化规范,各JavaEE应用服务器自主选择具体实现。JPA仅仅只是一个规范,而不是产品;使用JPA本身是不能做到持久化的。所以,JPA只是一系列定义好的持久化操作的接口,在系统中使用时,需要真正的实现者。

JPA的设计者是Hibernate框架的作者,因此Hibernate EntityManager作为Jboss服务器中JPA的默认实现;Oracle的Weblogic使用EclipseLink(以前叫TopLink)作为默认的JPA实现;IBM的Websphere和Sun的Glassfish默认使用OpenJPA(Apache的一个开源项目)作为其默认的JPA实现。
JPA的底层实现是一些流行的开源ORM(对象关系映射)框架,因此JPA其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范。

什么是ORM呢?
ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有三种:Hibernate,iBATIS,EclipseLink。

SpringData提供的编程接口:

【1】Repository:最顶层接口,是一个空接口,目的是为了统一所有的Repository的类型,且能让组件扫描的时候自动识别;
【2】CrudRepository:提供基础的增删改查操作;
【3】PagingAndSortingRepository:提供分页和排序的操作;
【4】JpaRepository:增加了批量操作的功能;
【5】JpaSpecificationExecutor :组合查询条件,提供原生SQL查询。

使用JDBC进行开发:
首先说明例子所设计的数据库,如下图:
![图片描述][1]   
1.JDBC工具类
public class JDBCUtil {    
    /*
     * 获取connection
     * @return 所获得的JDBC的Connection
     */
    public static Connection getConnection() throws ClassNotFoundException, SQLException, IOException
    {
        /*String url = "jdbc:mysql://localhost:3306/spring_data";
        String user = "root";
        String password = "123456";
        String driverClass = "com.mysql.jdbc.Driver";*/
        
        /*
         * 通过读取配置文件获取数据库连接所需参数
         */
        InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream("database.properties");
        Properties properties = new Properties();
        properties.load(inputStream);
        
        String url = properties.getProperty("jdbc.url");
        String user = properties.getProperty("jdbc.user");
        String password = properties.getProperty("jdbc.password");
        String driverClass = properties.getProperty("jdbc.driverClass");
        Class.forName(driverClass);
        Connection connection =  DriverManager.getConnection(url, user, password);    
        return connection;    
    }    
    /*
     * 释放资源
     */
    public static void release(ResultSet resultSet,Statement statement,Connection connection)
    {
        /*
         * 释放resultset
         */
        if(resultSet!=null)
        {
            try {
                resultSet.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(resultSet!=null)
        {
            try {
                resultSet.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /*
         * 释放statement
         */
        if(statement!=null)
        {
            try {
                statement.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /*
         * 释放connection
         */
        if(connection!=null)
        {
            try {
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

附: JDBC数据源配置文件:

jdbc.url = jdbc:mysql://localhost:3306/spring_data
jdbc.user = root
jdbc.password = 123456
jdbc.driverClass =com.mysql.jdbc.Driver
2.定义项目中设计的实体类
   /**
 * @author 熊涛
 *Student Entity Class
 */
public class Student {

    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
3.Dao层接口的实现
public interface StudentDAO {
    /*
     * 查询所有学生
     * @return所有学生
     */
    public List query();
    
    /*
     * 添加学生接口
     */
    public void save(Student student);
}
4.Dao层接口的实现类
  /**
 * @author 熊涛
 *StudentDAO接口的实现类,通过最原始的JDBC的方式操作
 */
public class StudetnDAOImpl implements StudentDAO {    
    public List query() {
        
        List students = new ArrayList();
        
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        String sql = "select id,name,age from student";
        try {
            connection = JDBCUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            
            Student student = null;
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                
                student = new Student();
                student.setId(id);
                student.setName(name);
                student.setAge(age);
                
                students.add(student);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JDBCUtil.release(resultSet, preparedStatement, connection);
        }
        
        return students;
    }

    public void save(Student student) {
        
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        String sql = "insert into student(name,age) values(?,?)";
        try {
            connection = JDBCUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1, student.getName());
            preparedStatement.setInt(2, student.getAge());
            preparedStatement.executeUpdate();
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        JDBCUtil.release(resultSet, preparedStatement, connection);
    }
    }
}


2.使用Spring JDBCTemplate进行开发

1.创建使用Spring-JDBCTemplate所需的配置文件beans.xml目的是将datasource和JDBCTemplate注入进来




    
        
        
        
        
    

    
        
    
    
    
            
    

2.在Dao层实现类中实现JDBCTemplate

/**
 * @author 熊涛
 *StudentDAo接口的实现类,通过Spring-JDBC的方式操作
 */
public class StudentDAOSpringJdbcImpl implements StudentDAO {

    //通过set方法注入JdbcTemplate
    private JdbcTemplate jdbcTemplate;
    
    public List query() {
        
        final List students = new ArrayList();
        String sql = "select id,name,age from student";
        jdbcTemplate.query(sql,new RowCallbackHandler(){

            public void processRow(ResultSet rs) throws SQLException {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                
                Student student = new Student();
                student.setId(id);
                student.setName(name);
                student.setAge(age);                    
                students.add(student);                    
            }               
        });
        return students;
    }

    public void save(Student student) {
        String sql = "insert into student(name,age) values(?,?)";
        jdbcTemplate.update(sql,new Object[]{student.getName(),student.getAge()});
    }
    
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

}  

3.使用Spring-Data方式进行开发

【1】创建使用Spring-Data所需的Spring配置文件      
         


    
    
        
        
        
        
    

    
    
        
        
            
        
        

        
            
                org.hibernate.cfg.ImprovedNamingStrategy
                org.hibernate.dialect.MySQL5InnoDBDialect
                true
                true
                update
            
        
            
    
    
        
    
    
    
    
            
           

      

【2】创建项目中所涉及到的实体类

    /**
 * @author 熊涛
 *雇员实体类
 *先开发实体类,然后生成对应的数据表
 */
@Entity
@Table(name="test_employee")
public class Employee {

    private Integer id;
    private String name;
    private Integer age;
    
    @GeneratedValue
    @Id
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    @Column(length=20)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
    }    
}

【3】创建项目中设计的接口类


 public interface EmployeeRepository extends Repository{

    public Employee findByName(String name);
    public List findByNameStartingWithAndAgeLessThan(String name,Integer age);
    public List findByNameEndingWithAndAgeLessThan(String name,Integer age);
    public List findByNameInOrAgeLessThan(List names,Integer age);
    public List findByNameInAndAgeLessThan(List names,Integer age);
        
    @Query("select o from Employee o where id=(select max(id) from Employee t1)")
    public Employee getEmployeeByMaxId();    
    @Query("select o from Employee o where o.name=?1 and o.age=?2")
    public List queryParams1(String name,Integer age);
    @Query("select o from Employee o where o.name=:name and o.age=:age")
    public List queryParams2(@Param("name")String name,@Param("age")Integer age);
    @Query("select o from Employee o where o.name like %?1%")
    public List queryLike1(String name);
    @Query("select o from Employee o where o.name like %:name%")
    public List queryLike2(@Param("name")String name);    
    @Query(nativeQuery = true,value = "select count(1) from employee")
    public long getCount();
    
    @Modifying
    @Query("update Employee o set o.age = :age where o.id = :id")
    public void update(@Param("id")Integer id,@Param("age")Integer age);
}

最后附上例子源码,源码中还有对于以上代码功能的测试,测试代码均位于test包下。
项目源码:
链接:https://pan.baidu.com/s/1pLcGCUR 密码:welh

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70842.html

相关文章

  • 谈谈Spring-Data那些事儿

    摘要:什么是呢全称,是提出的一个对象持久化规范,各应用服务器自主选择具体实现。仅仅只是一个规范,而不是产品使用本身是不能做到持久化的。只要提供了持久化类与表的映射关系,框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。 我们在进行事务处理往往需要和数据库进行交互,这其中有关系型数据库(MySql,Sql Server,Oracle)或者是非关系型数据库(Redis,Hadhoop)...

    charles_paul 评论0 收藏0
  • 你该知道ES6那些事儿

    摘要:最近重构了一个项目,引入了部分用法,最大的感受是让这门语言变得更加严谨,更加方便。通过该方法获得位置后还得比较一次才能判断是否存在。再来看看的写法使用数组来初始化一个,构造器能确保不重复地使用这些值。下面提供链接,供有兴趣的朋友参考。 最近重构了一个SPA项目,引入了部分ES6用法,最大的感受是ES6让javascript这门语言变得更加严谨,更加方便。本篇将结合实战经验,对最常用的部...

    CoffeX 评论0 收藏0
  • 跨域那些事儿

    摘要:什么是跨域我们先看下以下场景开启两个本地服务器,页面为,其中嵌套了,页面想使用页面的数据,例如调用它的方法,会报以下错误如图所示,,,译为协议主机和端口号必须符合,否则,就是跨域。跨域的几种常见方案同源策略的限制范围有以下几种和无法读取。 什么是跨域 我们先看下以下场景:开启两个本地服务器,页面A为localhost:9800,其中嵌套了iframeB localhost:9000,页...

    nevermind 评论0 收藏0
  • spring-data jpa 查询部分属性

    摘要:一准备有表结构如何生成相应的对象为省略二问题现在有一查询对象原先我是先查询出所有的对象,然后再循环赋值。经过一番尝试由于对象我不想改变,只能先差对象再循环赋值了。 一 准备 1.有表结构如何 CREATE TABLE `bbs_topic` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL DE...

    whataa 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<