java笔记
java初始化
注意类名和文件名要保持一致
public class Main{
public static void main(String[] args)//psvm然后回车可以直接打出这一行
{
System.out.println("hello world");
}
}
实例化
Connection conn=new Connection();,前半部分是定义一个新变量,后半部分是实例化
包名用公司域名翻转+项目名字+时间,(d0717就是day七月十七号)
注意类名和文件名要保持一致
public class Main{
public static void main(String[] args)//psvm然后回车可以直接打出这一行
{
System.out.println("hello world");
}
}
java的基本函数
文件读写
文件写入
//创建用户的数据文件
String filePath="D:\\Program Files\\Java\\java program\\program code\\src\\cn\\edu\\nefu\\mySchoolEntertainment\\d0717\\userData.txt";
//创建文件输出流,有true是在文件结尾追加,没有true的话是覆盖原来文件内容
FileWriter fw=new FileWriter(filePath,true);
//BufferedWriter字符缓冲流
BufferedWriter fout=new BufferedWriter(fw);
//往刚刚定义的fout中写入数据
fout.write(userId+","+userName+","+userPassword+","+userPhoneNum+","+userEmail+","+userMoney+"\n");
//写完之后释放
fout.close();
文件读取
//每组六个数据为一维,所有数据存入二维数组
public String[][] checkReuse(String filePath){
String[][] oldWords=new String[100][6];
//定义FileReader类型数据fr用于后面读取数据
FileReader fr;
try{
//读取数据
fr=new FileReader(filePath);
BufferedReader fin=new BufferedReader(fr);
String line;
String[] oldWord;
int count=0;
//按行读取
while((line=fin.readLine())!=null){
//每行数据按,分割回六个数据存入一维数组oldWord
oldWord=line.split(",");
//所有一维数组存入二维数组oldWords
oldWords[count]=oldWord;
count++;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return oldWords;
}
正则表达式
a.matches(正则表达式)检验是否合规
public String checkUserPhoneNumber(){
System.out.println("请输入您的电话号码: ");
String userPhoneNum;
boolean result;
//国内电话的正则表达式
String regex="[0-9-()()]{7,18}";//可以用正则表达式生成器生成
while(true){
userPhoneNum=sc.next();
result=userPhoneNum.matches(regex);//检验电话号码是否合规
if(result==true){
break;
}
System.out.println("你输入的电话号码是错误的,请重新输入: ");
}
return userPhoneNum;
}
寻找所有合规字符
String a="abcde123";
//正则表达式
String regex="[1-9]";
//定义Pattern型变量存放正则表达式
Pattern p=Pattern.compile(regex);
//匹配a中符合正则表达式的字符
Matcher m=p.matcher(a);
String num="";
while(m.find()){
//注意m.group()每次获取一个字符
num+=m.group();
}
System.out.print(num);
replaceall正则替换
//数据包含各种特殊字符(\r-回车符,把当前位置移动到本行开头也就是本行\r符之前的全消失)
String s = "1,2,\r,Hello,\n,world,,123, s---,#$%^&";
System.out.println(s);
/*
原输出:
,Hello,
,world,,123, s---,#$%^&
*/
String s1 = s.replaceAll("[^0-9a-zA-Z]", "");//把符合正则表达式的全用后面的替换
System.out.println(s1);//输出:12Helloworld123s
正则表达式符号
常用元字符
. | 匹配除换行符以外的任意字符 |
---|---|
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
常用限定符
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
常用反义词
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
split函数分割
String str2="wang,song,zhao,han,xu";
String[] str3=str2.split(",");//以,为分割
System.out.println(str3[2]);
indexOf函数
1、str.indexOf(104);或者str.indexOf(‘h’);查找某个字符所在的下标位置,查找失败结果为-1;
2、str.indexOf(“hell”);查找某个字符串所在的位置,查找失败结果为-1;
3、str.indexOf(101, 4);或str.indexOf(‘h’,4);从某个下标位置开始查找某个字符所在的位置,查找失败结果为-1;
4、str.indexOf(“che”, 0);从某个下标位置开始查找某个字符串所在的位置,查找失败结果为-1
类型
整型
byte型
范围为-128到127
占一位
原因是一个字节最大值是01111111,也就是127,最小值是11111111,也就是-127(第一位是符号位,0为正1为负)
short型
范围-3万到三万
占两位
int型
范围为-21亿到21亿
占四位
long型
范围-900亿亿到900亿亿
占八位
注意long类型的定义时候,如果数据不大直接写就行,如果数据特别大,数据值最后要加一个L,小l其实也可以,但容易混淆
浮点型
float型
小数可用位数比较少,占四位,数据末位要加F
double型
小数可用位数多,占八位
布尔型
用boolean定义,只能是true或false不能用0或1代替,占1位
字符型
注意!!!字符型java中占两位,所以字符可以是中文
字符串型
String定义
不能用==比较
BigDecmail类型
比double精度更高
取值范围
double>float>long
特殊字符
空类型
表示什么都没没有,用null表示,注意null不能直接打印
‘\r’回车符
把当前位置移动到本行开头,本行‘\r’符之前的都会消失
‘\t’制表符
将前面的数据补齐到八的倍数,比如三个字母就补齐到八位,九个字母就补齐到十六位
但要注意在idea中默认补齐到四位,目前还没找到在哪里调整
public class Main {
public static void main(String[] args) {
System.out.println("name"+'\t'+"ac");
System.out.println("tott"+'\t'+"23");
}
}
打印函数
输出任意类型数据,没有换行符
printf
和c类似,可输出各种类型各种精度等等的东西
println
输出数据,有换行符
关键字
class
class+类名+{},表示定义/创建一个类,类名是后面那个,大括号表示类的范围
变量
定义
一行可以定义多个变量,比如int a=1,b=2,c=3;
进制
进制表示
0b表示二进制
0x表示十六进制,10到15由a到f代替
0开头表示八进制
进制转换
其他进制转十进制
系数(某一位上的数)*基数(要转换的进制数2/8/16)的权(位数+1,比如个位的权是0,十位是1)次幂,最后得到的几个数字相加就是
Ps:二进制可以8421快速转换法,从末位往前依次是1,2,4,8,16,32,64,128,哪一位是1就取对应数字,是0取0,因为一般只会算四位,所以是8421
十进制转其他进制
一直除要转到的进制数指导商为0,把所有余数倒着拼起来
颜色函数
红绿蓝三原色,每种颜色的深度范围为0-255,通过不同的搭配就可以得到不同颜色,比如
(255,0,0)表示纯红色,十六进制表示为0xFF0000
(0,255,0)表示纯绿色,十六进制表示为0x00FF00
(0,0,255)表示纯蓝色,十六进制表示为0x0000FF
因此颜色值最大为0xFFFFFF(第12,34,56位分别代表红绿蓝,也称为RGB)
标识符
标识符组成
由字母,数字,下划线,美元符($)组成
数字不能打头
不能是关键字,但关键字换了某个字母大小写是可以的
标识符命名建议
小驼峰命名法:方法,变量
标识符是一个单词全小写
标识符由多个单词组成,第一个小写,其他的首字母大写
大驼峰命名法:类名
每个单词首字母都大写
包名
公司域名反转为前缀,然后是项目名(都变成小写),然后是时间,比如cn.edu.nefu.myjavaproject.d0717就是一个包名,(d0717就是day七月十七号)
运算符
算术运算符
包括+,-,*,/,%
整数参与计算只能得到整数,余数会被忽略
小数参与计算可能不精确,后面会学
自增自减运算符
和c语言一样
a++是先用后+
++a是先加后用
比如a等于10,如果b=a++,那么b为10,a为11
如果b=++a,那么b为11,a为11
赋值运算符
有+=,-=,*=,/=,%=,比如a+=b就是a=a+b
Ps:这些运算符隐藏了一个强制转换,会把右边的类型强制转换为左边的类型
逻辑运算符
& 与
如果是两个数字,比如a&b,其中a是15,b是10,那么就是计算a的二进制展开和b的二进制展开,同一位上的两个数字&,0是False1是True
比如a的二进制展开某一位是0,b的同一位是1,那么结果的那一位就是0
|或
! 非
^ 异或
相同取False 不同取True(可以按结婚来算,异性恋可以去民政局)
注意短路逻辑运算符&&和||和&和|区别在于&&和||如果左边能确定整个式子的结果则不再判断右边
位运算符
x<<y相当于x*( 2^y ) ;x>>y相当于x/(2^y)注意保留整数
三元运算符
a?b:c表示若a为真则执行b,若a为假则运行c
import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
int a,b,c;
Scanner sc=new Scanner(System.in);
a=sc.nextInt();
b=sc.nextInt();
c=sc.nextInt();
int max=(a>b?a:b)>c?(a>b?a:b):c;
System.out.println(max);
}
}//得到的结果是56
运算
不同类型数据做运算需要数据类型转换
隐式转换
规则一
小数据类型比如int会被自动转化为大数据类型比如float
比如10+2.5时候10会被自动转化为10.0
规则二
byte,short,char类型会先被转换为int再计算
计算完会转换回来!!!
比如byte a,byte b,c=a+b则c的类型是int而非byte,这点要注意!!!
public class Main {
public static void main(String[] arg) {
byte a = 15;
byte b = 16;
int c = a + b;
System.out.println(c);
}
}
强制转换
把一个取值范围大的数据赋值给范围小的数据就需要强制转换
转换完后数据类型就固定了,不会转换回来
如果不转换会出问题!!!
public class Main {
public static void main(String[] arg) {
double a = 15.7;
int b = (int) a;
System.out.println(b);
}
}//得到的结果是15
但注意数据会出现一些问题,比如double转为int时候15.7就会变成15
出问题是因为在计算机中比如int类型的a是300,二进制就是0000 0000 0000 0000 0000 0001 0010 1100
转换成byte类型就要把前面删除一直到剩下八位,得到0010 1100,跟原来就不一样了
字符串相加
规则一:当+运算中出现字符串时候就表示连接前后形成新串
public class Main {
public static void main(String[] arg) {
String a = "123";
double b = 123.6;
String c=a+b;
System.out.println(c);
}
}//得到的结果是123123.6
规则二:连续进行+操作会从前往后运算
public class Main {
public static void main(String[] arg) {
String a=1+2+"abc"+'a'+1+2;
System.out.println(a);
}
}//得到结果是 3abca12
字符相加
规则
若字符+字符 ,会将asc码值相加(A是65,a是97)
若字符加数字,会字符的asc码值和数字相加
得到的结果是asc码的值
字符和字符串相加请参考字符串相加的规则二
public class Main {
public static void main(String[] arg) {
System.out.println('a');//a
System.out.println('a'+57);//154
System.out.println('a'+"helloworld");//ahelloworld
System.out.println('a'+'b');//195
}
}
原码,反码,补码
反码
反码是原码符号位不变,其余位取反,原码用来表示负数,反码用来计算负数
比如-4的反码加一得到负三的反码,但-4的原码加一得到的实际上是-5的原码
补码
一个数的补码是大一的数的反码,比如-4的补码是-3的反码,也就是说补码是反码+1(补码主要是因为反码的计算会导致0有两个值)
这也导致-128是有补码但没有反码和原码,所以取值是-128到127
计算机数据的存储计算是由补码进行的
this.名字
访问当前类的方法,变量等等什么都可以
Scanner函数键盘赋值
import java.util.Scanner;//导包,找到Scanner的位置,注意要写在类定义的上面
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);//创建对象,表示我要用scanner这个类
int i=sc.nextInt();//把键盘接受的值赋给变量i,如果i是double就是nextdouble,注意字符串是特殊的,直接写next
System.out.println(i);
}
}
Random函数生成随机数(其实是伪随机)
跟Scanner很像,只是有两个地方不一样
import java.util.Random;
public class Main {
public static void main(String[] arg) {
Random r=new Random();//第一个不一样,()中什么也没有
int num=r.nextInt(1,100);//第二个不一样,要输入随机数范围,如果只写一个数默认0到那个数
//注意随机数是左闭右开的
System.out.println(num);
}
}
substring取子串函数
String str1="9513005@qq.com";
int length=str1.length();
System.out.println(str1.substring(0,length-7));//下标0到length-7(不包含)
System.out.println(str1.substring(7))//下标为7往后(包含)
trim函数去除字符串两端空格
因为输入用户名时候容易误按空格而且难以发现
a.trim()可以去掉a的两侧空格
StringBuilder字符串插入
String str="abcdefghij";
StringBuilder sb=new StringBuilder(str);
sb.insert(4,"123");
System.out.println(sb);//得到abcd123efghij
toCharArray转换数组函数
a.toCharArray()可以把字符串a转换成字符数组
if函数
用法跟c一样,但注意不要省略大括号
比如if(a>b) int c=10;就会报错
这是因为int那一句实际上是两句,包括定义和赋值
ifeach函数遍历
private boolean checkUserChoice(String[] checkBackstageData, String userChoice){
boolean result=false;
for(String data: checkBackstageData){//遍历数组checkBackstageData,每次遍历的元素赋给变量data
if(data.equals(userChoice)){//如果遍历时候发现数组中有元素和userChoice相等,说明用户输入的选项是正确的,返回true
result= true;
break;
}
}
return result;
}
Integer函数字符串转数字
String input = "123456";
int num = Integer.parseInt(input,16);//把字符串input转换成16进制的整型
Integer函数数字转字符串
int num =123456;
String str = Integer.toString (num);
replace函数关键词替换
a.replace(b,”c”)表示把a中的b都替换成c
Scanner sc = new Scanner(System.in);
String inputWord=sc.nextLine();
String[] keyWords={"荣","者","王","马","耀","超","标"};//关键字数组
for(String keyWord : keyWords){//遍历关键字数组,每次遍历到的值赋给变量keyWord
inputWord=inputWord.replace(keyWord,"*");//把inputWord中在关键字数组中的字替换成*
}
System.out.println(inputWord);
switch函数
取值为byte,short,int,char,JDK5之后可以是枚举,JDK7之后可以是String
第一种写法
如果没写break,正确取值之后的语句都会被执行,例如:
public class Main {
public static void main(String[] arg) {
int a=2;
switch(a){
case 1:
System.out.println(1);
case 2:
System.out.println(2);
case 3:
System.out.println(3);
default:
System.out.println(4);
}
}
}//结果是2和3
第二种写法(自带break不用再写break)
public class Main {
public static void main(String[] arg) {
int a=2;
switch(a){
case 1-> {
System.out.println(1);
}
case 2->{
System.out.println(2);
}
case 3-> {
System.out.println(3);
}
default->{
System.out.println(4);
}
}
}
}//结果是2
如果大括号里只有一句可以省略大括号
public class Main {
public static void main(String[] arg) {
int a=2;
switch(a){
case 1->System.out.println(1);
case 2->System.out.println(2);
case 3->System.out.println(3);
default->System.out.println(4);
}
}
}//结果是2
无限循环函数
比如while(true)或者for(;;)里面只写两个;
注意:无限循环下面不能再写代码,因为无限循环停不下来
continue函数
跳过本次循环,执行下一次循环
break函数
结束整个循环
equals函数
a.equals(b)表示判断a和b是否相等,输出的是布尔值
因为字符串是不能直接用==判断的
Math函数
Math.random()
是从0到1中随机生成一个数
如果想规定随机范围可以
public class CommonUse {
public static void main(String[] args) {
int min=10;
int max=20;
int num=(int)(Math.random()*(max-min+1)+min);//注意+1是因为强制类型转化为int
System.out.println(num);
}
}
Math.sqrt(a)
把a开方,结果是double类型的
数组
定义
数据类型 数组名 [ ] (比如int a[ ])
也可以用 数据类型 [ ] 数组名,两种一样
初始化
int a[ ]=new int [ ]{1,2,3}
其中new int []可以省略,也就是直接int a[ ]={1,2,3}
数组的打印值
直接打印数组名得到数组地址
集合
List(列表):有序
数组ArrayList()存储的数据类型是object类型的
//ArrayList是列表,此时存的对象是object类
ArrayList list=new ArrayList();
//加上<>可以存<>中数据类型的数据,注意<>中不能写基本数据类型
//要写基本数据类型的包装类型,其中int包装类型是integer,其他的都是首字母大写
//比如char包装类型是Char
//String可以写,因为String不是基本类型
ArrayList<String> names=new ArrayList<>();
ArrayList<String> names1=new ArrayList<>();
//如果一开始知道可能会存储的大小可以加进去,这样性能更好
ArrayList<String> names2=new ArrayList<>(1000);
//一个一个往列表最后加
names.add("张三");
names.add("李四");
names.add("张三丰");
names.add("张无忌");
//王五会被添加到最前面,说明Arraylist里面的位置不固定
names.add(0,"王五");
//会把整个names1数组加在names的最后
names.addAll(names1);
//会加到下标0的位置,跟上面一样
names.addAll(0,names1);
//会清空names列表的所有数据
names.clear();
//会获得names1中下标1的数据
names1.get(1);
//返回一个boolean类型的值表示看是否存在张三丰这个数据
names1.contains("张三丰");
//返回寻找数据的位置
names.indexOf("");
//删除等于给定数据的第一个,返回boolean
names.remove("");
//删除names在names中存在的数据,返回boolean
names.removeAll(names1);
//删除索引0的,返回删掉的值
names1.remove(0);
//把这个数组转换成另外一个类型的数组
names.toArray(char[]names5);
Set(集合):无序,没有重复值
//根据哈希算法算出每个数据特定的值,所以每个值只能存一次
HashSet<String> names6 =new HashSet<>();
names6.add("张三");
names6.add("李四");
names6.add("王五");
names6.add("张三");
//打印的话会得到李四张三王五,这是因为集合HashSet重复值会消失,并且是无序的,哈希值也不是有序排列,虽然无序,但永远都是这个顺序
Map(映射):有两个值,通过一个找到另外一个
HashMap<String,String> map=new HashMap<>();
map.put("张三","1");
map.put("李四","2");
map.put("张三","3");
map.get("张三");//第一个张三被覆盖,得到结果是3,如果是3,得到结果是张三
//遍历
//第一种:快的
for(Map.Entry<String,String>data:map.entrySet()){
System.out.println("");
}
java例题
回文数问题
题目
给一个数判断是否是回文数,是返回True,不是返回False
代码
import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
int num1=num;
int numBack=0;
while(num!=0){
numBack=numBack*10+num%10;//这一步是关键步骤
num/=10;
}
System.out.println(numBack==num1);
}
}
除法问题
题目
给定被除数和除数,不用乘除法和%,求他的商和余数
代码
import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
int num1=sc.nextInt();
int num2=num1;
int count=1;
int numBack=0;
while(num1<=(num-num2)){//易错点,如果num1<=num就会多循环一次
num1+=num2;
count++;
}
int Mod=num-num1;
System.out.println(count+"\n"+Mod);//一次输出多个数据,注意不要用'\n'这样会把字符换算成ASCII码值计算
}
}
逢七过问题
题目
给定一个开头数,一个结尾数,在这俩数之间的数,一个一个打印,若某个数是七的倍数或数字中含有七就打印过
代码
import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
int gameNum,Start,End,count;
Scanner sc=new Scanner(System.in);
Start=sc.nextInt();
End=sc.nextInt();
for(count=Start;count<End;count++) {
gameNum=count;
while (gameNum != 0) {
if (gameNum % 10 == 7) {
break;
}
else gameNum = gameNum / 10;
}
if (gameNum!=0||count % 7 == 0) {
System.out.println("过");
}
else{
System.out.println(count);
}
}
}
}
判断素数问题
题目
给一个数判断是不是素数
代码
import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
int prime,i;
Scanner sc = new Scanner(System.in);
prime = sc.nextInt();
boolean result=true;//重点思路,布尔型
if(prime!=2){
for(i=2;i<=(prime/2)+1;i++) {//重点标识,只需要判断到一半就行
if(prime%i==0){
result=false;
break;
}
}
}
System.out.println(result);
}
}
加密解密问题
题目
写一个加密解密系统
代码
import java.util.Scanner;
public class CommonUse{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
System.out.println("输入你的密文");
String darkMessage=sc.next();
System.out.println("输入你的秘钥");
int darkKey=sc.nextInt();
System.out.println(enCode(darkMessage,darkKey));
System.out.println("输入你的明文");
String lightMessage=sc.next();
System.out.println("输入你的解码秘钥");
int lightKey=sc.nextInt();
System.out.println(deCode(lightMessage,lightKey));
}
//加密方法
public static String enCode(String message,int key){
String data="";
//字符串转换成字符数组
for(char c:message.toCharArray()){
//先把字符转换成对应的Unicode码,加上秘钥再转换成对应字符
c=(char)((int)c+key);
data+=c;
}
return data;
}
//解密方法
public static String deCode(String message,int key){
String data="";
for(char c:message.toCharArray()){
c=(char)((int)c-key);
data+=c;
}
return data;
}
}
关键词屏蔽
题目
写一个关键词屏蔽系统
代码
import java.util.Scanner;
public class CommonUse {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String inputWord=sc.nextLine();
String[] keyWords={"荣","者","王","马超","耀"};
inputWord=replaceWord(keyWords,inputWord);
System.out.println(inputWord);
}
//关键词屏蔽函数
private static String replaceWord(String[]keyWords,String inputWord){
String temp="*";
//把对应屏蔽词的词语替换成*
for(String keyWord:keyWords){
for(int i=1;i<keyWord.length();i++){
temp+="*";
}
inputWord=inputWord.replace(keyWord,temp);
}
return inputWord;
}
}
JDBC
MVC三层架构
entity
写基础的getter和setter语法达到对对象封装保护的目的
与mysql中建立的表格和其中的字段一一对应
代码形式如下
package jdbcstandardproject.entity;
public class Student {
//Student 表对应的实体类,实现类对象和表之间的映射关系
//之所以要定义成private类型导致还得在方法中传递,是因为怕变量被随意更改,为了保护这个变量
//这样可以在方法中限定输入数据必须合法
private int student_id;
private String student_name;
private String student_gender;
private String student_phone;
public void setStudent_name(String student_name) {
this.student_name = student_name;
}
public void setStudent_phone(String student_phone) {
this.student_phone = student_phone;
}
public String getStudent_name() {
return student_name;
}
public String getStudent_phone() {
return student_phone;
}
//在类里面,方法外面定义的变量称为属性,也叫成员
public String getStudent_gender(){
//访问这里的private的student_gender
return this.student_gender;
}
public void setStudent_gender(String student_gender){
if(student_gender.equals("男")||student_gender.equals("女")){
this.student_gender=student_gender;
}else{
System.out.println("你输入的性别不正确,已设为默认值男");
this.student_gender="男";
}
}
public int getStudent_id(){
return this.student_id;
}
public void setStudent_id(int student_id){
this.student_id=student_id;
}
}
Dao
分为两部分,一部分写DBHelper,用来连接mysql数据库
同时还需再项目目录中新建一个目录导入数据库jar,并设置为库
代码形式如下
package jdbcstandardproject.dao;
import java.sql.*;
//建立一个类,用来连接和关闭数据库服务
public class DBHelper {
//getConnection函数用于连接数据库服务
public static Connection getConnection(){
//定义一个Connection类型的变量
Connection conn;
try {
//forName是class类的用法,返回一个class类的对象
Class.forName("com.mysql.cj.jdbc.Driver");
//一个DriveManager下的用法用来获取跟数据库的连接,三个语句分别是url,用户名,密码,其中url的组成是: 数据库的url/你要查询的数据库的名字?useUnicode=true&characterEncoding=UTF-8,用户名和用户密码填自己数据库对应的
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF-8","用户名","用户密码");
//最后返回这个Connection型的变量conn
return conn;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//回收数据库资源,这三项只要存在就把他关闭
public static void close(Connection conn, Statement st, ResultSet rs){
try {
if(conn!=null) {
conn.close();
}
if(st!=null){
st.close();
}
if(rs!=null){
rs.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
第二部分与entity中写好封装的相对应
写的是对这些对象执行相应操作的方法
代码形式如下
package jdbcstandardproject.dao;
import jdbcstandardproject.entity.Student;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//专门针对Student表进行CRUD操作
public class StudentDao {
//第一个方法:增操作,传入一个Student类的变量student(Student类是在包里我自己写的类)
public static int addStudent(Student student){
//定义一个Connection类型的变量conn,其值为DBHelper类中的getConnection的返回值
Connection conn =DBHelper.getConnection();
//定义sql语句,问号做占位符
String sql="insert into student values(?,?,?,?)";
//预编译类型,要多次执行查询的时候比Statement型更高效
PreparedStatement ps=null;
int result;
try {
//变量连接sql语句开始对表进行操作
ps=conn.prepareStatement(sql);
//填在第一个占位符中的数据
ps.setInt(1, student.getStudent_id());
ps.setString(2, student.getStudent_name());
ps.setString(3, student.getStudent_gender());
ps.setString(4, student.getStudent_phone());
//把所影响的行数赋给result变量
result=ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
//这里没用到ResultSet类型的所有把他赋null,不需要关闭
DBHelper.close(conn,ps,null);
}
//返回int类型的result(影响的行数)
return result;
}
//删操作,按id名进行删除操作,也可以写其他的方法按其他名删除,由于这里根本没有用到student类里面的方法所以不需要传进来student类的变量
public static int deleteByStudentId(int student_id){
Connection conn=DBHelper.getConnection();
//sql语句,student_data是用于查询的字段名
String sql="delete from student where student_id =?";
int result;
PreparedStatement ps=null;
try {
//sql语句传入预编译过的变量中
ps=conn.prepareStatement(sql);
ps.setInt(1,student_id);
result=ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBHelper.close(conn,ps,null);
}
return result;
}
//改操作,按id名进行修改操作
public static int modifyByStudent(Student student){
Connection conn=DBHelper.getConnection();
int result;
PreparedStatement ps = null;
String sql = "update Student student_phone=? where student_id = ?";
try {
ps=conn.prepareStatement(sql);
ps.setString(1,student.getStudent_phone());
ps.setInt(2,student.getStudent_id());
result=ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBHelper.close(conn,ps,null);
}
return result;
}
//查询操作,按照id查询,返回一个Student类型的值,因为要查的是一组值嘛,这里查的是单行数据
public static Student getByStudentId(int student_id){
Student student = null;
Connection conn = DBHelper.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
String sql="select * from student where student_id = ?";
try {
ps=conn.prepareStatement(sql);
ps.setInt(1,student_id);
//executeQuery返回值是接口,ResultSet类型,所以定义的rs是ResultSet类型的
rs = ps.executeQuery();
//只要rs还能往下搜索说明下面的数据没有被过滤掉说明数据属于合法数据
if(rs.next()){
//新建student类型的变量student
student=new Student();
//用student类里的setStudent_id方法给student_id赋值,然后rs让java从数据库中获取这个值,下面的以此类推
student.setStudent_id(rs.getInt("student_id"));
student.setStudent_name(rs.getString("student_name"));
student.setStudent_gender(rs.getString("student_gender"));
student.setStudent_phone(rs.getString("student_phone"));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBHelper.close(conn,ps,rs);
}
return student;
}
//这里查的是整张表的值,多行数据,用List<Student>类型,说明定义的是Student类型的List<>类型,套娃类型
public static List<Student> getAllStudents(){
//定义新的list数组存放student数组
List<Student> students = new ArrayList<>();
Connection conn = DBHelper.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
String sql="select * from student";
try {
ps=conn.prepareStatement(sql);
if (!rs.next()) {
//每次循环新建一个student
Student student = new Student();
student.setStudent_id(rs.getInt("student_id"));
student.setStudent_name(rs.getString("student_name"));
student.setStudent_gender(rs.getString("student_gender"));
student.setStudent_phone(rs.getString("student_phone"));
//每次循环把student接在students后面
students.add(student);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBHelper.close(conn,ps,rs);
}
return students;
}
}
controller
写运行函数
面向对象四步
类和类之间extends,类和接口直接implements,接口和接口extends
抽象:创建类
抽象类父类要加上abstract写成public abstract class
OOA
列举出对象的所有特征和行为
OOP
给对象以及特征和行为都分别写出他们的英文变量名和类型
OOP
以OOD中对象创建类,特征行为创建方法
封装:保护类
把对象定义为private权限,这样其他类无法直接访问,然后写getter和setter方法,其他类通过访问setter方法来访问this.对象,达到私有对象不可更改的保护目的
四个关键词
private私有的
此方法只能在类的内部使用
protected受保护的
只能在类的内部和子类访问
public公开的
可以在任何地方访问
默认(啥也不写的)
比如String str;
这里的str就是默认
只能在类的内部或者同一个包中访问
分类
成员变量封装
属性私有化
比如把默认格式的String str
写成private String str
添加setter和getter方法
自己编写的,并不是说引用这方法
比如编写public void setName(){}赋值
public String getName(){}取值
编写属性控制语句
在上面的setter,getter方法中编写属性控制语句
继承:重用类
构造方法和private类不能继承
多态(接口的继承)
接口可以有多个,逗号隔开接口名就行
接口命名必须以大写i开头
PS:注意接口类里的方法不能有主体,只能写一个空方法,这样才能做到接口的绝对安全