既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
- 内容:调用service+Scanner
1.4、完整实现步骤
- 书写实体类
package com.bz.entity;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String username;
private String pwd;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
public User(Integer id, String username, String pwd) {
this.id = id;
this.username = username;
this.pwd = pwd;
}
}
- 书写DAO
package com.bz.dao;
import com.bz.entity.User;
/\*\*
\* 跟数据库对接:从数据库中查找user信息
\*/
public interface UserDao {
/\*\*
\* 查询用户信息是否存在
\* @param username 用户名
\* @param pwd 密码
\* @return 用户对象
\*/
User selectUser(String username,String pwd) throws Exception;
}
- 书写DaoImpl
package com.bz.dao.impl;
import com.bz.dao.UserDao;
import com.bz.entity.User;
import com.bz.util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDaoImpl implements UserDao {
@Override
public User selectUser(String username, String pwd) throws Exception {
User user=null;//用来返回
Connection conn= JDBCUtils.getConnection();
String sql = "select \* from t\_user where u\_username=? and u\_pwd=?";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2, pwd);
ResultSet rs=ps.executeQuery();
if (rs.next()) {
Integer id = rs.getInt("u\_id");
String name = rs.getString("u\_username");
String password = rs.getString("u\_pwd");
user = new User(id, name, password);
}
JDBCUtils.close(rs,ps,conn);
return user;
}
}
- 书写Service
package com.bz.service;
public interface UserService {
/\*\*
\* 用户登录
\* @param username 用户输入的账号名
\* @param pwd 用户输入的密码
\* @return 是否登录成功
\*/
boolean login(String username,String pwd) throws Exception;
}
- 书写ServiceImpl
package com.bz.service.impl;
import com.bz.dao.UserDao;
import com.bz.dao.impl.UserDaoImpl;
import com.bz.service.UserService;
public class UserServiceImpl implements UserService {
//创建Dao对象
private UserDao ud=new UserDaoImpl();
@Override
public boolean login(String username, String pwd)throws Exception {
if (ud.selectUser(username, pwd)!=null) {
return true;
}else{
return false;
}
}
}
- 书写view
package com.bz.view;
import com.bz.service.UserService;
import com.bz.service.impl.UserServiceImpl;
import java.util.Scanner;
/\*\*
\* 用户登录
\*/
public class UserloginTest {
public static void main(String[] args) throws Exception{
UserService us=new UserServiceImpl();
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username=sc.next();
System.out.println("请输入密码:");
String pwd=sc.next();
//调用Service方法判断登录是否成功
if (us.login(username,pwd)){
System.out.println("登录成功!");
}else {
System.out.println("登录失败");
}
}
}
2、事务及JDBCUtils最终版
- 回顾事务概念:将多个操作步骤归为同一个原子操作,要么同时成功,要么同时失败
开启事务
执行操作
结束事务:commit rollback
- 通常需要添加在Service层,Service层的所有功能方法都应该配套事务
2.1、事务基本操作与问题解决
- 开启事务:
Connection对象.setAutoCommit(false)
- 结束事务:
- 提交:
Connection对象.commit();
- 回滚:
Connection对象.rollback();
- 提交:
2.1.1、存在问题
操作事务和操作数据库数据的数据库连接不是同一个,或导致事务回滚不会影响数据库内容
2.1.2、解决方案:ThreadLocal
-
思路: 放入线程的存储空间中,
Service
和DAO
不再自行创建conn
,如有需要,直接从线程存储空间中取出 -
实现:
- 确保工具类只会创建一个
conn
对象 - 使用
ThreadLocal
将工具类创建的conn对象放入存储空间
ThreadLocal:可以操作线程存储空间的工具,可以对空间的数据进行添加、获取、删除
添加:ThreadLocal对象.set(数据)
获取:ThreadLocal对象.get()
删除:ThreadLocal对象.remove()
- 确保工具类只会创建一个
-
使用:
- 由于DAO和Service共用同一个conn,并且Service一定晚于DAO执行结束,所以为了确保Service的执行,DAO中不能关闭conn,该操作应由Service完成
2.2、JDBCUtils-最终版
package com.bz.util;
import java.io.InputStream;
import java.sql.\*;
import java.util.Properties;
/\*\*
\* 工具类:方便方法调用,所有方法都应为静态方法
\*/
public class JDBCUtils {
//提升集合的作用范围,确保getConnection方法中也能使用
private static Properties p=null;
//创建操作线程存储空间的工具对象
private static ThreadLocal<Connection> tl=new ThreadLocal<>();
//把流对象的创建放入静态初始代码块,确保在工具类类加载时执行
static{
try(
//通过类对象.getResourseAsStream()获取一个字节输入流对象
//当前配置文件在src之下
InputStream is=JDBCUtils.class.getResourceAsStream("/jdbc.properties");
){
//创建用来接收的Properties集合
p=new Properties();
//调用方法加载配置文件的内容至集合中
p.load(is);
//1. 加载驱动
Class.forName(p.getProperty("driverClassName"));
}catch (ClassNotFoundException e) {
System.out.println("驱动路径不正确");
} catch (Exception e){
e.printStackTrace();
}
}
/\*\*
\* 获取Connection连接
\* @return
\*/
public static Connection getConnection(){
Connection conn =tl.get();
try {
if (conn==null) {//这里如果线程存储空间里没有conn就创建conn并存入线程空间
//2. 获取连接
//连接的url
String url = p.getProperty("url");
//用户名
String username = p.getProperty("username");
//密码
String pwd = p.getProperty("password");
conn = DriverManager.getConnection(url, username, pwd);
//将新创建的conn放入线程的存储空间
tl.set(conn);
}
} catch (SQLException e) {
System.out.println("获取连接失败");
} catch (Exception e) {
System.out.println("未知异常");
e.printStackTrace();
}
return conn;
}
/\*\*
\* 关闭资源连接 非空判断:防止空指针
\* @param rs
\* @param ps
\* @param conn
\*/
public static void close(ResultSet rs, PreparedStatement ps,Connection conn){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
![img](https://img-blog.csdnimg.cn/img_convert/7b4cf73a69feca29e31d715eedef41e8.png)
![img](https://img-blog.csdnimg.cn/img_convert/28c3900a00415fe10b1f03e746125c3b.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-nNNc86rQ-1715636640793)]
[外链图片转存中...(img-40zfOgmx-1715636640793)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**