通过java语言实现数据库用户增删改查

这篇博客介绍了如何使用Java进行数据库的增删改查操作,并深入探讨了JDBC中的事务管理。作者讨论了事务的ACID特性,强调了在处理事务时保持连接一致性的重要性。为了解决这个问题,提出了使用ThreadLocal来管理事务与连接,确保 Dao 操作和业务层的事务在同一连接上。此外,还提到了连接池的使用以及如何避免并发问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDBC day03

增删改查

public class UserDaoimpl implements UserDao {

DataSource ds = new ComboPooledDataSource();
QueryRunner qu = new QueryRunner(ds);
@Override
public void saveUser(User user) {//插入一条用户信息 增
	String sql = "insert into user_dao values(null,?,?,?,?,?,?)";
	try {
		qu.update(sql, user.getUsername(),user.getPassword(),user.getRealname(),user.getEmail(),user.getBirthday(),user.getGender());
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

@Override
public void removeUserById(int id) {//移除用户 删
	String sql = "delete from user_dao where id = ?";
	try {
		qu.update(sql,id);
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

@Override
public void modifyUser(User user) {//修改用户信息  改
	String sql = "update user_dao set id=null,username =?,password1=?,realname=?,email=?,birthday=?,gender=? where id =? ";
	try {
		qu.update(sql, user.getUsername(),user.getPassword(),user.getRealname(),user.getEmail(),user.getBirthday(),user.getGender(),user.getId());
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

@Override
public User getUserById(int id) {//查询指定id的用户 查
	String sql = "select * from user where id = ?";
	User user;
	try {
		user = qu.query(sql, new BeanHandler<User>(User.class), id);
		return user;
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
}

@Override
public List<User> getAllUsers(){//查询所有用户 查
	String sql = "select * from user_dao";
	try {
		List<User> query  = qu.query(sql, new BeanListHandler<User>(User.class));
		return query;
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
}

@Override
public int getUserCount() {//查询共有几个用户 查
	String sql = "select count(1) from user_dao";
	try {
		long count =(Long)qu.query(sql, new ScalarHandler());
		int i = (int)count;
		return i;
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return 0;
}

@Override
public User getUserByIdPwd(int id, String pwd) {
	// TODO Auto-generated method stub
	return null;
}

}

public class UserDaoTest {

private UserDao ud=null;

@Before
public void before() {
	ud = new UserDaoimpl();
}

@Test
public void saveUser() {//--------------增
	User user = new User();
	user.setUsername("zhelin1");
	user.setPassword("Szl12345");
	user.setRealname("史浙林");
	user.setEmail("coral8878@163.com");
	user.setBirthday(new Date());
	user.setGender("男");
	ud.saveUser(user);
}

@Test
public void removeUserById() {//------------------删
	ud.removeUserById(1);
}
@Test
public void modifyUser() {//------------------------改
	User user =new User();
	user.setUsername("zhangsan");
	user.setPassword("12345");
	user.setRealname("张三");
	user.setEmail("zahngsan@163.com");
	user.setBirthday(new Date());
	user.setGender("男");
	user.setId(5);
	ud.modifyUser(user);
}
@Test
public void testGetCount() {//-----------------------查
	int i = ud.getUserCount();
	System.out.println("总共有"+i+"个数据");
}

@Test
public void testFindAll() {//--------------------------查
	List<User> list = ud.getAllUsers();
	for(User user : list) {
		System.out.println(user);
	}
}
@Test
public void testGetUserById() {//-----------------------查
	User user = ud.getUserById(3);
	System.out.println(user);
}

}

笔记

回顾:
JDBC Sql注入
预编译 PrepareStatement

连接池优势:
	不需要频繁创建、关闭连接
	效率有一定提高	

处理结果集太麻烦 - DBUtils
QueryRunner qu = new QueryRunner(dataSource);
qu.query(sql, new BeanListHandler(Class));


业务处理 数据处理
系统相关 增删改查 CRUD

登录操作:控制器
1.从前端获得用户名、密码
2.和数据库中的对比
3.登录成功/失败

一个表 -> 实体类 -> Dao接口

业务中不能拆分的最小单位:事务
事务
原子性
一致
持久
隔离

JDBC操作事务,必须保证连接是同一个

问题一:
Dao 业务
开启事务:业务
提交、回滚事务:业务

事务是和连接绑定在一起
结论:要保证业务中开始事务的连接和Dao中操作数据的连接是同一个

解决方案:事务绑定在线程中 ThreadLocal
1.DataSourceUtils - getConnection()
- 和当前线程绑定的connection对象
- 第一次get,先要set
2.Dao实现类中,DML操作,先传递一个指定的Connection对象

问题二:
每个DAO中都创建一个连接池

结论:每个项目中,连接池只创建一个
解决方案:封装一个DataSource的工具类

线程并发:多个线程之间共用同一个资源
加锁:用时间换空间

ThreadLocal:用空间换时间
把公用的对象,给不同的线程创建了一个独立的副本

get()
set(T)
remove()

initialValue

详见:https://blog.youkuaiyun.com/hz_liuzb/article/details/98170689	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值