.1.什么框架?
框架软件的半成品,我们在框架基础上快速开发我们公司定制化的软件应用
好处:
1.开发速度块
2.降低难度 框架提供了很多现成的模块和功能 拿来就用
3.提供软件同一的规范 很多公司都在用
4.提高软件质量 把关键的代码 业务实现 我们只是站在巨人肩膀上
框架解决高并发高性能的问题,可以让初学者都能开出高性能的应用
ORM框架?
对象映射框架
读取:将数据库表中的每一行数据 映射为java对象
写入: 将java对象映射为数据库 每一行数据
mybatis 就是一个orm框架,要取代最基本的jdbc queryRuner
2.mybatis
优秀的持久层和orm框架
特点:
简单易用
灵活
sql 与java代码解耦
提供高级映射功能: 1.数据表列名和Java属性不一致问题 2.一对一,一对多
动态sql语句 解决模糊查询等类似问题
Hibernate 框架
也是持久层框架,已经渐渐被淘汰
特点:
功能强大,重量级,不需要写SQL语句(开发者不能自定义sql语句,不能优化,不灵活)
3.mybatis入门示例
1.创建maven-Java工程,引入依赖
<!-- 所有的jar 依赖都要放在dependencies-->
<dependencies>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- log4j 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 测试jar-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
2.创建实体类
/**
* 学生实体类
*/
public class Student implements Serializable {
private int id;
private String name;
private String sex;
private int age;
private float height;
public Student() {
}
public Student(int id, String name, String sex, int age, float height) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.height = height;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
3.创建dao 接口
import com.qfedu.entity.Student;
/**
* student dao接口
*
* 需要 mybatis 创建一个 实现类
* 在IStudentDao.xml 告诉mybatis 如何创建一个实现类
*/
public interface IStudentDao {
/**
* 根据id 查找 学生
* @param id
* @return
*/
Student findStudentById(int id);
}
4.在resources 文件***下创建com/qfedu/文件夹***
创建IStudentDao.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">
<!--
namespace="com.qfedu.dao.IStudentDao" 和mybatis 二级相关
mybatis 根据当前 xml文件生成 IStudentDao 对应的实现类
-->
<mapper namespace="com.qfedu.dao.IStudentDao" >
<!--
select 查询标签
id 对应 dao 中的方法名
#{id} 就是获取方法传来的参数
resultType="com.qfedu.entity.Student" 将查询结果 转换为 Student 对象
parameterType="int" 参数类型
-->
<select id="findStudentById" resultType="com.qfedu.entity.Student" parameterType="int">
select * from student_tb where id = #{id}
</select>
</mapper>
5.在resources下创建mybatis配置文件sqlMapperConfig.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">
<!-- mybatis 相关的配置-->
<configuration>
<!-- 选区mysql 环境-->
<environments default="mysql">
<!-- mybtis 环境 -->
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接池数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 配置url-->
<property name="url" value="jdbc:mysql://localhost:3306/qf2006"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- mappers 一定要在 environments -->
<mappers>
<!-- 在配置文件声明 IStudentDao 只有声明了,mybatis 才会根据 IStudentDao 去出创建实现类-->
<mapper resource="com/qfedu/dao/IStudentDao.xml"></mapper>
</mappers>
</configuration>
6.测试
public class MyBatisTest1 {
public static void main(String[] args) {
try {
//1获取连接
InputStream inputStream = Resources.getResourceAsStream("sqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取连接工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 获取 sqlSession mysql连接
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession 获取IStudentDao 的实现类
IStudentDao iStudentDao = sqlSession.getMapper(IStudentDao.class);
Student student = iStudentDao.findStudentById(2);
System.out.println("student:"+student);
} catch (IOException e) {
e.printStackTrace();
}
}
}
7.配置日志
在resource配置log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=mybatis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
注意
4.mybatis 增删改查
IstudentDao
/**
* 查找所有学生
* @return
*/
List<Student> findAllStudent();
/**
* 增加学生
* @param student
* @return
*/
int addStudent(Student student);
/**
* 更新学生
* @param student
* @return
*/
int updateStudent(Student student);
/**
* 更具 id 删除
* @param id
* @return
*/
int deleteStudentById(int id);
IstudentDao.xml
<select id="findAllStudent" resultType="com.qfedu.entity.Student">
select * from student_tb
</select>
<!--
parameterType="com.qfedu.entity.Student" 可以不传
-->
<insert id="addStudent" >
insert into student_tb (name,age,sex,height) values (#{name},#{age},#{sex},#{height})
</insert>
<!-- 更新学生-->
<update id="updateStudent" >
update student_tb set name = #{name},age=#{age},sex=#{sex},height=#{height} where id = #{id}
</update>
<!--
删除
-->
<delete id="deleteStudentById">
delete from student_tb where id = #{id}
</delete>
测试
//查询所有学生
// List<Student> studentList = iStudentDao.findAllStudent();
// 第二种方式查询所有学生
// List<Student> studentList = sqlSession.selectList("com.qfedu.dao.IStudentDao.findAllStudent");
//
// for (Student student:studentList){
// System.out.println("student:"+student);
// }
/* // 添加学生
Student student = new Student();
student.setName("吕臣2");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
int num = iStudentDao.addStudent(student);
System.out.println("num:"+num);*/
// 更新学生
/* Student student = new Student();
student.setId(101);
student.setName("吕臣3");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
iStudentDao.updateStudent(student);
*/
// 删除
iStudentDao.deleteStudentById(101);
// 提交事务
sqlSession.commit();
resultType 标签只存在与select查询中,增删改不需要 映射javabean
5.获取自增id
xml
<!-- 第一种插入学生 获取id
<selectKey 获取自增id
resultType="int" 自增id 类型
keyColumn="id" 对应数据库表中自增主键列名
keyProperty="id" 传入的实体类中 主键的属性
order="AFTER" 插入完成之后执行 select last_insert_id()
-->
<!-- <insert id="addStudentGetId" parameterType="com.qfedu.entity.Student">
insert into student_tb (name,age,sex,height) values (#{name},#{age},#{sex},#{height})
<selectKey resultType="int" keyColumn="id" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
</insert>-->
<!--第二种获取自增id
useGeneratedKeys="true" 获取自增id
将数据库表自增id keyColumn="id" 设置到 student对象的属性id keyProperty="id"
-->
<insert id="addStudentGetId" parameterType="com.qfedu.entity.Student" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into student_tb (name,age,sex,height) values (#{name},#{age},#{sex},#{height})
</insert>
dao
/**
* 添加学生后 获取自增id
*
* 返回值是 修改数据库的影响行数
* @param student
* @return
*/
int addStudentGetId(Student student);
测试
// 通过sqlSession 获取IStudentDao 的实现类
IStudentDao iStudentDao = sqlSession.getMapper(IStudentDao.class);
// 添加学生
Student student = new Student();
student.setName("大拿");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
// 影响的行数
int num = iStudentDao.addStudentGetId(student);
System.out.println("num:"+num);
// 提交事务
sqlSession.commit();
// 获取自增id
System.out.println("获取自增id:"+student.getId());
6.模糊查询
<!--模糊查询
#{name} 占位符 只是替换值 禁止sql 拼接
-->
<!-- <select id="getStudentByLikeName" resultType="com.qfedu.entity.Student">
select * from student_tb where name like #{name}
</select>
-->
<!--
'${value}' mybatis 字符串的替换拼接
${value} 获取到如何 sql 字符串都会拼接接进来 最大的风险是 sql 注入
'${value}' select name from student_tb where id = 1
-->
<select id="getStudentByLikeName" resultType="com.qfedu.entity.Student">
select * from student_tb where name like '${value}'
</select>
/**
* 根据名称模糊查询
* @param name
* @return
*/
List<Student> getStudentByLikeName(String name);
测试
// 模糊查询
// 含有大的 名字对应学生都查询出来
List<Student> studentList = iStudentDao.getStudentByLikeName("%大%");
for (Student student:studentList){
System.out.println("student:"+student);
}
${} #{} 区别????
1.获取值不同 ${value} #{参数名}
2.${} 字符串替换 ,sql拼接 #{} 占位符
3.${} 有sql 注入风险
7别名的配置
别名就是mybatis 给 Java实体类起一个小名(简短的名字,而不需要全限定名)
在sqlMapperConfig.xml 配置文件添加
<!-- 配置类型别名
必须写在environments 标签之上
-->
<typeAliases>
<!-- 为com.qfedu.entity.Student 取别名为 student-->
<!-- <typeAlias type="com.qfedu.entity.Student" alias="student"></typeAlias>-->
<!-- 为当前包下面所有实体类 取别名
Student 别名 Student student 不区分大小写
-->
<package name="com.qfedu.entity"/>
</typeAliases>
使用 Student别名
<select id="getStudentByLikeName" resultType="Student">
select * from student_tb where name like '${value}'
</select>
8.resultMap
解决列名和实体类属性不匹配方法
- select id,name ,age,sex,height,s_address as address from student_tb where id = #{id}
- 使用 resultmap
<!--
解决列名和实体类属性不匹配方法
1. select id,name ,age,sex,height,s_address as address from student_tb where id = #{id}
2. 使用 resultmap
1.声明resultMap标签 在内部完成映射
2.使用resultMap="studentMap1" 应用声明的resultMap的id
-->
<!-- 定义一个 resultMap
使用resultMap 完成 数据库列名到 实体类的映射
<id property="id" column="id"></id> 数据表 主键列名 与 实体类属性映射
<result property="name" column="name"></result> 普通列明和 实体类属性映射
-->
<resultMap id="studentMap1" type="com.qfedu.entity.Student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="address" column="s_address"></result>
</resultMap>
<select id="findStudentById" resultMap="studentMap1" parameterType="int">
select id,name ,age,sex,height,s_address from student_tb where id = #{id}
</select>