咱们在进行事务处理每每须要和数据库进行交互,这其中有关系型数据库(MySql,Sql Server,Oracle)或者是非关系型数据库(Redis,Hadhoop),常见的操纵数据库的方式就有JDBC和Spring JdbcTemplate,而这两种处理方式其实很繁琐并且代码复用率也比较低。另外使用这这种方式进行实际开发时效率也比较低,今天咱们使用Spring Data进行开发。在进行开发以前咱们首先介绍一下什么是Spring-Data,以及如何使用JDBC和Spring JDBCTemplate方式进行经常使用的CRUD功能的开发。
SpringData是Spring基于ORM框架、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实体对象和关系型数据库创建起映射关系,经过面向对象编程的思想操做关系型数据库的规范。java
ORM,即Object-Relational Mapping(对象关系映射),它的做用是在关系型数据库和业务实体对象之间做一个映射,这样,咱们在具体的操做业务对象的时候,就不须要再去和复杂的SQL语句打交道,只需简单的操做对象的属性和方法。只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有三种:Hibernate,iBATIS,EclipseLink。
【1】Repository:最顶层接口,是一个空接口,目的是为了统一全部的Repository的类型,且能让组件扫描的时候自动识别;
【2】CrudRepository:提供基础的增删改查操做;
【3】PagingAndSortingRepository:提供分页和排序的操做;
【4】JpaRepository:增长了批量操做的功能;
【5】JpaSpecificationExecutor :组合查询条件,提供原生SQL查询。mysql
首先说明例子所设计的数据库,以下图: ![图片描述][1]
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数据源配置文件:spring
jdbc.url = jdbc:mysql://localhost:3306/spring_data jdbc.user = root jdbc.password = 123456 jdbc.driverClass =com.mysql.jdbc.Driver
/** * @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; } }
public interface StudentDAO { /* * 查询全部学生 * @return全部学生 */ public List<Student> query(); /* * 添加学生接口 */ public void save(Student student); }
/** * @author 熊涛 *StudentDAO接口的实现类,经过最原始的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); } } }
1.建立使用Spring-JDBCTemplate所需的配置文件beans.xml目的是将datasource和JDBCTemplate注入进来sql
<?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.在Dao层实现类中实现JDBCTemplate数据库
/** * @author 熊涛 *StudentDAo接口的实现类,经过Spring-JDBC的方式操做 */ public class StudentDAOSpringJdbcImpl implements StudentDAO { //经过set方法注入JdbcTemplate 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.使用Spring-Data方式进行开发编程
【1】建立使用Spring-Data所需的Spring配置文件 <?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 配置数据源--> <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 配置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 配置事务管理器--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!--4 配置支持注解的事务--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--5 配置spring data--> <jpa:repositories base-package="com.imooc" entity-manager-factory-ref="entityManagerFactory"/> <context:component-scan base-package="com.imooc"/> </beans>
【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<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); }
最后附上例子源码,源码中还有对于以上代码功能的测试,测试代码均位于test包下。
项目源码:
连接:https://pan.baidu.com/s/1pLcGCUR 密码:welhapp