2019-8-5 [Java_Spring]3. Spring框架下 控制反转(IOC)/依赖注入(DI)实战: Spring+Dbutils实现CURD操作

20 篇文章 0 订阅

3.Spring框架 控制反转(IOC)/依赖注入(DI)实战

3.1 优化现有的CURD流程

需求说明 : 引入Spring优化现有开发流程,完成user_info表的CURD操作
完成数据库表的CURD操作,步骤无外乎就几步

  1. 创建实体类
  2. 编写数据库连接工具类
  3. DAO层完成数据库SQL语句的封装
  4. 业务层处理可以业务数据

所以我们就按照步骤实现即可

3.2 Spring+Dbutils实现CURD操作

数据库 : userdb

3.2.1 表 :

CREATE TABLE `user_info` (
  `u_id` int(8) NOT NULL auto_increment,
  `u_name` varchar(32) default NULL,
  `u_regdate` date default NULL,
  `u_money` double default NULL,
  PRIMARY KEY  (`u_id`)
)

在这里插入图片描述

3.2.2 创建项目,导入jar包

在这里插入图片描述

3.2.3 创建Spring的配置文件,applicationContext.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"
    xsi:schemaLocation="
    	http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">	
</beans>

创建各层的包,依次编写

3.2.4 实体类 :

package com.hnxy.entity;

import java.util.Date;
/**
 * 用户表的实体类
 * @author sysmaster
 *
 */
public class UserInfo {
	
	// 私有属性	
	private Integer uid;	// 主键ID
	private String uname;	// 客户姓名
	private Date regDate;	// 注册日期
	private Double money;	// 存款
		
	// 共有方法
	public Integer getUid() {
		return uid;
	}
	public void setUid(Integer uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	public Date getRegDate() {
		return regDate;
	}
	public void setRegDate(Date regDate) {
		this.regDate = regDate;
	}
	public Double getMoney() {
		return money;
	}
	public void setMoney(Double money) {
		this.money = money;
	}
	
	@Override
	public String toString() {
		return "UserInfo [uid=" + uid + ", uname=" + uname + ", regDate=" + regDate + ", money=" + money + "]";
	}
}

3.3.6 DAO层接口,固定六个方法

package com.hnxy.dao;

import java.util.List;
import com.hnxy.entity.UserInfo;

/**
 * DAO层的6个方法
 * @author sysmaster
 *
 */
public interface UserDAO {
	
	/**
	 * 添加
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int insertUser(UserInfo user)throws Exception;
	
	/**
	 * 更新
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int updateUser(UserInfo user)throws Exception;
	
	/**
	 * 删除
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int deleteUser(UserInfo user)throws Exception;
	
	/**
	 * 按ID查询
	 * @param uid
	 * @return
	 * @throws Exception
	 */
	public UserInfo findUserByID(Integer uid)throws Exception;
	
	/**
	 * 分页展示
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception
	 */
	public List<UserInfo> findUserListByPage(Integer start,Integer end)throws Exception;
	
