目标:(医疗管理系统)
Day1
内容回顾:
Java面向对象:封装、继承和多态(接口)
数据库MySQL (增删改查)
JDBC: Java连接数据库
JSP + servlet、Tomcat: 服务器
Springioc:控制反转
SpringMVC:对servlet 封装
Mybaits:JDBC封装
SSM整合:Spring+SpringMVC+Mybaitis
命名规则:
- 包名:反域名,纯小写 com.公司名.项目名
- 类名 采用大驼峰,即首字母大写,碰到新的单词首字母大写
- 方法名和变量名,采用小驼峰,首字母小写
- 常量,纯大写 final修饰的变量
- 实体类的命名 类名+Bean/Model/Entity/Data 例如PersonBean
解决问题:
- 将属性全部私有化,提供一个公有的方法访问私有的属性,提高安全性
构造方法:
== 和equals区别:
Equals 来源于object ,在java中一切类都继承了object ,在object中equals也是用==判断的
String类继承了Object,重写了equals方法,所有可以判断字符的内容是否相等
如果打印对象的每个属性值,需要重写toString方法,否则打印的是hash值
@Overridepublic String toString() {return "PersonBean{" +"pname='" + pname + '\'' +", age=" + age +", sex='" + sex + '\'' +'}';}
构造方法:作用是构造对象的,如果不写构造方法,会自动生成一个无参的构造方法,如果一旦自己写了,那么就没有无参的构造方法了
将来使用框架的时候,框架采用的是反射机制,需要利用无参的构造方法构造对象,所有创建类的时候一定要保证有一个无参的构造方法
静态代码块
静态static
静态方法:直接用类名.静态方法名调用即可,不需要创建对象,也可以先创建对象,再调用静态方法
实例方法必须先创建实例
public class StudentBean {
public StudentBean() {
System.out.println("构造");
}
/**
* 实例方法
*/
public void introduce_1(){
System.out.println("你好,我叫张三");
}
/**
* 静态方法
*/
public static void introduce_2(){
System.out.println("你好我叫李四");
}
}
public static void main(String[] args) {
//可以直接调用静态方法
StudentBean.introduce_2();
StudentBean s=new StudentBean();
s.introduce_1();
s.introduce_2();
}
//不需要调用,在类加载的时候,自动调用的,无论如何都最先执行
static {
System.out.println("这是静态代码块");
}
继承(多态)
继承:拥有父类中所有的至少protected修饰的方法,但是不能继承私有的方法,在构造的时候先构造父类,再构造子类
public class Animal {
private String name;
private String color;
public Animal(String name) {
this.name=name;
System.out.println("构造animal");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void play(){
System.out.println("动物玩。。。");
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name);//先构造父类
System.out.println("构造狗");
}
@Override
public void play() {
System.out.println("狗游泳");
}
}
public static void main(String[] args) {
Animal dog=new Dog("大黄");
dog.setColor("黄色");
dog.play();
System.out.println(dog);
}
接口和抽象类不能直接new对象,一般new他的子类或者接口的实现类
抽象类:
有抽象方法的类都是抽象类
抽象类中可以没有抽象方法
接口(多态)
接口是一个特殊的抽象类
接口中所有的方法都是抽象方法,不能有实例方法
关键字Interface
接口不能有实例变量,接口中所有的变量都是静态常量
接口中不能有私有的方法
一个接口可以继承多个接口,但是不能实现接口
一个类可以实现多个接口,但是只能继承一个类
public interface I {
void i_1();
}
public interface II {
void ii_1();
}
public interface Usb extends I,II{
//接口的变量都是公有的静态的常量
final public static double PI=3.14;
void work();
public abstract void stop();
default void tt(){
System.out.println("111111");
}
}
public class Computer implements Usb,I,II {
@Override
public void work() {
System.out.println("电脑上网");
}
@Override
public void stop() {
System.out.println("断电了");
}
@Override
public void tt() {
System.out.println("电脑开机了");
}
@Override
public void i_1() {
}
@Override
public void ii_1() {
}
}
public static void main(String[] args) {
// Usb u=new Computer();
Usb u=new UStroge();
u.work();
u.stop();
u.tt();
// Usb.PI=3.15;
System.out.println(Usb.PI);
}
Java集合框架
List
集合的添加和删除,遍历
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(111);
list.add(2222);
list.add(3333);
//获取集合中元素的个数
System.out.println(list.size());
System.out.println(list.get(0));
//删除
list.remove(2);
System.out.println(list.size());
for (int i=0;i<=list.size();i++){
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
PersonBean p1=new PersonBean("aaa");
PersonBean p2=new PersonBean("bbb");
PersonBean p3=new PersonBean("ccc");
List<PersonBean> list=new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
//删除对象
list.remove(p1);
for(PersonBean p:list){
System.out.println(p);
}
}
set
无序,不能重复
实现原理:直接new了一个hashmap,在添加元素的时候,将元素作为hashmap的key值,value直接设置成object,最终只取key,而舍弃value。
public static void main(String[] args) {
Set<String> set=new HashSet<>();
set.add("aaa");
set.add("aaa");
set.add("bbb");
set.add("ccc");
for(String s:set){
System.out.println(s);
}
}
Hashmap
以key-value方式存储。并且key和value默认是object类型
public static void main(String[] args) {
Map<String, PersonBean> map=new HashMap<>();
map.put("aaa",new PersonBean("AAAA"));
map.put("bbb",new PersonBean("BBBB"));
System.out.println(map);
}
线程安全不安全:
线程同步:单车道行车,线程排队
线程异步:多车道行车,哪个线程抢占资源先执行
线程死锁:资源抢占,比如两个人饭店吃饭,老板给了一双筷子,一人抢了一只筷子互不相让,导致处于相互等待的情况
线程锁的使用。
Day2
数据库:
数据库简介:
- 关系型数据库:每一张表都不是独立存在的,可能与另外几张表有着某种关系,比如一对一,一对多,多对多。Sqlserver(微软),mysql(甲骨文),oracle(甲骨文),sqllite….
- 非关系型数据库:每一条数据都是独立,以key-value的形式存储的,常用的redis
MySQL数据库 + Navicat
操作数据库
显示所有的数据库:show databases;
创建数据库 create database tt default character set utf8;
删除数据库 drop database 数据库名;
使用指定的数据库:use 数据库名
数据库中数据类型:
- Int 整型
- Float double 小数类型
- Varchar(字符串长度) 字符串类型 不定长
- Char(字符串长度) 字符串类型 一般不用 定长
- Datetime 时间类型
创建表
Create table 表名(
字段名 类型 ,……
)删除表 drop table 表名
操作表数据
Navicate连接mysql



