About spring data

Time:2019-11-12
In transaction processing, we often need to interact with databases, including relational databases (mysql, SQL server, Oracle) or non relational databases (redis, Hadoop). The common ways to manipulate databases are JDBC and spring jdbctemplate, which are actually cumbersome and low code reuse rate. In addition, the actual development efficiency using this method is also relatively low. Today we use spring data for development. Before development, we will first introduce what spring data is and how to use JDBC and spring JDBC template to develop common crud functions.

Related concepts of springdata:

Spring data is a set of JPA application framework based on ORM framework and JPA specification encapsulation of spring. It provides common functions including adding, deleting, modifying and querying, and is easy to expand. It enables developers to access and operate the database with simple code.

What is JPA?

The full name of JPA is java persistence API, which is an object persistence specification proposed by sun. Each Java EE application server chooses its own implementation. JPA is just a specification, not a product; using JPA itself is not persistent. Therefore, JPA is only a series of defined interfaces for persistent operations. When it is used in the system, a real implementer is required.

The designer of JPA is the author of Hibernate framework, so hibernate entitymanager is the default implementation of JPA in JBoss server; Oracle’s Weblogic uses eclipse link (formerly known as TopLink) as the default implementation of JPA; IBM’s WebSphere and sun’s GlassFish use openjpa (an open source project of APACHE) as the default implementation of JPA.
The underlying implementation of JPA is some popular open-source ORM (object relational mapping) framework, so JPA is actually the Java entity object and relational database to establish a mapping relationship, and operate the specification of relational database through the idea of object-oriented programming.

What is ORM?

ORM, or object relational mapping, is used to map between relational database and business entity objects. In this way, when we operate business objects, we don't need to deal with complex SQL statements, but simply operate the properties and methods of the objects. As long as the mapping relationship between persistent classes and tables is provided, the ORM framework can refer to the mapping file information and persist the objects into the database at runtime. Currently, there are three ORM frameworks: Hibernate, ibatis, and eclipse link.

Programming interface provided by springdata:

[1] Repository: the top-level interface is an empty interface, which aims to unify all repository types and enable automatic identification during component scanning;
[2] crudrepository: provides basic addition, deletion, modification and query operations;
[3] pagingandsortingrepository: provides paging and sorting operations;
[4] jparepository: added the function of batch operation;
[5] jpaspecification executor: combine query conditions to provide native SQL query.

Develop with JDBC:

First, the database designed by the example is illustrated as follows:
! [picture description] [1]

1. JDBC tool class

public class JDBCUtil {    
    /*
     *Get connection
     *@ return the JDBC connection obtained
     */
    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";*/
        
        /*
         *Obtain parameters required for database connection by reading configuration file
         */
        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;    
    }    
    /*
     *Release resources
     */
    public static void release(ResultSet resultSet,Statement statement,Connection connection)
    {
        /*
         *Release 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();
            }
        }
        /*
         *Release statement
         */
        if(statement!=null)
        {
            try {
                statement.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /*
         *Release connection
         */
        if(connection!=null)
        {
            try {
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Attachment: JDBC data source configuration file:

jdbc.url = jdbc:mysql://localhost:3306/spring_data
jdbc.user = root
jdbc.password = 123456
jdbc.driverClass =com.mysql.jdbc.Driver

2. Define entity classes designed in the project

/**
 *@ author Xiong Tao
 *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. Implementation of Dao interface

public interface StudentDAO {
    /*
     *Query all students
     *@ return all students
     */
    public List<Student> query();
    
    /*
     *Add student interface
     */
    public void save(Student student);
}

4. Implementation class of Dao layer interface

/**
 *@ author Xiong Tao
 *The implementation class of studentdao interface operates in the most primitive way of JDBC
 */
public class StudetnDAOImpl implements StudentDAO {    
    public List<Student> query() {
        
        List<Student> students = new ArrayList<Student>();
        
        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. Develop with spring JDBC template

1. Create the configuration file beans.xml required to use spring JDBC template to inject datasource and JDBC template

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

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_data"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="studentDAO" class="com.imooc.dao.StudentDAOSpringJdbcImpl">
            <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
</beans>

2. Implement JDBC template in Dao layer implementation class

/**
 *@ author Xiong Tao
 *Implementation class of studentdao interface, operated by spring JDBC
 */
public class StudentDAOSpringJdbcImpl implements StudentDAO {

    //Inject jdbctemplate through set method
    private JdbcTemplate jdbcTemplate;
    
    public List<Student> query() {
        
        final List<Student> students = new ArrayList<Student>();
        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. Develop in spring data mode

[1] create the spring configuration file required to use spring data      
      <?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:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <! -- 1 configure data source -- >
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_data"/>
    </bean>

    <! -- 2 configure entitymanagerfactory -- >
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="packagesToScan" value="com.imooc"/>

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>        
    <! -- 3 configure transaction manager -- >
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <! -- 4 configure transactions supporting annotation -- >
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <! -- 5 configure spring data -- >
    <jpa:repositories base-package="com.imooc" entity-manager-factory-ref="entityManagerFactory"/>        
    <context:component-scan base-package="com.imooc"/>       
</beans>

[2] create entity classes involved in the project

/**
 *@ author Xiong Tao
 *Employee entity class
 *Develop entity class first, and then generate corresponding data table
 */
@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] create interface classes designed in the project


 public interface EmployeeRepository extends Repository<Employee,Integer>{

    public Employee findByName(String name);
    public List<Employee> findByNameStartingWithAndAgeLessThan(String name,Integer age);
    public List<Employee> findByNameEndingWithAndAgeLessThan(String name,Integer age);
    public List<Employee> findByNameInOrAgeLessThan(List<String> names,Integer age);
    public List<Employee> findByNameInAndAgeLessThan(List<String> 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<Employee> queryParams1(String name,Integer age);
    @Query("select o from Employee o where o.name=:name and o.age=:age")
    public List<Employee> queryParams2(@Param("name")String name,@Param("age")Integer age);
    @Query("select o from Employee o where o.name like %?1%")
    public List<Employee> queryLike1(String name);
    @Query("select o from Employee o where o.name like %:name%")
    public List<Employee> 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);
}

Finally, the source code of the example is attached. In the source code, there are tests for the above code functions. The test codes are all under the test package.
Project source code:
Link: https://pan.baidu.com/s/1plcgcur password: welh