	/**
	 * 获取数据总条数
	 * @return
	 * @throws Exception
	 */
	public int findUserListByPageCount()throws Exception;	
}

3.3.7 DAO层实现类优化方案 :

以前我们肯定是需要编写一个数据库连接驱动类来获取连接,现在有了spring就不用了,我们可以直接在spring配置文件applicationContext.xml里创建数据库连接

3.3.7.1 创建数据源 :
	<!-- 创建数据源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/userdb?characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>

这些属性都是我们根据之前在jdbcutil中的设置转化而来的,通过这些属性Spring就能帮助我们创建一个数据源了

3.3.7.2 创建SQL的执行对象

其实不光是数据源 我们的queryRunner对象也可以放在spring配置文件中创建

<!-- 创建SQL执行对象 -->
<bean id="qr" class="org.apache.commons.dbutils.QueryRunner"></bean>

此处我们除了创建QueryRunner对象之外还能够将他与数据源关联,因为根据源码可以知道qr在创建的时候可以关联数据源,关联数据源之后我们就不用在
调用qr的query或者update方法的时候设定conn了

3.3.7.3 源码

在这里插入图片描述
所以我们可以通过构造注入完成这个数据源对象的注入

<!-- 创建SQL执行对象 -->
<bean id="qr" class="org.apache.commons.dbutils.QueryRunner">
	<constructor-arg name="ds" ref="dataSource" />
</bean>

这样我们就有了一个QueryRunner对象

但是大家要注意一个问题就是QueryRunner是负责执行SQL语句的对象,Spring创建这个对象的时候会以单例模式创建这个对象,那么这时就有一个问题了

单例对象在多线程环境下只有一个实例对象,这时候大家(多个线程)都使用这一个QueryRunner执行SQL语句势必会造成线程阻塞问题,而且在执行一些包含有事务的操作

3.3.7.4 多线程问题

如果多个线程共享一个QueryRunner对象似乎也不太安全,所以这个时候我们就想能不能用多例创建这个对象呢?
当然可以,在bean标签中加入scope属性即可

<!-- 创建SQL的执行对象 -->
<bean id="qr" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
	<constructor-arg name="ds" ref="dataSource" />
</bean>

通过 scope=“prototype” 的设置,Spring在创建这个对象的时候就是多例创建了
默认情况下spring创建的对象都是单例的 所以通过bean的scope属性可以改变创建对象的策略

如果 scope=“singleton” 的时候(默认情况)spring就会以单例模式创建
如果scope=“prototype” 的时候 spring就会以多例创建这个对象

3.3.7.4.1 多例配置测试
public static void main(String[] args) {
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
     QueryRunner qr1 = context.getBean(QueryRunner.class);
     QueryRunner qr2 = context.getBean(QueryRunner.class);
     System.out.println(qr1);
     System.out.println(qr2);
 }

在这里插入图片描述

3.3.7.4.2 单例配置测试
	<!-- 创建SQL执行对象 -->
	<bean id="qr" class="org.apache.commons.dbutils.QueryRunner">
		<constructor-arg name="ds" ref="dataSource" />
	</bean>

在这里插入图片描述
那么这时候有的同学就会想,QueryRunner是多例的其他的对象要不要也多例呢?

这个问题就需要根据你们公司的具体业务来实现了,因为多例与单例模式创建对象各有优缺点,所以不能一概而论用哪个更好,
必须根据实际业务需要来就好比我们这个qr对象一样,我们是因为怕多线程阻塞 所以采用的多例

举个例子,
银行有一台ATM,每天来取钱的由5个人,这时候虽然可能5个人都来的时候会等一会但是时间不长,可以忍受,这时候一台ATM就可以 这就是单例

但是如果每天都有500个人来取钱,那么一台ATM肯定是不够的,所以就需要增加ATM的数量 这就是多例

所以 单例或者多例的设置必须根据业务逻辑来实现!

我们已经设置好了QueryRunner,那么大家想一想谁会用到这个对象呢?
是DAO的实现类!所以DAO实现类中如果想使用这个对象就可以这么写

public class UserDAOImpl implements UserDAO {
	
	// 创建数据库的执行对象
	private QueryRunner qr;
	
	// Spring值注入
	public void setQr(QueryRunner qr) {
		this.qr = qr;
	}
    .......其他代码省略
}

说完了对jdbcUtil的改造之后我们继续完成

3.3.8 DAO层接口实现

数据库对象都交给spring了所以此处我们只关心操作就可以了

package com.hnxy.dao.impl;

import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.hnxy.dao.UserDAO;
import com.hnxy.entity.UserInfo;

public class UserDAOImpl implements UserDAO {
	
	private QueryRunner qr;	
	public void setQr(QueryRunner qr) {
		this.qr = qr;
	}

	@Override
	public int insertUser(UserInfo user) throws Exception {
		// 创建方法的返回值
		int count = 0;
		// 编写SQL语句
		String sql = "insert into user_info values (null,?,?,?)";
		// 占位符赋值
		Object[] params = {user.getUname(),user.getRegDate(),user.getMoney()};
		// 执行
		count = qr.update(sql, params);
		// 返回
		return count;
	}