创建表
\# 注释
-- 创建表
CREATE table person(
pid int ,
pname varchar(20)
);
添加数据
Insert into 表名(字段列表,....) values(字段值,.......),(字段值....)....
insert into person(pid,pname)values(1,'张三'),
(2,'李四'),(3,'王五')
删除
语法:delete from 表名 where 条件
注意:慎用delete ,在企业中一般是禁用的,一般企业做法是在每一张表中预留一个状态status字段,一般0表示正常数据,9999代表删除的数据
delete from person where pid=3
-- 创建userinfo表,设置主键自动增长
create table userinfo(
uid int PRIMARY key auto_increment,
uname varchar(20)
);
-- userinfo添加数据,主键不用管
insert into userinfo(uname) value('张三'),
('张三') ;
删除:
TRUNCATE TABLE userinfo 这种删除方式比较彻底,先删除整个表结构,再重新创建,所以主键id又会从1开始,删除的速度比较高,但是不能加条件,一定要慎用
修改数据
语法:update 表名 set 字段名=新的值, ..... where 条件
update userinfo set uname='老王' where uid=2
update userinfo set uname='王五',address='延安' where uid=2;
查询
语法 select 字段1,字段2...... from 表名 (where 条件)
-- 查询所有
select uid ,uname ,address from userinfo
select * from userinfo ;
-- 查询uid>=2的数据
select * from userinfo where uid>=2;
-- 模糊查询 地址中含有‘安’的数据
SELECT * from userinfo where address like '%安%'
-- 查询地址是西安的数据
select * from userinfo where address='西安';
-- 查询uid在2和3之间的
SELECT * from userinfo where uid BETWEEN 2 and 3
SELECT * from userinfo where uid>=2 and uid<=3
-- 查询id=2或者id=3,或者=1的
select * from userinfo where uid=2 or uid=3 or uid=1
select * from userinfo where uid in(1,2,3)
select * from userinfo where uid not in(2,3)
外键约束
一对一设置外键:

