目标:(医疗管理系统)
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值
@Override
public 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 person p,cardinfo as c where p.pid=c.fk_pid
-- 内连接 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,
name 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
内容回顾:
数据库mysql:
- 建表 create table 表名(字段名 数据类型,…….)
- Insert 表名(字段列表,.,.,) values(字段值,.,……)
- Delete from 表名 where 条件
- Truncate table 表名 直接将表结构删除,重新建表
- Update 表名 字段=字段值,……. where 条件
- Select 字段列表,.,.,…. from 表名 (where 条件)
- 函数:now(),concat(‘’,’’,’’),sum(),avg(),min(),max(),count(*)
- 连接查询:内连接(等值连接),左外连接,右外连接 ,全外连接
- 子查询 (嵌套查询):将内层查询结果,作为外层查询的条件
- 主键(标记数据的唯一性),外键(一对一,一对多,多对多)
Jdbc: 就是jdk提供的一套接口,接口由各大数据库厂商实现
- 加载驱动
- 获取连接对象DriverManager.getConnection(url,username,password)
- 获取statement 执行sql
- Sql执行完成,如果是查询操作会返回resultSet 结果集
第三方的数据源
连接池:容器中放了很多的连接对象connection,使用连接时,从连接池中获得链接即可,要把连接归还到连接池中。 数据源自带的连接池 常用的数据源:c3p0 ,druid,dbcp,springjdbc
Pom坐标依赖:
<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>
</dependencies>
创建DbUtil
```java public class DbUtil {
public static DruidDataSource ds=null;
static {
ds=new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("123456");
ds.setUrl("jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8");
}
/**获取连接
* @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();
}
}
}
2. 测试```java
@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);
}
抽取公共的更新的方法
/**执行数据的更新
* @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;
}
测试
@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);
}
}
MyBaits
MyBaits 3.4.2 和Mybats 3.4.1 arge 1 、 1 Mybatis 使用开源的orm框架 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录 Mybatis一种半自动化的orm框架,小巧,简单易于上手和精通。运行速度快 Hibernate 全自动话的orm框架,几乎不需要开发者做什么时候,一切都是自动化的,包括建表和主外键关系。上手容易,精通非常难,学习成本较高,可定制化很弱。运行效率慢。目前很少有企业在使用。
使用步骤
Idea连接mysql
如果下载不了mysql的驱动,可以使用本地的mysql驱动
1. 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>
2.创建UserBean
public class UserBean {
private int uid;
private String uname;
private String address;
private int age;
//alt+insert 生成get/set tostring
}
3. 创建接口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();
}
4.书写UserMapper.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">
<!--注意:id="接口的方法名" parameterType =“方法的入参类型” resulType=“方法的返回值类型”
如果是基本数据类型或者string,或者map都可以省略不写-->
<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">
<!-- parameterType 入参类型-->
update userinfo set uname=#{uname},address=#{address},age=#{age} where uid=#{uid}
</update>
<select id="findAll" resultType="com.ujiuye.bean.UserBean">
<!--resultType 出参类型-->
select * from userinfo
</select>
</mapper>
5. 书写mybaits的核心配置文件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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--管理所有的mapper映射文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
6.测试
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();
}
}
抽出公共的方法
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中给全类名起别名
xml<!--给全类名起别名-->
<typeAliases>
<typeAlias type="com.ujiuye.bean.UserBean" alias="user"/>
</typeAliases>
在**Mapper.xml中直接使用别名即可
Mybatis的参数传递的问题
方法的参数如果是对象,取值#{属性名}
Map传参
UserDao中加入方法
List<UserBean> findByCondition(Map map);
UserMapper.xml中取值#{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);
在UserMapper.xml中添加方法
<select id="findByCondition2" resultType="user">
select * from userinfo where age=#{arg1} and uname=#{arg0}
</select>
测试
@Test
public void t2(){
UserDao dao = session.getMapper(UserDao.class);
List<UserBean> list = dao.findByCondition2("老张", 18);
System.out.println(list);
}
给参数起别名@Param(“别名”) 取值#{别名}
在UserDao中添加方法
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);
}
对参数传值: 取值#{arg索引}
Day4
内容回顾
Jdbc:
- 数据源:druid,c3p0,dbcp
- 第三方框架:dbutils
Mybatis: 使用步骤:
- 映射的实体类
- Dao接口 定义增删改查的方法
- Mapper文件 namespace=”dao接口全限定名”
- Mybatis_conf.xml 配置数据源 ,管理mapper文件
- 测试方法:
- 读取核心配置文件
- SqlsessionFactory
- 获取sqlsession
- 获取接口的实例
- 调用接口的方法
- 获取方法中参数
- 入参是对象 取值#{对象的属性名}
- 入参是Map 取值#{key}
- 别名@Param(“别名”) 取值#{别名}
- 对参数传递 取值#{arg索引}
一对一
Pom依赖
1. 创建一对一 实体类的映射
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; //一对一
}
2. 创建接口
public interface PersonDao {
List<PersonBean> findAll();
}
3. 创建PersonMapper.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>
<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>
4. 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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/tt?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/PersonMapper.xml"/>
</mappers>
</configuration>
5. BaseTest
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);
}
}
一对多
1. 创建表对应实体映射
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;//一对多
}
2. 创建接口
public interface CustomerDao {
List<CustomerBean> findAll();
}
3. 创建CustomerMapper.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.CustomerDao">
<select id="findAll" resultMap="cusMap">
select * from customer
</select>
<resultMap id="cusMap" type="com.ujiuye.bean.CustomerBean">
<id property="cid" column="cid"/>
<collection property="orders" select="findOrderByCid" column="cid"/>
</resultMap>
<select id="findOrderByCid" resultType="com.ujiuye.bean.OrderBean">
select * from orderinfo where fk_cid=#{0}
</select>
</mapper>
4. 在mybatis_conf.xml加入CustomerMapper.xml的管理
多对多
1. 创建实体类的关系映射
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;
}
2. 接口TeacherDao
public interface TeacherDao {
List<TeacherBean> findAll();
}
3. TeacherMapper.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.TeacherDao">
<select id="findAll" resultMap="teacherMap">
select* from teacher t,teac_course ts,course c
where t.tid=ts.fk_tid and ts.fk_cid=c.cid
</select>
<resultMap id="teacherMap" type="com.ujiuye.bean.TeacherBean">
<id property="tid" column="tid"/>
<result property="tname" column="tname"/>
<collection property="ts" ofType="com.ujiuye.bean.Teac_Course">
<association property="course" javaType="com.ujiuye.bean.CourseBean">
<id column="cid" property="cid"/>
<result column="cname" property="cname"/>
</association>
</collection>
</resultMap>
</mapper>
4. mybatis_conf.xml添加mapper管理
测试
/**
* 多对多
*/
@Test
public void t3(){
TeacherDao dao = session.getMapper(TeacherDao.class);
List<TeacherBean> list = dao.findAll();
System.out.println(list);
}
分页测试
有时候数据量太大,用户浏览不了太多数据,而且浏览器承受不了太大的数据量,需要分页显示。在mybatis中提供了专门用于分页的插件
1. 导入分页插件pom坐标依赖
<!-- 引入mybatis的 pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2. 在mybatis_conf.xml的核心配置文件,加入分页插件
<plugins>
<!--引入分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3. 在PersonDao加入新的方法
List<PersonBean> findByPage();
4. 在PersonMapper.xml实现接口方法
<select id="findByPage" resultType="com.ujiuye.bean.PersonBean">
select * from person
</select>
5. 测试分页
@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
1. if ,where 标签
Where 作用,自动帮助加上where关键字,并且自动去除紧跟着where后面多余的and|or关键字
1. 创建UserBean
public class UserBean {
private Integer uid;
private String uname;
private String address;
private Integer age;
}
2. 创建UserDao
public interface UserDao {
/**按照入参的属性值查找,如果属性没有值就不按此条件查找
* @param u
* @return
*/
List<UserBean> findByCondition(UserBean u);
}
3. UserMapper.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>
<!--where 会自动去除and-->
</mapper>
4. mybatis_conf.xml 管理UserMapper.xml
5. 测试 注意观察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);
}
2. set标签
Set标签能够自动帮助加上set关键字,去除多余的逗号 案例:对象的哪个属性有值,就修改哪个属性,没有值就不修改
1. UserDao中添加方法
int update(UserBean u);
2.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>
3. 测试
@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 批量操作
1. 批量添加
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);
}
2. 批量删除
在UserDao中添加批量删除的方法
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);
}
插入数据时,获取自动增长的主键
1. 在userdao添加方法
int add(UserBean u);
2. 在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);
}
模糊搜索
1. 在userDao添加搜索方法
List<UserBean> searchByName(String name);
2. 在UserMapper.xml中实现方法
<select id="searchByName" resultType="com.ujiuye.bean.UserBean">
select * from userinfo where uname like concat('%',concat(#{0},'%'))
<!--Mysql和Sql Server 任意个参数,Oracle最多只能写两个参数-->
</select>
测试
@Test
public void t6(){
UserDao dao = session.getMapper(UserDao.class);
List<UserBean> list = dao.searchByName("老");
System.out.println(list);
}
Day5
内容回顾:
- Mybatis 一对一(association) 一对多(collection),多对多
- 分页 PageHelper.startPage(pageNum,pageSize)直接查询PageInfo info=new Pageinfo<>(list);
- 动态sql where if, set,foreach
- 获取自动增长的主键
select last_insert_id() 主键取出之后放在对象属性中 - 模糊搜索Concat(‘%’,concat(#{arg},’%’))