	@Override
	public int updateUser(UserInfo user) throws Exception {
		// 创建方法的返回值
		int count = 0;
		// 编写SQL语句
		String sql = "update user_info set `u_name`=?,`u_regdate`=?,`u_money`=? where `u_id`=?";
		// 占位符赋值
		Object[] params = {user.getUname(),user.getRegDate(),user.getMoney(),user.getUid()};
		// 执行
		count = qr.update(sql, params);
		// 返回
		return count;
	}

	@Override
	public int deleteUser(UserInfo user) throws Exception {
		// 创建方法的返回值
		int count = 0;
		// 编写SQL语句
		String sql = "delete from user_info where `u_id` = ?";
		// 占位符赋值
		Object[] params = {user.getUid()};
		// 执行
		count = qr.update(sql, params);
		// 返回
		return count;
	}

	@Override
	public UserInfo findUserByID(Integer uid) throws Exception {
		// 创建方法的返回值
		UserInfo user = null;
		// 编写SQL语句
		String sql = "select * from v1 where `uid` = ?";
		// 占位符赋值
		Object[] params = {uid};
		// 执行
		user = qr.query(sql, new BeanHandler<UserInfo>(UserInfo.class),params);
		// 返回
		return user;
	}

	@Override
	public List<UserInfo> findUserListByPage(Integer start, Integer end) throws Exception {
		// 创建方法的返回值
		List<UserInfo> list = null;
		// 创建SQL语句
		String sql = "select * from v1 limit ?,?";
		// 占位符赋值
		Object[] params = {start,end};
		// 执行
		list = qr.query(sql, new BeanListHandler<UserInfo>(UserInfo.class),params);
		// 返回
		return list;
	}

	@Override
	public int findUserListByPageCount() throws Exception {
		// 创建方法的返回值
		int totalCount = 0;
		// 编写SQL语句
		String sql = "select count(*) from v1";
		// 占位符赋值
		// 执行
		Number num = qr.query(sql, new ScalarHandler<Number>());
		// 设定返回值
		totalCount = num.intValue();
		// 返回
		return totalCount;
	}
}

3.3.9 在spring中配置UserDAOImpl的对象applicetionContext.xml

在spring中配置UserDAOImpl的对象applicetionContext.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"
    xsi:schemaLocation="
    	http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 1.创建数据源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/userdb?characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>
	<!-- 2.创建SQL执行对象 -->
	<bean id="qr" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
		<constructor-arg name="ds" ref="dataSource" />
	</bean>
	
	<!-- 3.创建DAO对象 -->
	<bean id="userDAO" class="com.hnxy.dao.impl.UserDAOImpl">
		<property name="qr" ref="qr" />
	</bean>
</beans>

在这里插入图片描述

3.3.10 测试类

package com.hnxy.test;

import java.util.Date;
import java.util.List;
import java.util.Random;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hnxy.dao.UserDAO;
import com.hnxy.entity.UserInfo;

public class Test1 {
	
	private ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	private UserDAO userDAO = context.getBean(UserDAO.class);
		
	public void addTest()throws Exception{
		// 添加测试
		UserInfo user = null;
		Random random = new Random();
		for (int i = 1; i <= 100; i++) {
			user = new UserInfo();
			user.setUname("用户"+i);
			user.setMoney(random.nextInt(50000)+0D);
			user.setRegDate(new Date(System.currentTimeMillis()+1000*60*60*24*random.nextInt(366)));
			int count = userDAO.insertUser(user);
			System.out.println(count);
		}
	}
		