-- 创建person表
create table person(
pid int PRIMARY key auto_increment,
pname VARCHAR(20)
);
insert into person(pname)VALUEs('张三'),('李四')
-- 创建身份证表
create table cardinfo(
cid int PRIMARY key auto_increment,
cnum varchar(20),
fk_pid int,
FOREIGN key(fk_pid) REFERENCES person(pid);
-- 给张三添加身份证号码
insert into cardinfo(cnum,fk_pid)values('11111',1);
insert into cardinfo(cnum,fk_pid)values('22222',2)
-- 主表中数据正在被从表使用,是删不掉的
delete from person where pid=1;
-- 只有先删除从表中正在使用的数据,才能删除从表的数据
delete from cardinfo where fk_pid=1
多表联合查询
内连接 等值连接 返回所有的满足条件的数据
等值连接

-- 查询每个人对应的身份证号码, 等值连接
-- 等值连接:select * from 主表 主表对象,从表 as 从表对象 where 条件
select * from person p,cardinfo as c where
p.pid=c.fk_pid
-- 内连接 innner join 表 on 连接条件
-- 内连接:select * from 主表 主表对象 innner join 从表 从表对象 on 条件
select * from person p INNER JOIN cardinfo c
on p.pid=c.fk_pid
外连接
分为左外链接和右外连接
左外连接 返回左表中所有的数据,返回右表中只有满足条件的数据
-- 左外链接
SELECT * from person p LEFT JOIN cardinfo c
on p.pid=c.fk_pid;
-- 右外连接
SELECT * from cardinfo c right JOIN person p
on p.pid=c.fk_pid;
一对多:

create table customer(
cid int PRIMARY key auto_increment,
cname VARCHAR(20)
);
insert into customer(cname)values('张三'),('李四')
-- 创建订单表
create table orderinfo(
oid int PRIMARY key auto_increment,
price DOUBLE,
fk_cid int,
FOREIGN key(fk_cid) REFERENCES customer(cid)
);
insert into orderinfo(price,fk_cid) values
(100,1),(200,1),(300,1),(400,2),(500,2);
SELECT * from customer c left join orderinfo o
on c.cid=o.fk_cid
多对多:

-- 多对多
create table teacher(
tid int primary key auto_increment,
tname varchar(20)
);
-- 课程表
create table course(
cid int PRIMARY key auto_increment,
cname varchar(20)
);
create table teac_course(
fk_tid int ,
fk_cid int,
foreign key(fk_tid) REFERENCES teacher(tid),
FOREIGN key(fk_cid) REFERENCES course(cid)
);
insert into teacher(tname) values('张三'),('李四')
insert into course(cname) values('java'),('C++')
,('python');
insert into teac_course(fk_tid,fk_cid)values
(1,1),(1,2),(2,2),(2,3),(2,1);
-- 查询每位老师教的课程
select t.tname,c.cname from teacher t,teac_course ts,
course c where t.tid=ts.fk_tid
and ts.fk_cid=c.cid

常用的查询
排序:
select * from userinfo ORDER BY uid desc;
Desc 降序 ,asc 升序(默认)
函数:
普通函数
select now();
select concat('你','好','世界');
select SUBSTR('helloworle',3,4);
聚合函数:
Count 数据的条数
Avg 平均值
Sum 求和
Max 最大值
Min 最小值
select count(*)条数, sum(age) 年龄和,
avg(age)平均年龄,max(age)最大年龄,
min(age)最小年龄 from userinfo
子查询:
将一个查询的结果作为另外一个查询的条件
-- 查询和赵四年龄相同的人
select * from userinfo where age=(select age
from userinfo where uname='赵四')
Maven的操作
Maven作用:
- 可以将一个大项目拆分成多个子模块,统一管理父项目即可
- 添加依赖,可以自动下载项目中所需要的第三方jar包
- 插件的支持,可以获取项目所需要的插件,比如tomcat
- 解决jar之间的冲突
目录结构:

设置本地仓库地址:将来下载的jar,或者是打包结果放在此文件夹下面

设置中央仓库镜像

设置jdk的版本号

使用maven,在idea中使用



新建maven项目


设置自动下载maven的依赖

学习maven就是学习配置pom.xml
使用依赖:
- 找到maven中央仓库的坐标 https://mvnrepository.com


<dependencies>
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
</dependencies>
JDBC
Jdk给提供一套连接数据库的接口规范,这些接口是由各种数据库厂商实现,所有,如果想使用jdbc,必须去对应的数据库厂商下载对应的数据库驱动
操作数据库步骤(三个接口一个类):
加载驱动
DriverManager.getConnection(url,用户名,密码)获取连接对象Connection接口
Statement 接口,执行sql语句
如果执行的是查询,获取结果ResultSet
导入依赖:
<dependencies>
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
测试Jdbc:
/**jdbc 完成更新数据的操作
* @throws Exception
*/
@Test
public void t1() throws Exception {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接 url规则:jdbc:数据库类型://ip:端口/数据库名?编码格式
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8",
"root", "123456");
//3.获取statement实例
Statement statement = con.createStatement();
//4.执行sql
int row=statement.executeUpdate("update userinfo set uname='老王',age=30 where uid=2");
System.out.println("影响了"+row+"行");
//5.关闭资源
con.close();
statement.close();
}
/**
* 测试查询
*/
@Test
public void t2() throws Exception {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8",
"root", "123456");
//3.获取执行sql的statement
Statement statement = con.createStatement();
//执行查询,获取结果集
ResultSet resultSet = statement.executeQuery("select * from userinfo");
//遍历结果集
while (resultSet.next()){//每执行next()一次,光标往下移动一行
//获取当前行的每一列值
int uid= resultSet.getInt(1);//根据列号获取,注意列号从1开始
String uname=resultSet.getString("uname");
String add=resultSet.getString("address");
int age=resultSet.getInt(4);
System.out.println(uid+"\t"+uname+"\t"+add+"\t"+age);
}
con.close();
statement.close();
resultSet.close();
}
Day3:
内容回顾:
建表 create table 表名(字段名 数据类型,…….)
Insert 表名(字段列表,.,.,) values(字段值,.,……)
Delete from 表名where 条件
Truncate table 表名 直接将表结构删除,重新建表
Update 表名 字段=字段值,……. where 条件
Select 字段列表,.,.,…. from 表名 (where 条件)
函数:now(),concat(‘’,’’,’’),sum(),avg(),min(),max(),count(*), SUBSTR(起始坐标,个数)截取
连接查询:内连接(等值连接),左外连接,右外连接 ,全外连接
子查询 (嵌套查询):将内层查询结果,作为外层查询的条件
主键(标记数据的唯一性),外键(一对一,一对多,多对多)
jdbc:
- 就是jdk提供的一套接口,接口由各大数据库厂商实现
2. 获取连接对象DriverManager.getConnection(url,username,password)
3. 获取statement 执行sql
4. Sql执行完成,如果是查询操作会返回resultSet 结果集
第三方的数据源:
连接池:
容器中放了很多的连接对象connection,使用连接的时候,从连接池中获取一个连接即可,用完之后,要把连接归还到连接池中。
数据源自带的连接池
常用的数据源:c3p0 ,druid,dbcp,springjdbc
操作步骤:
建maven工程,导入mysql,junit依赖
坐标依赖pom.xml
<!-- druid jar--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
- 创建Dbutil工具类:
public class DbUtil {
public static DruidDataSource ds=null;
static {
ds=new DruidDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("950824");
ds.setUrl("jdbc:mysql://localhost/demo?useUnicode=true&serverTimezone=GMT&characterEncoding=utf8&useSSL=true");
}
/**获取连接
* @return
*/
public static Connection getConnection(){
try {
return ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**关闭资源
* @param con
* @param sm
* @param rs
*/
public static void close(Connection con, Statement sm, ResultSet rs){
try {
if (con!=null){
con.close();
}
if (null!=sm){
sm.close();
}
if (null!=rs){
rs.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- 测试类:
@Test public void t1() throws Exception { Connection con= DbUtil.getConnection(); Statement statement= con.createStatement(); int i=statement.executeUpdate("update userinfo set uname='老张' where uid=4"); System.out.println("影响了"+i+"行"); DbUtil.close(con,statement,null); }
获取自增的主键:
/**
* 添加数据,获取自增的主键
*/
@Test
public void t2() throws SQLException {
Connection con=DbUtil.getConnection();
Statement sm=con.createStatement();
int i= sm.executeUpdate("insert userinfo(uname,address,age) values('赵六','上海',19)",Statement.RETURN_GENERATED_KEYS);
System.out.println("影响了"+i+"行");
ResultSet rs = sm.getGeneratedKeys();
if (rs.next()){
System.out.println("自增的主键=="+rs.getInt(1));
}
DbUtil.close(con,sm,null);
}
抽取公共的更新的方法:
- 在Dbuitl中加入方法:
/**执行数据的更新
* @param sql
* @param args 就是一个数组
* @return
*/
public static int update(String sql,Object...args){
Connection con= DbUtil.getConnection();
PreparedStatement statement= null;
int row=0;
try {
//设置sql语句
statement = con.prepareStatement(sql);
if (null!=args&&args.length>0){
for (int i=0;i<args.length;i++){
//给sql中?设置参数值,参数的索引从1开始
statement.setObject(i+1,args[i]);
}
}
//执行更新
row=statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源
close(con,statement,null);
}
return row;
}
- 测试: ```java @Test public void t3(){ String sql=”update userinfo set uname=? where uid=?”; int row= DbUtil.update(sql,”老四”,8); System.out.println(“影响了”+row+”行”); }
/**
- 根据id删除数据 */ @Test public void t4(){ String sql=”delete from userinfo where uid =?”; int i = DbUtil.update(sql, 8); System.out.println(“影响了”+i+”行”); } ```
dbutils框架的使用:
- 导入pom坐标依赖:
<!--dbutils--> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.5</version> </dependency>
单元测试:
public class DbUtilTest { QueryRunner qr=new QueryRunner(DbUtil.ds); /** * 添加 */ @Test public void t1() throws SQLException { String sql="insert userinfo(uname,address,age)values(?,?,?)"; int i=qr.update(sql,"赵四","深圳",20); System.out.println("影响了"+i+"行"); } /** * 删除 */ @Test public void t2() throws SQLException { String sql="delete from userinfo where uid=?"; int i= qr.update(sql,9); System.out.println("影响了"+i+"行"); } /** * 修改 */ @Test public void t3() throws SQLException { String sql="update userinfo set uname=? where uid=?"; int i = qr.update(sql, "赵四", 7); System.out.println(i); } /** * 查询 */ @Test public void t4() throws SQLException { String sql="select *from userinfo "; List<UserBean> list = qr.query(sql, new BeanListHandler<UserBean>(UserBean.class)); System.out.println(list); } }
MyBatis:
Mybatis 使用开源的orm框架MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录 Mybatis一种半自动化的orm框架,小巧,简单易于上手和精通。运行速度快 Hibernate 全自动话的orm框架,几乎不需要开发者做什么时候,一切都是自动化的,包括建表和主外键关系。上手容易,精通非常难,学习成本较高,可定制化很弱。运行效率慢。目前很少有企业在使用。 封装了jdbc
使用步骤:
Idea连接mysql


- 如果下载不了mysql的驱动,可以使用本地的mysql驱动

Pom.xml依赖
- 加入pom坐标依赖,拷贝log4j.properties 文件到resource文件夹下
<!--mybatis的依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.2</version> </dependency> <!--log4j日志--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependencies> <!--mysql的驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> </dependency> <!-- druid jar--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.0</version> </dependency> <!-- 单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
创建UserBean:
public class UserBean {
private int uid;
private String uname;
private String address;
private int age;
}
//alt+insert 生成get/set tostring
创建UserDao接口:
public interface UserDao {
/**添加
* @param u
* @return
*/
int add(UserBean u);
/**根据主键id删除
* @param id
* @return
*/
int del(int id);
/**修改
* @param u
* @return
*/
int update(UserBean u);
/**查询
* @return
*/
List<UserBean> findAll();
}
创建mybatis_conf.xml:
- 位于resources文件夹下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<-- <property name="url" value="jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8"/> -->
<property name="url" value="jdbc:mysql://localhost/demo?useUnicode=true&serverTimezone=GMT&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--管理所有的mapper映射文件-->
<mappers>
<mapper resource="mapper/***Mapper.xml"/>
</mappers>
</configuration>
创建*Mapper.xml:
- 位于resources文件夹下的mapper文件夹下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ujiuye.dao.UserDao">
<!---->
<!--注意:id="接口的方法名" parameterType =“方法的入参类型” resulType=“方法的返回值类型”
如果是基本数据类型或者string,或者map都可以省略不写-->
<!-- namespace=”dao接口全限定名” -->
<!-- <select id=”接口的方法名”
ParameterType=”入参” resultType=”出参类型”></select>-->
<insert id="add" parameterType="com.ujiuye.bean.UserBean">
insert into userinfo (uname, address, age) values (#{uname},#{address},#{age});
</insert>
<delete id="del">
delete from userinfo where uid=#{0}
</delete>
<update id="update" parameterType="com.ujiuye.bean.UserBean">
update userinfo set uname=#{uname},address=#{address},age=#{age} where uid=#{uid}
</update>
<select id="findAll" resultType="com.ujiuye.bean.UserBean">
select * from userinfo
</select>
</mapper>
测试:
public class MybatisTest {
@Test
public void t1() throws IOException {
//1.读取核心配置文件
InputStream is= Resources.getResourceAsStream("mybatis_conf.xml");
//2.获取sqlSessionFactory
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
//3.获取sqlsession
SqlSession session=ssf.openSession();
//获取接口实例
UserDao dao = session.getMapper(UserDao.class);
UserBean u=new UserBean();
u.setUname("aaaa");
u.setAge(19);
u.setAddress("西安");
int i= dao.add(u);
System.out.println("影响了"+i+"行");
//提交数据 mybatis是收订提交模式
session.commit();
session.close();
}
/**
* 删除
*/
@Test
public void t2() throws IOException {
//1.读取核心配置文件
InputStream is= Resources.getResourceAsStream("mybatis_conf.xml");
//2.获取sqlSessionFactory
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
//3.获取sqlsession
SqlSession session=ssf.openSession();
//获取接口实例
UserDao dao = session.getMapper(UserDao.class);
dao.del(10);
session.commit();
session.close();
}
/**更新
* @throws IOException
*/
@Test
public void t3() throws IOException {
//1.读取核心配置文件
InputStream is= Resources.getResourceAsStream("mybatis_conf.xml");
//2.获取sqlSessionFactory
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
//3.获取sqlsession
SqlSession session=ssf.openSession();
//获取接口实例
UserDao dao = session.getMapper(UserDao.class);
UserBean u=new UserBean();
u.setAddress("新加坡");
u.setAge(80);
u.setUname("sssss");
u.setUid(7);
dao.update(u);
session.commit();
session.close();
}
/**
* 查询
*/
@Test
public void t4() throws IOException {
//1.读取核心配置文件
InputStream is= Resources.getResourceAsStream("mybatis_conf.xml");
//2.获取sqlSessionFactory
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
//3.获取sqlsession
SqlSession session=ssf.openSession();
//获取接口实例
UserDao dao = session.getMapper(UserDao.class);
List<UserBean> list = dao.findAll();
System.out.println(list);
session.close();
}
}
抽取公共方法:
- @before @after的基类
public class BaseTest { public SqlSession session=null; @Before public void before(){ System.out.println("before===="); try { InputStream is= Resources.getResourceAsStream("mybatis_conf.xml"); SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is); session=ssf.openSession(); } catch (IOException e) { e.printStackTrace(); } } @After public void after(){ System.out.println("after======"); session.commit(); session.close(); } }
- 测试类,继承基类
public class MybatisTest extends BaseTest{ @Test public void t1() throws IOException { //获取接口实例 UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean(); u.setUname("bbb"); u.setAge(20); u.setAddress("西安"); int i= dao.add(u); System.out.println("影响了"+i+"行"); //提交数据 mybatis是收订提交模式 /* session.commit(); session.close();*/ } /** * 删除 */ @Test public void t2() throws IOException { //获取接口实例 UserDao dao = session.getMapper(UserDao.class); dao.del(10); } /**更新 * @throws IOException */ @Test public void t3() throws IOException { //获取接口实例 UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean(); u.setAddress("新加坡"); u.setAge(80); u.setUname("sssss"); u.setUid(7); dao.update(u); } /** * 查询 */ @Test public void t4() throws IOException { //获取接口实例 UserDao dao = session.getMapper(UserDao.class); List<UserBean> list = dao.findAll(); System.out.println(list); } }
全类名别名:
- 在mybatis_conf.xml中给全类名起别名

<!--给全类名起别名--> <typeAliases> <typeAlias type="com.ujiuye.bean.UserBean" alias="user"/> </typeAliases> 在***Mapper类中直接使用别名即可

参数传递:
方法的参数是Bean类对象名,取值#{属性名}


Map传参
- UserDao中加入方法
List<UserBean> findByCondition(Map map);
- *Mapper中取值#{Map的key}
<select id="findByCondition" resultType="user"> select * from userinfo where uname=#{name} and age=#{age} </select>
测试:
@Test public void t1(){ UserDao dao = session.getMapper(UserDao.class); Map map=new HashMap(); map.put("name","bbb"); map.put("age",20); List<UserBean> list = dao.findByCondition(map); System.out.println(list); }//注意:在sql中接收#{key} 一定和传的map的key名称相等
直接使用参数的索引值,取值#{arg索引}
- 在userDao添加方法
List<UserBean> findByCondition2(String name,Integer age);
- 在*Mapper.xml中添加方法
<select id="findByCondition2" resultType="user"> select * from userinfo where age=#{arg1} and uname=#{arg0} </select>
测试: ```java @Test public void t2(){ UserDao dao = session.getMapper(UserDao.class);
List
list = dao.findByCondition2(“老张”, 18); System.out.println(list);
}
<a name="214521bb"></a>
##### 给参数起别名@Param(“别名”) 取值#{别名}
1.
在UserDao中添加方法
```java
List<UserBean> findByCondition3(@Param("uname") String name, @Param("b") Integer age);
- 在UserMapper.xml实现方法
<select id="findByCondition3" resultType="user"> select * from userinfo where uname=#{uname} and age=#{b} </select>
测试
@Test **public void** t3(){ UserDao dao = **session**.getMapper(UserDao.**class**); List<UserBean> list = dao.findByCondition3(**"老张"**, 18); System.***out\***.println(list); }
Day04:
内容回顾:
Jdbc:
数据源:druid,c3p0,dbcp
第三方框架:dbutils
Mybatis:
使用步骤:
1. 映射的实体类Bean
2. Dao接口 定义增删改查的方法
3. ***Mapper文件 namespace=”dao接口全限定名” <select id=”接口的方法名”
ParameterType=”入参” resultType=”出参类型”></select>
4. Mybatis_conf.xml 配置数据源 ,管理mapper文件
5. 测试方法:
1> 读取核心配置文件
2> SqlsessionFactory工厂
3> 获取sqlsession
4> 获取接口的实例
5> 调用接口的方法
6. 获取方法中参数
1> 入参是对象 取值#{对象的属性名}
2> 入参是Map 取值#{key}
3> 别名@Param(“别名”) 取值#{别名}
4> 对参数传递 取值#{arg索引}
数据间关系:
一对一:
Pom依赖:
- log4j.properties 复制到resources下面
- 创建一对一 实体类的映射
public class CardBean {
private Integer cid;
private String cnum;
private Integer fk_pid;
//alt+insert 自己生成get/set/toString
}
public class PersonBean {
private Integer pid;
private String pname;
private CardBean card; //一对一
}
- 创建接口
public interface PersonDao { List<PersonBean> findAll(); }
- 创建*Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ujiuye.dao.PersonDao">
<select id="findAll" resultMap="personMap">
select * from person
</select>
<!--property对应的是属性名,column对应的是表中属性名-->
<resultMap id="personMap" type="com.ujiuye.bean.PersonBean">
<id property="pid" column="pid"/>
<result property="pname" column="pname"/>
<association property="card" select="findCardByPid" column="pid"/>
</resultMap>
<!--根据人的pid查询人的身份证-->
<select id="findCardByPid" resultType="com.ujiuye.bean.CardBean">
select * from cardinfo where fk_pid=#{0}
</select>
</mapper>

- Mybatis_conf.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <-- <property name="url" value="jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8"/> --> <property name="url" value="jdbc:mysql://localhost/demo?useUnicode=true&serverTimezone=GMT&characterEncoding=utf8&useSSL=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/PersonMapper.xml"/> </mappers> </configuration>
测试:
@before @after的基类
public class BaseTest { public SqlSession session=null; @Before public void before(){ try { InputStream is= Resources.getResourceAsStream("mybatis_conf.xml"); SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is); session=ssf.openSession(); } catch (IOException e) { e.printStackTrace(); } } @After public void after(){ session.commit(); session.close(); } }
- 测试
public class MyTest extends BaseTest{
/**
* 一对一
*/
@Test
public void t1(){
PersonDao dao = session.getMapper(PersonDao.class);
List<PersonBean> list = dao.findAll();
System.out.println(list);
}
}
一对多:
- 创建一对一多实体类的映射
public class OrderBean { private Integer oid; private Double price; private Integer fk_cid; } public class CustomerBean { private Integer cid; private String cname; private List<OrderBean> orders;//一对多 }
创建接口
public interface CustomerDao { List<CustomerBean> findAll(); }
创建*Mapper.xml ```xml <?xml version=”1.0” encoding=”UTF-8” ?> <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
Mybatis_conf.xml
<br />
-
测试
```java
/**
* 一对多
*/
@Test
public void t2(){
CustomerDao dao = session.getMapper(CustomerDao.class);
List<CustomerBean> list = dao.findAll();
System.out.println(list);
}
多对多:
多对多,就是多个一对一
创建实体类的关系映射
public class TeacherBean { private Integer tid; private String tname; private List<Teac_Course> ts;//一个老师对应中间表中多条数据 } public class Teac_Course { private CourseBean course;//中间表中一条数据对应着一个老师和一门课程 } public class CourseBean { private Integer cid; private String cname; }
- 接口TeacherDao:
public interface TeacherDao { List<TeacherBean> findAll(); }
TeacherMapper.xml ```xml <?xml version=”1.0” encoding=”UTF-8” ?> <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
mybatis_conf.xml添加mapper管理
<br />
-
测试:
```java
/**
* 多对多
*/
@Test
public void t3(){
TeacherDao dao = session.getMapper(TeacherDao.class);
List<TeacherBean> list = dao.findAll();
System.out.println(list);
}
MyBatis分页插件:

有时候数据量太大,用户浏览不了太多数据,而且浏览器承受不了太大的数据量,需要分页显示。在mybatis中提供了专门用于分页的插件
分页插件pom坐标依赖:
<!-- 分页依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
mybatis_conf.xml引入分页插件:
<plugins>
<!--引入分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

在PersonDao加入新的方法
List<PersonBean> findByPage();
在PersonMapper.xml实现接口方法
<select id="findByPage" resultType="com.ujiuye.bean.PersonBean">
select * from person
</select>
测试分页
@Test
public void t4(){
PersonDao dao = session.getMapper(PersonDao.class);
//分页
PageHelper.startPage(3,5);
List<PersonBean> list = dao.findByPage();
PageInfo<PersonBean> info=new PageInfo<>(list);
System.out.println(info);
}
结果:

mybatis的动态sql:
if ,where 标签
Where 作用,自动帮助加上where关键字,并且自动去除紧跟着where后面多余的and||or关键字
- 创建UserBean
public class UserBean { private Integer uid; private String uname; private String address; private Integer age; }
- 创建UserDao
public interface UserDao { /**按照入参的属性值查找,如果属性没有值就不按此条件查找 * @param u * @return */ List<UserBean> findByCondition(UserBean u); }
- UserMapper.xml
xml<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ujiuye.dao.UserDao"> <select id="findByCondition" parameterType="com.ujiuye.bean.UserBean" resultType="com.ujiuye.bean.UserBean"> select * from userinfo <where> <if test="uname!=null"> and uname=#{uname} </if> <if test="address!=null"> and address=#{address} </if> <if test="age!=null"> and age=#{age} </if> </where> </select> </mapper>
- mybatis_conf.xml 管理UserMapper.xml

- 测试 注意观察sql语句
@Test public void t1(){ UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean(); u.setAge(20); u.setAddress("西安"); List<UserBean> list = dao.findByCondition(u); System.out.println(list); }
set标签
Set标签能够自动帮助加上set关键字,去除多余的逗号
案例:对象的哪个属性有值,就修改哪个属性,没有值就不修改
- UserDao中添加方法
int update(UserBean u);
- UserMapper.xml实现方法
<update id="update" parameterType="com.ujiuye.bean.UserBean"> update userinfo <set> <if test="uname!=null"> uname=#{uname}, </if> <if test="address!=null"> address=#{address}, </if> <if test="age!=null"> age=#{age}, </if> </set> <where> uid=#{uid} </where> </update>
- 测试
@Test public void t2(){ UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean(); u.setAddress("西安"); u.setAge(80); u.setUid(11); dao.update(u); }
Foreach 批量操作:
Foreach标签中的元素
Collection: 如果方法中传来的是集合,用list/collection 也可给参数起别名
如果是数组,接收用array
Separator: 分隔符
Item: 每一次遍历到的对象
Open:以什么开始
Close:以什么结束
批量添加
- UserDao中添加方法:
int addBathch(List<UserBean> users);
- UserMapper.xml中实现方法
<insert id="addBathch" parameterType="com.ujiuye.bean.UserBean"> insert into userinfo (uname, address, age) values <!-- ('n1','',80), ('n1','',80), ('n1','',80);--> <foreach collection="list" separator="," item="user"> (#{user.uname},#{user.address},#{user.age}) </foreach> </insert>
- 测试:
/* 批量添加 */ @Test public void t3(){ UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean("aaa","北京1",20); UserBean u2=new UserBean("bbbb","北京2",30); UserBean u3=new UserBean("cccc","北京3",40); List<UserBean> list=new ArrayList<>(); list.add(u); list.add(u2); list.add(u3); dao.addBathch(list); }
批量删除:
- 在UserDao中添加批量删除的方法 ```java
- int delBatch(Integer[] ids); ```
- 在UserMapper.xml中实现方法
<delete id="delBatch"> delete from userinfo where uid in <!--(1,2,3)--> <foreach collection="array" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete>
- 测试
/** * 批量删除 */ @Test public void t4(){ UserDao dao = session.getMapper(UserDao.class); Integer ids[]={18,19,20}; dao.delBatch(ids); }
插入数据时,获取自动增长的主键
- 在userdao添加方法
int add(UserBean u);
- 在UserMapper.xml实现方法
<insert id="add" parameterType="com.ujiuye.bean.UserBean"> <selectKey keyColumn="uid" keyProperty="uid" resultType="int" order="AFTER"> select last_insert_id() </selectKey> insert into userinfo (uname, address, age) values (#{uname},#{address},#{age}); </insert>

- 测试
@Test public void t5(){ UserDao dao = session.getMapper(UserDao.class); UserBean u=new UserBean("yyy","南京",70); dao.add(u); System.out.println(u); }
模糊搜索
- 在userDao添加搜索方法
List<UserBean> searchByName(String name);
- 在UserMapper.xml中实现方法
<select id="searchByName" resultType="com.ujiuye.bean.UserBean"> select * from userinfo where uname like concat('%',concat(#{0},'%')) </select>
- 测试
@Test public void t6(){ UserDao dao = session.getMapper(UserDao.class); List<UserBean> list = dao.searchByName("老"); System.out.println(list); }
