三层架构包含的三层:
界面层(表示层,视图层)(User Interface layer): 主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和 用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。业务逻辑层(Business Logic Layer):接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。数据访问层(Data access layer):与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交 给业务层,同时将业务层处理的数据保存到数据库.三层的处理请求的交互: 用户—> 界面层—>业务逻辑层—>数据访问层—>DB 数据库
在pom.xml加入 :
maven坐标junit的依赖mybatis依赖mysql驱动依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjpowernode</groupId> <artifactId>ch01-first-mybatis</artifactId> <version>1.0-SNAPSHOT</version> <name>ch01-first-mybatis</name> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!--junit依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <build> <!--资源文件--> <resources> <resource> <directory>src/main/java</directory><!--所在的目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> <!--指定maven编译程序时使用的jdk版本--> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>ProvinceDao接口:
public interface ProvinceDao { //定义对数据库的操作方法 //查询数据库的所有数据 List<Province> selectProvinces(); //添加数据 //返回值是表示对数据库影响的行数 public int insertProvince(Province province); //更新 //返回值是表示对数据库影响的行数 public int updateProvince(Province province); //删除 //返回值是表示对数据库影响的行数 public int deleteProvinceById(Integer id); }注意:
mapper文件是xml格式的,也叫做映射文件在mapper文件中写sql语句,MyBatis会执行这些sql语句mapper文件可以有多个,一般是一个表一个mapper文件mapper文件名称和dao接口名一样,区分大小写mapper文件和dao接口在同一目录ProvinceDao.xml:
mapper文件中的约束文件:mybatis-3-mapper.dtd,扩展名为 .dtd 约束文件作用:
定义在当前文件中可以使用的标签和属性定义标签,属性的出现顺序,次数等 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">mapper是根元素 属性:namespace :表示命名空间,目的是给当前文件中的各个sql起一个唯一标识值。 namespace的值是自定义的, 可以a,b,c。推荐使用dao接口的全限定名称
<mapper namespace="com.bjpowernode.dao.ProvinceDao">mapper内部写sql语句,不同的sql语句使用不同的标签
查询select ---- <select>更新update ----<update>插入insert ----<insert>删除delete ----<delete>查询: select标签是表示执行select操作。 语法:<select> select 语句</select> 属性:
id:sql语句的唯一标识,可以自定义,推荐使用接口中的方法名称。当执行sql语句时,mybatis使用 namespace + id的值唯一标识一条sql语句
resultType:表示sql语句执行后,转为java对象的类型。 推荐使用类型的全限定名称(包名加类名) mybatis的操作是执行sql语句,使用PreparedStatement. 把查询的结果转为resultType指定的类,创建这个类的java对象,并把列的值赋值给同名的属性。
<select id="selectProvinces" resultType="com.bjpowernode.domain.Province"> select * from province; </select>添加: mybatis使用占位符,获取传入到xml文件中的数据 #{java对象的属性名} : 表示获取这个属性的值,放到sql语句中。等同于PreparedStatment对象的 ?
<insert id="insertProvince"> insert into student values(#{id},#{name},#{email},#{age}) </insert> <!--更新 update --> <update id="updateProvince"> update student set age=#{age} where id=#{id} </update>删除: 当你的dao中,方法的参数是一个简单类型的数据时,在mapper文件中,使用这个参数值语法是 #{任意变量名} 简单类型:java的基本数据类型和String
<delete id="deleteProvinceById"> delete from student where id=#{studentId} </delete> </mapper>对于上面的步骤,main方法中的步骤大部分是固定的,可以将他们封装成一个工具类,减少代码量
将测试方法中的固定写法封装到一个工具类中 public class MyBatisUtil { //定义一个全局的 SqlSessionFactory对象 private static SqlSessionFactory factory; static { String config="mybatis.xml"; InputStream in = null; try { in = Resources.getResourceAsStream(config); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); factory = builder.build(in); } catch (IOException e) { e.printStackTrace(); } } //定义方法获取SqlSession对象 public static SqlSession getSqlSession(){ SqlSession sqlSession = null; if( factory != null){ sqlSession = factory.openSession(); } return sqlSession; } } 用工具类对数据库进行增删改查 public class MyTest { //测试update @Test public void testUpdateProvince() throws IOException { //1.通过工具类获取sqlSession SqlSession sqlSession = MyBatisUtil.getSqlSession(); //2.执行sql语句, 使用sql语句的唯一标识 // namesapce + 每个sql语句自己的id String id="updateProvince"; String sqlid="com.bjpowernode.dao.ProvinceDao." + id; Province province= new Province(); province.setId(1003); province.setAge(26); int rows = sqlSession.update(sqlid,province); System.out.println("updateStudent 返回的rows:"+rows); //3.提交事务, mybatis默认的操作是不自动提交事务。需要手工执行 sqlSession.commit(); //4.关闭资源 sqlSession.close(); }使用动态代理MyBatis开发步骤与之前的开发步骤基本一致,唯一的不同是在最后一步的测试中,调用SqlSession的实例方法getMapper()创建动态代理类对象: 接口类型的对象 = sqlSession.getMapper(接口的.class); 然后再调用接口对象的方法,就相当于执行了mapper文件中的 id对应的sql语句
public class MyTest { @Test public void testSelectStudents(){ //使用mybatis的动态代理技术 SqlSession sqlSession = MyBatisUtil.getSqlSession(); //根据接口获取他的对象 ProvinceDao dao = sqlSession.getMapper(ProvinceDao.class); //调用dao的方法 List<Province> provinces = dao.selectProvinces(); provinces.forEach( stu-> System.out.println(stu)); } } 通过dao,动态代理对象,执行方法的内部原理: dao执行方法时,方法名称就是mapper中的 iddao的数据类型,可以根据getMapper(接口的.class)能够获取到接口的全限定名称 com.bjpowernode.dao.StudentDao这个接口的全限定名称和mapper文件中的namespace是一样的。mybatis根据 接口的类型 + 方法名称就可以组成 要执行的是sql语句的id