1. 配置数据库连接池
1.1 配置Spring的内置的连接池
<!-- 配置Spring的内置的连接池 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test04"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
1.2 配置DBCP连接池
- 导入DBCP的jar包
<!-- 配置DBCP连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test04"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
1.3 配置C3P0连接池
- 导入C3P0的jar包
<!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test04"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
1.4 使用属性文件存储数据库信息
- 在属性文件jdbc.properties中配置数据库信息
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test04
jdbc.username=root
jdbc.password=root
- 引入属性文件并配置连接池
<!-- 通过context标签引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
2. JdbcTemplate
2.1 配置Spring的JDBC模版实例
<!-- 此处省略连接池配置,具体参考上面代码 -->
<!-- 配置Spring的JDBC的模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
2.2 使用的JdbcTemplate的增删改操作
//读取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据bean标签的id属性值查找实例
JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);
//update方法执行的是增删改方法
jdbcTemplate.update("insert into Account values (null,?,?)","田七",1000);
jdbcTemplate.update("update Account set money=? where id=?",800,1);
jdbcTemplate.update("delete from Account where id=?",11);
2.3 查询返回单个值
//读取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据bean标签的id属性值查找实例
JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);
String name=jdbcTemplate.queryForObject("select name from Account where id=?", String.class,1);
System.out.println(name);
Long count=jdbcTemplate.queryForObject("select count(*) from Account ", Long.class);
System.out.println(count);
2.4 查询返回封装成对象的数据
- 下面代码不用自己手动把结果集封装进对象,直接用
new BeanPropertyRowMapper<T>(T.class)
即可
@Test
public void test3(){
//读取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据bean标签的id属性值查找实例
JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);
//查询返回单行数据并封装成对象
Account account=jdbcTemplate.queryForObject("select * from Account where id=?", new AccountRowMapper(),1);
System.out.println(account);
//查询多行数据并封装成对象集合
List<Account> list=jdbcTemplate.query("select * from Account", new AccountRowMapper());
for (Account a : list) {
System.out.println(a);
}
}
//对返回结果封装成对象
class AccountRowMapper implements RowMapper<Account>{
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account=new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getDouble("money"));
return account;
}
}
3.Spring声明式事务(AOP)
3.1 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: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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Spring配置中使用事务beans标签需要引入
① xmlns:tx="http://www.springframework.org/schema/tx"
② xsi:schemaLocation中添加以下两个值
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
-->
<!-- 1.通过context标签引入数据库连接属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 2.配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 3.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 4.配置事务增强,并指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定义属性,声明事务规则 -->
<tx:attributes>
<!-- name表示添加事务的方法名,支持*模式匹配 -->
<!-- read-only设置为true表示事务只读,可以提高查询功能事务的处理性能,默认值为false -->
<!-- 事务传播机制propagation的默认值为REQUIRED,表示如果存在当前事务,则支持当前事务,
如果不存在当前事务,则开启一个新事务 -->
<tx:method name="find*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" "/>
<!-- 本次例子的方法名 -->
<tx:method name="transfer" />
</tx:attributes>
</tx:advice>
<!-- 5.定义切面 -->
<!-- 如果出现异常BeanNotOfRequiredTypeException需要把 proxy-target-class设置为true -->
<aop:config proxy-target-class="true">
<!-- 定义事务管理器的切入点,这里设置了业务包下的所有方法为切入点 -->
<aop:pointcut expression="execution(* com.service.impl.*.*(..))" id="servicePointcut"/>
<!-- 将事务增强与切入点组合 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
</aop:config>
<!-- 这里不用配置JdbcTemplate实例,JdbcDaoSupport类中会自动根据dataSource进行创建实例 -->
<!-- 这里注入的属性是dataSource,而不是jdbcTemplate,因为继承了JdbcDaoSupport类 -->
<bean id="accountDao" class="com.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="accountService" class="com.service.impl.AccountServiceImpl" >
<property name="accountDao" ref="accountDao"></property>
</bean>
</beans>
3.2 转账例子
- Dao类
package com.dao.impl;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.dao.AccountDao;
//只要在Spring文件中配置了dataSource实例,并且注入dataSource实例进AccountDaoImpl中,继承JdbcDaoSupport类后就可以直接使用JdbcTemplate
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
//父类JdbcDaoSupport有setDataSource(),所以要注入dataSource,而jdbcTemplate父类会自动创建,所以不用注入
//转入
@Override
public void in(String name,double money) {
String sql="update Account set money=money+? where name=?";
getJdbcTemplate().update(sql,money,name);
}
//转出
@Override
public void out(String name,double money) {
String sql="update Account set money=money-? where name=?";
getJdbcTemplate().update(sql,money,name);
}
}
- Service类
package com.service.impl;
import com.dao.AccountDao;
import com.service.AccountService;
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
//转账操作
@Override
public void transfer(String from, String to, double money) {
accountDao.out(from, money);
//模拟抛出异常
// int num=1/0;
accountDao.in(to, money);
}
}
- 测试类
package com.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.service.AccountService;
import com.service.impl.AccountServiceImpl;
public class TestAccount {
@Test
public void test(){
//读取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根据bean标签的id属性值查找实例
AccountService accountService= ac.getBean("accountService",AccountServiceImpl.class);
accountService.transfer("张三", "李四", 500);
}
}
3.3 注解事务
<!-- 1.通过context标签引入数据库连接属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 2.配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 3.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 4.开启注解事务(把原先的4和5替换了) -->
<!-- 如果出现异常BeanNotOfRequiredTypeException需要把 proxy-target-class设置为true -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
//在需要添加事务的类上添加注解@Transactional
@Transactional
public class AccountServiceImpl implements AccountService {}
4. HibernateTemplate
4.1 配置SSH环境
//继承HibernateDaoSupport类可以使用HibernateTemplate的方法
//需要注入sessionFactory属性
public class GradeDaoImpl extends HibernateDaoSupport implements GradeDao{
}
4.2 Hibernate方法
- 参考:https://blog.csdn.net/u013087359/article/details/105911975
- HibernateTemplate方法大部分跟Hibernate一样
4.2 HibernateTemplate特有方法
List<?> find(String hql, Object... values)
- values参数是可变参数(低版本spring该参数是一个数组),根据hql中的?占位符顺序和数量进行填写占位符的值
- find方法与?占位符配合使用
String hql="from Student where name like ? and sex=?";
List<Student> list=(List<Student>)getHibernateTemplate().find(hql, "张%",1);
List<?> findByValueBean(String hql, Object valueBean)
- valueBean是条件类实例,条件类的每个属性都会跟hql占位符名字逐一配对,同名则把属性值作为占位符的值
- findByValueBean方法跟变量占位符配合使用
String hql="from Student where name like :name and sex=:sex";
//创建条件类,条件类的每个属性都会跟hql占位符名字逐一配对,同名则把属性值作为占位符的值
Student student=new Student("张%",1);
List<Student> list=(List<Student>)getHibernateTemplate().findByValueBean(hql, student);
List<T> findByExample(Object exampleEntity)
- 根据对象的非空属性作为查询条件查询返回该实例集合
- null属性不会作为条件
- 主键不会作为条件
- 关联外键不会作为条件
- 基本类型的属性即使没有赋值也会以默认值作为条件(如int类型默认为0,double默认为0.0)
Student student=new Student();
student.setSex(1); //设置普通属性的值
student.setId(3); //设置主键值
student.setGrade(new Grade(1)); //设置外键值
//主键和外键不会作为条件
//等同于"from Student where sex=1"
List<Student> list=getHibernateTemplate().findByExample(student);
-
List<T> findByExample(Object exampleEntity,int firstResult,int maxResults)
- 根据对象的非空属性作为查询条件进行分页查询返回实例集合
- firstResult表示从第几条记录开始查询
- maxResults表示每页显示几条记录
- 其他特性跟findByExample()的特性一样
-
Object execute(HibernateCallback action)
- 实现HibernateCallback接口后就可以使用Hibernate Session自带的API
- 这个方法是通用的执行回调函数功能的方法,返回值是Object类型
-
public Object executeFind(HibernateCallback action)
- 实现HibernateCallback接口后就可以使用Hibernate Session自带的API
- 这个方法是返回List集合,适合于执行查询功能
public List<Book> findByPage(final int pageIndex,final int pageSize){
getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query=session.createQuery("from Student");
query.setFirstResult((pageIndex-1)*pageSize);
query.setMaxResults(pageSize);
List<Student> books=query.list();
return books;
}
});
}