使用的Spring是3.1版本,不是3.0版本。两者还是有区别的,其中一点就是:SimpleJdbcTemplate在3.1版本被标记为过时了,而SimpleJdbcTemplate的一些方法,被JdbcTemplate吸收了。所以,个人推荐使用3.1版本.
需要的JAR文件:
org.springframework.aop-3.1.0.RELEASE.jar
org.springframework.asm-3.1.0.RELEASE.jar
org.springframework.beans-3.1.0.RELEASE.jar
org.springframework.context-3.1.0.RELEASE.jar
org.springframework.core-3.1.0.RELEASE.jar
org.springframework.expression-3.1.0.RELEASE.jar
org.springframework.jdbc-3.1.0.RELEASE.jar
org.springframework.test-3.1.0.RELEASE.jar
org.springframework.transaction-3.1.0.RELEASE.jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
com.springsource.org.junit-4.7.0.jar
ojdbc14.jar
数据库脚本:
--创建商品表 create table product( id varchar2(255) primary key, name varchar2(255), author varchar2(255), price number(6,2), quantity number, description varchar2(255) );
实体类:
package org.monday.springjdbc.domain; public class Product /*implements Serializable*/{ //暂不序列化 private String id; private String name; private String author; private double price; private int quantity; private String description; public Product() { } // getter and setter @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", author=" + author + ", price=" + price + ", quantity=" + quantity + ", description=" + description + "]\n"; } }
正题:
BaseDao接口不提供了,附件中会有,直接给出BaseDaoImpl
package org.monday.springjdbc.dao.impl; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.sql.Types; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.monday.springjdbc.dao.BaseDao; import org.monday.springjdbc.util.QueryResult; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; /** * 使用场景 * * 数据库是Oracle * 主键列名为id * 主键由程序提供(这里用的是UUID) * 实体类名和数据库表名一致 比如:类名Product 表名product、PRODUCT、Produc 都可以 t_product 不可以 */ public class BaseDaoImpl<T> implements BaseDao<T> { /** 设置一些操作的常量 */ public static final String SQL_INSERT = "insert"; public static final String SQL_UPDATE = "update"; public static final String SQL_DELETE = "delete"; private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } private Class<T> entityClass; @SuppressWarnings("unchecked") public BaseDaoImpl() { ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass(); entityClass = (Class<T>) type.getActualTypeArguments()[0]; System.out.println("Dao实现类是:" + entityClass.getName()); } @Override public void save(T entity) { String sql = this.makeSql(SQL_INSERT); Object[] args = this.setArgs(entity, SQL_INSERT); int[] argTypes = this.setArgTypes(entity, SQL_INSERT); jdbcTemplate.update(sql.toString(), args, argTypes); } @Override public void update(T entity) { String sql = this.makeSql(SQL_UPDATE); Object[] args = this.setArgs(entity, SQL_UPDATE); int[] argTypes = this.setArgTypes(entity, SQL_UPDATE); jdbcTemplate.update(sql, args, argTypes); } @Override public void delete(T entity) { String sql = this.makeSql(SQL_DELETE); Object[] args = this.setArgs(entity, SQL_DELETE); int[] argTypes = this.setArgTypes(entity, SQL_DELETE); jdbcTemplate.update(sql, args, argTypes); } @Override public void delete(Serializable id) { String sql = " DELETE FROM " + entityClass.getSimpleName() + " WHERE id=?"; jdbcTemplate.update(sql, id); } @Override public void deleteAll() { String sql = " TRUNCATE TABLE " + entityClass.getSimpleName(); jdbcTemplate.execute(sql); } /** * 未完成 */ @Override public void batchSave(List<T> list) { } /** * 未完成 */ @Override public void batchUpdate(List<T> list) { } /** * 未完成 */ @Override public void batchDelete(List<T> list) { } @Override public T findById(Serializable id) { String sql = "SELECT * FROM " + entityClass.getSimpleName() + " WHERE id=?"; RowMapper<T> rowMapper = BeanPropertyRowMapper.newInstance(entityClass); return jdbcTemplate.query(sql, rowMapper, id).get(0); } @Override public List<T> findAll() { String sql = "SELECT * FROM " + entityClass.getSimpleName(); RowMapper<T> rowMapper = BeanPropertyRowMapper.newInstance(entityClass); return jdbcTemplate.query(sql, rowMapper); } @Override public QueryResult<T> findByPage(int pageNo, int pageSize) { List<T> list = this.find(pageNo, pageSize, null, null); int totalRow = this.count(null); return new QueryResult<T>(list, totalRow); } @Override public QueryResult<T> findByPage(int pageNo, int pageSize, Map<String, String> where) { List<T> list = this.find(pageNo, pageSize, where, null); int totalRow = this.count(where); return new QueryResult<T>(list, totalRow); } @Override public QueryResult<T> findByPage(int pageNo, int pageSize, LinkedHashMap<String, String> orderby) { List<T> list = this.find(pageNo, pageSize, null, orderby); int totalRow = this.count(null); return new QueryResult<T>(list, totalRow); } @Override public QueryResult<T> findByPage(int pageNo, int pageSize, Map<String, String> where, LinkedHashMap<String, String> orderby) { List<T> list = this.find(pageNo, pageSize, where, orderby); int totalRow = this.count(where); return new QueryResult<T>(list, totalRow); } // 组装SQL private String makeSql(String sqlFlag) { StringBuffer sql = new StringBuffer(); Field[] fields = entityClass.getDeclaredFields(); if (sqlFlag.equals(SQL_INSERT)) { sql.append(" INSERT INTO " + entityClass.getSimpleName()); sql.append("("); for (int i = 0; fields != null && i < fields.length; i++) { fields[i].setAccessible(true); // 暴力反射 String column = fields[i].getName(); sql.append(column).append(","); } sql = sql.deleteCharAt(sql.length() - 1); sql.append(") VALUES ("); for (int i = 0; fields != null && i < fields.length; i++) { sql.append("?,"); } sql = sql.deleteCharAt(sql.length() - 1); sql.append(")"); } else if (sqlFlag.equals(SQL_UPDATE)) { sql.append(" UPDATE " + entityClass.getSimpleName() + " SET "); for (int i = 0; fields != null && i < fields.length; i++) { fields[i].setAccessible(true); // 暴力反射 String column = fields[i].getName(); if (column.equals("id")) { // id 代表主键 continue; } sql.append(column).append("=").append("?,"); } sql = sql.deleteCharAt(sql.length() - 1); sql.append(" WHERE id=?"); } else if (sqlFlag.equals(SQL_DELETE)) { sql.append(" DELETE FROM " + entityClass.getSimpleName() + " WHERE id=?"); } System.out.println("SQL=" + sql); return sql.toString(); } // 设置参数 private Object[] setArgs(T entity, String sqlFlag) { Field[] fields = entityClass.getDeclaredFields(); if (sqlFlag.equals(SQL_INSERT)) { Object[] args = new Object[fields.length]; for (int i = 0; args != null && i < args.length; i++) { try { fields[i].setAccessible(true); // 暴力反射 args[i] = fields[i].get(entity); } catch (Exception e) { e.printStackTrace(); } } return args; } else if (sqlFlag.equals(SQL_UPDATE)) { Object[] tempArr = new Object[fields.length]; for (int i = 0; tempArr != null && i < tempArr.length; i++) { try { fields[i].setAccessible(true); // 暴力反射 tempArr[i] = fields[i].get(entity); } catch (Exception e) { e.printStackTrace(); } } Object[] args = new Object[fields.length]; System.arraycopy(tempArr, 1, args, 0, tempArr.length - 1); // 数组拷贝 args[args.length - 1] = tempArr[0]; return args; } else if (sqlFlag.equals(SQL_DELETE)) { Object[] args = new Object[1]; // 长度是1 fields[0].setAccessible(true); // 暴力反射 try { args[0] = fields[0].get(entity); } catch (Exception e) { e.printStackTrace(); } return args; } return null; } // 设置参数类型(写的不全,只是一些常用的) private int[] setArgTypes(T entity, String sqlFlag) { Field[] fields = entityClass.getDeclaredFields(); if (sqlFlag.equals(SQL_INSERT)) { int[] argTypes = new int[fields.length]; try { for (int i = 0; argTypes != null && i < argTypes.length; i++) { fields[i].setAccessible(true); // 暴力反射 if (fields[i].get(entity).getClass().getName().equals("java.lang.String")) { argTypes[i] = Types.VARCHAR; } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Double")) { argTypes[i] = Types.DECIMAL; } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Integer")) { argTypes[i] = Types.INTEGER; } else if (fields[i].get(entity).getClass().getName().equals("java.util.Date")) { argTypes[i] = Types.DATE; } } } catch (Exception e) { e.printStackTrace(); } return argTypes; } else if (sqlFlag.equals(SQL_UPDATE)) { int[] tempArgTypes = new int[fields.length]; int[] argTypes = new int[fields.length]; try { for (int i = 0; tempArgTypes != null && i < tempArgTypes.length; i++) { fields[i].setAccessible(true); // 暴力反射 if (fields[i].get(entity).getClass().getName().equals("java.lang.String")) { tempArgTypes[i] = Types.VARCHAR; } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Double")) { tempArgTypes[i] = Types.DECIMAL; } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Integer")) { tempArgTypes[i] = Types.INTEGER; } else if (fields[i].get(entity).getClass().getName().equals("java.util.Date")) { tempArgTypes[i] = Types.DATE; } } System.arraycopy(tempArgTypes, 1, argTypes, 0, tempArgTypes.length - 1); // 数组拷贝 argTypes[argTypes.length - 1] = tempArgTypes[0]; } catch (Exception e) { e.printStackTrace(); } return argTypes; } else if (sqlFlag.equals(SQL_DELETE)) { int[] argTypes = new int[1]; // 长度是1 try { fields[0].setAccessible(true); // 暴力反射 if (fields[0].get(entity).getClass().getName().equals("java.lang.String")) { argTypes[0] = Types.VARCHAR; } else if (fields[0].get(entity).getClass().getName().equals("java.lang.Integer")) { argTypes[0] = Types.INTEGER; } } catch (Exception e) { e.printStackTrace(); } return argTypes; } return null; } private List<T> find(int pageNo, int pageSize, Map<String, String> where, LinkedHashMap<String, String> orderby) { // where 与 order by 要写在select * from table 的后面,而不是where rownum<=? ) where rn>=?的后面 StringBuffer sql = new StringBuffer(" SELECT * FROM (SELECT t.*,ROWNUM rn FROM (SELECT * FROM " + entityClass.getSimpleName()); if (where != null && where.size() > 0) { sql.append(" WHERE "); // 注意不是where for (Map.Entry<String, String> me : where.entrySet()) { String columnName = me.getKey(); String columnValue = me.getValue(); sql.append(columnName).append(" ").append(columnValue).append(" AND "); // 没有考虑or的情况 } int endIndex = sql.lastIndexOf("AND"); if (endIndex > 0) { sql = new StringBuffer(sql.substring(0, endIndex)); } } if (orderby != null && orderby.size() > 0) { sql.append(" ORDER BY "); for (Map.Entry<String, String> me : orderby.entrySet()) { String columnName = me.getKey(); String columnValue = me.getValue(); sql.append(columnName).append(" ").append(columnValue).append(","); } sql = sql.deleteCharAt(sql.length() - 1); } sql.append(" ) t WHERE ROWNUM<=? ) WHERE rn>=? "); System.out.println("SQL=" + sql); Object[] args = { pageNo * pageSize, (pageNo - 1) * pageSize + 1 }; RowMapper<T> rowMapper = BeanPropertyRowMapper.newInstance(entityClass); return jdbcTemplate.query(sql.toString(), args, rowMapper); } private int count(Map<String, String> where) { StringBuffer sql = new StringBuffer(" SELECT COUNT(*) FROM " + entityClass.getSimpleName()); if (where != null && where.size() > 0) { sql.append(" WHERE "); for (Map.Entry<String, String> me : where.entrySet()) { String columnName = me.getKey(); String columnValue = me.getValue(); sql.append(columnName).append(" ").append(columnValue).append(" AND "); // 没有考虑or的情况 } int endIndex = sql.lastIndexOf("AND"); if (endIndex > 0) { sql = new StringBuffer(sql.substring(0, endIndex)); } } System.out.println("SQL=" + sql); return jdbcTemplate.queryForInt(sql.toString()); } }
其他具体的接口只要继承BaseDao就可以了
例如:
package org.chendl.springjdbc.dao; import org.chendl.springjdbc.domain.Product; public interface ProductDao extends BaseDao<Product> { }
而具体的实现类只要集成BaseDaoImpl,并实现自己的接口就可以了。
例如:
package org.monday.springjdbc.dao.impl; import org.monday.springjdbc.dao.ProductDao; import org.monday.springjdbc.domain.Product; public class ProductDaoImpl extends BaseDaoImpl<Product> implements ProductDao{ }
补上分页的工具类:
package org.monday.springjdbc.util; import java.util.List; public class QueryResult<T> { private List<T> list; // 结果集 private int totalRow; // 总记录数 public QueryResult() { } public QueryResult(List<T> list, int totalRow) { this.list = list; this.totalRow = totalRow; } //getter and setter }
补上生成主键的工具类:
package org.monday.springjdbc.util; import java.util.UUID; public final class ToolUtil { /** * 生成32位UUID 并去掉"-" */ public static String getUUID() { return UUID.randomUUID().toString().replaceAll("-", ""); } public static void main(String[] args) { System.out.println(ToolUtil.getUUID()); System.out.println(ToolUtil.getUUID().length());// 32 } }
Spring的配置文件Beans.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/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <!-- 加载属性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 配置jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置Dao --> <bean id="baseDao" class="org.monday.springjdbc.dao.impl.BaseDaoImpl" abstract="true"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <bean id="productDao" class="org.monday.springjdbc.dao.impl.ProductDaoImpl" parent="baseDao"/> <!-- 配置事务 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*"/> <tx:method name="find*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="daoMethod" expression="execution(* org.monday.springjdbc.dao.impl.*Impl*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethod"/> </aop:config> </beans>
测试:
1.测试Spring的数据源
package junit.test; import java.sql.SQLException; import javax.sql.DataSource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/beans.xml" }) public class SpringTest { // 测试是否取得数据库连接 @Test public void testDataSource() throws SQLException { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); DataSource dataSource = ctx.getBean(DataSource.class); System.out.println(dataSource.getConnection()); } }
2.测试Dao
package junit.test; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.monday.springjdbc.dao.ProductDao; import org.monday.springjdbc.domain.Product; import org.monday.springjdbc.util.QueryResult; import org.monday.springjdbc.util.ToolUtil; 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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/beans.xml" }) public class BaseDaoTest { @Autowired private ProductDao dao; @Test public void testSave() throws Exception { Product product = new Product(); product.setId(ToolUtil.getUUID()); product.setName("aaa"); product.setAuthor("bbb"); product.setPrice(111); product.setQuantity(9); product.setDescription("ccc"); dao.save(product); } @Test public void testUpdate() throws Exception { Product product = new Product(); product.setId("79934cfd71b84cc6819d3c06b2984f80"); product.setName("a"); product.setAuthor("b"); product.setPrice(444); product.setQuantity(44); product.setDescription("c"); dao.update(product); } @Test public void testDelete1() { Product product = new Product(); product.setId("79934cfd71b84cc6819d3c06b2984f80"); dao.delete(product); } @Test public void testDelete2() { dao.delete("7030aaf8a19d4d30b26e6e2588c43c30"); } @Test public void testDeleteAll() { dao.deleteAll(); } // 插入一些测试数据 @Test public void insertTestData() { for (int i = 1; i <= 100; i++) { Product product = new Product(); product.setId(ToolUtil.getUUID()); product.setName("springJdbc" + i); product.setAuthor("monday" + i); product.setPrice((double) Math.random() * 100); product.setQuantity((int) (Math.random() * 100)); product.setDescription("介绍SpringJdbc" + i); dao.save(product); } } // 未完成 @Test public void testBatchSave() { } // 未完成 @Test public void testBatchUpdate() { } // 未完成 @Test public void testBatchDelete() { } @Test public void testFindById() { System.out.println(dao.findById("07b5999dcb9346b3b353df18de345c31")); } @Test public void testFindAll() { System.out.println(dao.findAll()); } // 分页 @Test public void testFindByPage1() { int pageNo = 1; int pageSize = 10; QueryResult<Product> queryResult = dao.findByPage(pageNo, pageSize); for (Product p : queryResult.getList()) { System.out.println(p.getAuthor()); } } // 分页+条件 @Test public void testFindByPage2() { int pageNo = 1; int pageSize = 10; Map<String, String> where = new HashMap<String, String>(); where.put("author", "like '%monday1%'"); where.put("price", "<90"); QueryResult<Product> queryResult = dao.findByPage(pageNo, pageSize, where); for (Product p : queryResult.getList()) { System.out.println(p.getAuthor()); } } // 分页+排序 @Test public void testFindByPage3() { int pageNo = 1; int pageSize = 10; LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("price", "desc"); orderby.put("author", "asc"); QueryResult<Product> queryResult = dao.findByPage(pageNo, pageSize, orderby); for (Product p : queryResult.getList()) { System.out.println(p.getAuthor()); } } // 分页+条件+排序 @Test public void testFindByPage4() { int pageNo = 1; int pageSize = 10; Map<String, String> where = new HashMap<String, String>(); where.put("author", "like '%monday1%'"); where.put("price", "<90"); LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); orderby.put("price", "desc"); orderby.put("author", "asc"); QueryResult<Product> queryResult = dao.findByPage(pageNo, pageSize, where, orderby); for (Product p : queryResult.getList()) { System.out.println(p.getAuthor()); } } }
一些说明:
这些代码的应用有些局限性,没有使用Hibernate方便。 可能还有些Bug自己没有测试出来。这里只是提供一些思路或者只是为了学习而用。之所以有这么想法是觉得单纯的使用JDBC确实有点那个(你懂的...),而使HibernateTemplate可以实现类似的Dao,那用SpringJdbc能吗?自己就试了试。就个人觉得SpringJdbc 是十分好用的。有一次写批量的时候,SpringJdbc提供的batchUpdate()方法比Hibernate的快好多。所以,就自己看来,持久层可以Hibernate+SpringJdbc搭配使用,其中批量建议使用SpringJdbc处理。(可能自己还没想到Hiberante批量性能提高的方法)。而这里基于SpringJdbc的泛型的批量方法,还没想出来。基于HibernateTemplate的倒是可以,但是性能...
这里只是自己一点学习心得仅供参考。
相关推荐
spring-data-jdbc-repository, Spring Data JDBC泛型DAO实现 Spring Data JDBC泛型DAO实现查看正在积极开发和维护的 jirutka/spring-data-jdbc-repository fork 。 不再支持这里存储库。本项目的目的是为基于 ...
【描述】"基于hibernate5 泛型Dao实例,下载后改一下数据库配置直接可以用",意味着这个压缩包文件提供了一个已经实现好的Hibernate5版本的泛型Dao示例项目。用户只需要根据自己的数据库环境修改相应的配置信息,就...
本文将深入探讨`JdbcTemplate`通用泛型Dao实现的相关知识点,帮助开发者更好地理解和应用这一技术。 首先,让我们了解什么是`JdbcTemplate`。它是Spring框架的一部分,用于处理SQL操作。`JdbcTemplate`提供了一组...
本程序整合了struts-2.2.3.1+spring-framework-3.1.0+hibernate-distribution-3.6.8+JSON+MySQL+Annotation,并且对Dao和Service进行了封装,内含.jar包,并且解决了一对多双向关联的could not initialize proxy - ...
1. **泛型DAO**:通过泛型,可以创建通用的DAO接口和实现,减少代码的重复。例如,`IMessageDAO` 和 `IUserDAO` 接口定义了基本的CRUD操作,而`HibernateDAO`基础类提供了对这些操作的实现,子类可以进一步扩展以...
在实际应用中,这样的分页实现可以广泛用于Web应用程序,尤其是在基于Spring框架的项目中,可以方便地与DAO层和Service层集成,提供强大的数据检索和展示功能。 总的来说,"反射泛型完美版分页.rar"提供的解决方案...
然后,每个特定实体的DAO类可以继承这个基类,通过泛型指定对应的实体类型。 最后,通过Spring的`@Autowired`注解,我们将DAO注入到Service层。Service层负责业务逻辑,它调用DAO的方法来执行数据库操作。这样,...
本篇文章将介绍一个基于JDBC封装的`BaseDao`实例,该实例提供了一个通用的DAO(Data Access Object)模板,可以应用于多种实体类的操作。 首先,`BaseDao`泛型类被定义为`<T>`,表示它可以处理任何类型的对象。类中...
在Spring3和Hibernate4的整合中,泛型常用于创建泛型DAO,如`UserDao<User>`,这样在处理不同类型的实体时,可以重用相同的DAO基础代码,提高了代码的复用性和可维护性。 4. **注解的应用**:Spring3和Hibernate4都...
使用泛型确保DAO方法返回的结果类型与实体类匹配。同时,定义ResultMap来映射查询结果到实体类,可以处理复杂的数据类型和关联关系。 4. **Mapper代理**: Mybatis使用`SqlSession`和`MapperFactoryBean`来创建...
java-entitymanager-generic-dao 这是一个使用通用 daos 访问数据的小...技术栈本示例使用: Spring Boot Framework(实现 CommandLineRunner 的主类) Spring事务管理+Spring JDBC PostgreSQL 数据库 9.2 Apache Log4J
在这个接口中,`T`代表任何继承了特定基类或实现了特定接口的实体类,这得益于Java的泛型机制。`save`方法用于保存新实体到数据库,`update`用于更新已有实体,`deleteById`根据ID删除实体,`findById`通过ID查询...
4. **数据访问集成**:Spring 2.0加强了与各种数据存储的集成,包括JDBC、Hibernate、JPA等,提供了模板类和DAO支持,简化了数据访问层的开发。 5. **Web服务支持**:Spring 2.0引入了Spring-WS项目,提供了一种...
2. **Data Access/Integration** - 提供了数据访问/集成的功能,包括事务管理、ORM支持、JDBC抽象、DAO抽象等。 3. **Web** - 包含Web上下文模块,提供了一个适用于web应用的ApplicationContext实现,同时也包含了...
在SSH框架中,泛型可以被应用到DAO(Data Access Object)层,创建泛型DAO接口和实现,以减少代码重复,提高代码复用性和可维护性。例如,你可以创建一个泛型BaseDAO接口,如下所示: ```java public interface ...
Spring1.x对JDBC和ORM的支持相对较弱,而Spring2.x在这一领域有了显著增强,集成了更多ORM框架,如Hibernate、JPA等,提供了Template和DAO支持,简化了数据库操作。此外,还引入了Transaction API,使得事务管理...
- **DAO 支持:** Spring 提供了一套 DAO 支持,用于简化持久层的操作。 - **使用 JDBC 进行数据访问:** Spring 对 JDBC 进行了封装,简化了 JDBC 编程的复杂性。 - **ORM 数据访问:** Spring 支持多种 ORM 框架的...
Spring框架的主要组成部分包括Spring IoC容器、Spring AOP、Spring MVC、Spring ORM、Spring JDBC、Spring DAO、Spring Web模块、Spring Context和Spring Web MVC等。 Spring的核心特性之一是依赖注入(DI)和控制...
3. **Spring JDBC**:在Java世界中,Spring框架提供了JDBC模板(JdbcTemplate)和SQL映射工具(MyBatis)等,可以方便地构建DAO层。如果`GenericDaoImpl`是在Spring环境中,那么它可能使用了这些工具来简化数据库...