	public void updateTest()throws Exception{
		// 测试更新
		UserInfo user = userDAO.findUserByID(64);
		if(null != user){
			// 开始更新
			user.setUname("赵文明");
			user.setMoney(88888D);
			user.setRegDate(new Date());
			int count = userDAO.updateUser(user);
			String msg = count>0?"更新成功":"更新失败";
			System.out.println(msg);
		}else{
			System.out.println("没有找到要更新的数据!");
		}
	}
	
	
	public void deleteTest()throws Exception{
		// 测试删除
		UserInfo user = userDAO.findUserByID(65);
		if(null != user){
			// 开始删除
			int count = userDAO.deleteUser(user);
			String msg = count>0?"删除成功":"删除失败";
			System.out.println(msg);
		}else{
			System.out.println("没有找到要删除的数据!");
		}
	}
	
	@Test
	public void queryTest()throws Exception{
		// 分页测试
		// 定义分页属性
		int totalCount = 0;
		int totalPage = 0;
		int pageIndex = 1;
		int pageSize = 10;
		// 获取总条数
		totalCount = userDAO.findUserListByPageCount();
		// 计算总页数
		totalPage = totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;
		// 输出
		System.out.println("共查询出" + totalCount + "条数据,每页展示" + pageSize + "条,一共展示" + totalPage + "页,当前为第" + pageIndex + "页");
		// 获取数据集合
		List<UserInfo> list = userDAO.findUserListByPage((pageIndex-1)*pageSize, pageSize);
		// 循环展示
		for (UserInfo userInfo : list) {
			System.out.println(userInfo);
		}
	}
}

DAO层完成,正常整理Service层即可

3.3.11 Service接口

package com.hnxy.service;

import java.util.List;
import com.hnxy.entity.UserInfo;

/**
 * 用户表的业务层接口
 * @author sysmaster
 *
 */
public interface UserService {
	/**
	 * 添加
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int insertUser(UserInfo user)throws Exception;
	
	/**
	 * 更新
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int updateUser(UserInfo user)throws Exception;
	
	/**
	 * 删除
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public int deleteUser(UserInfo user)throws Exception;
	
	/**
	 * 按ID查询
	 * @param uid
	 * @return
	 * @throws Exception
	 */
	public UserInfo findUserByID(Integer uid)throws Exception;
	
	/**
	 * 分页展示
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception
	 */
	public List<UserInfo> findUserListByPage(Integer start,Integer end)throws Exception;
	
	/**
	 * 获取数据总条数
	 * @return
	 * @throws Exception
	 */
	public int findUserListByPageCount()throws Exception;
}

3.3.12 Service实现类

package com.hnxy.service.impl;

import java.util.List;
import com.hnxy.dao.UserDAO;
import com.hnxy.entity.UserInfo;
import com.hnxy.service.UserService;

public class UserServiceImpl implements UserService {
	
	// 声明DAO层对象
	private UserDAO userDAO;
	
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	@Override
	public int insertUser(UserInfo user) throws Exception {
		return userDAO.insertUser(user);
	}

	@Override
	public int updateUser(UserInfo user) throws Exception {	
		return userDAO.updateUser(user);
	}

	@Override
	public int deleteUser(UserInfo user) throws Exception {
		return userDAO.deleteUser(user);
	}

	@Override
	public UserInfo findUserByID(Integer uid) throws Exception {
		return userDAO.findUserByID(uid);
	}

	@Override
	public List<UserInfo> findUserListByPage(Integer start, Integer end) throws Exception {
		return userDAO.findUserListByPage(start, end);
	}

	@Override
	public int findUserListByPageCount() throws Exception {
		return userDAO.findUserListByPageCount();
	}
}

3.3.13 spring配置Service对象applicetionContext.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"
    xsi:schemaLocation="
    	http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 创建数据源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/userdb?characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>
	<!-- 创建SQL执行对象 -->
	<bean id="qr" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
		<constructor-arg name="ds" ref="dataSource" />
	</bean>
	
	<!-- 创建DAO对象 -->
	<bean id="userDAO" class="com.hnxy.dao.impl.UserDAOImpl">
		<property name="qr" ref="qr" />
	</bean>
	
	<!-- 创建Service对象 -->
	<bean id="userService" class="com.hnxy.service.impl.UserServiceImpl">
		<property name="userDAO" ref="userDAO" />
	</bean>
</beans>

至此Spring引入CURD项目完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值