-
框架(Framework)是整个或部分系统的可重用设计,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统
-
关于xml文件的问题,这个xml指的是每个dao层的配置文件,按照人家的那个写出来就是运行不了。问题是当我放在resources下时,此时目录结构也和dao层是一样的,但是运行的时候就是读不到xml。为什么,不知道,但是有个解决办法就是把每个dao 的mapper也就是xml放在dao层下,然后在SalDaoConfig.xml下加上:
<mappers> <mapper resource="com/mybatis/dao/IUserDao.xml"/> <mapper resource="com/mybatis/dao/IAccountDao.xml"/> </mappers>
此时就可以
-
基于xml配置文件的mybatis
目录结构:
- 首先呢,要有一个SqlDaoConfig.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> <!-- 配置 mybatis 的环境 --> <environments default="mysql"> <!-- 配置 mysql 的环境 --> <environment id="mysql"> <!-- 配置事务的类型 --> <transactionManager type="JDBC"/>' <!-- 配置连接数据库的信息:用的是数据源(连接池) --> <dataSource type="POOLED"> <property name="url" value="jdbc:mysql://localhost:3306/java"/> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="username" value="zheng"/> <property name="password" value="123456789"/> </dataSource> </environment> </environments> <!-- 告知 mybatis 映射配置的位置 --> <mappers> <mapper resource="com/mybatis/dao/IUserDao.xml"/> <mapper resource="com/mybatis/dao/IAccountDao.xml"/> </mappers> </configuration>
-
然后呢,要写一个domain下的类,里面有,比如,一个name,一个age,生成setter,getter,
-
接下来写dao层,用了咱mybatis就只需写借口就好了,不用谢接口的实现类,在借口里,比如,有个findAll()
-
最后了就,创建一个xml来给findAll用
<?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.mybatis.dao.IUserDao"> 哪个方法,执行什么操作 <select id="findAll" resultType="com.mybatis.domain.User"> select * from user; </select>
- 到此为止,mybatis就完了,测试的话:
/** * * <p>Title: MybatisTest</p> * <p>Description: 测试 mybatis 的环境</p> */ public class MybatisTest { public static void main(String[] args)throws Exception { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //3.使用构建者创建工厂对象 SqlSessionFactory SqlSessionFactory factory = builder.build(in); //4.使用 SqlSessionFactory 生产 SqlSession 对象 SqlSession session = factory.openSession(); //5.使用 SqlSession 创建 dao 接口的代理对象 IUserDao userDao = session.getMapper(IUserDao.class); //6.使用代理对象执行查询所有方法 List<User> users = userDao.findAll(); for(User user : users) { System.out.println(user); } //7.释放资源 session.close(); in.close(); } }
-
保存操作
在持久层接口中添加新增方法 /** * 保存用户 * @param user * @return 影响数据库记录的行数 */ int saveUser(User user); 在用户的映射配置文件中配置 <!-- 保存用户--> <insert id="saveUser" parameterType="com.itheima.domain.User"> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert> 细节: parameterType 属性: 代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。 sql 语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。 具体的数据是由#{}里面的内容决定的。 #{}中内容的写法: 由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。 它用的是 ognl 表达式。 ognl 表达式: 它是 apache 提供的一种表达式语言,全称是: Object Graphic Navigation Language 对象图导航语言 它是按照一定的语法格式来获取数据的。 语法格式就是使用 #{对象.对象}的方式 #{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用 getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username。 添加测试类中的测试方法 @Test public void testSave(){ User user = new User(); user.setUsername("modify User property"); user.setAddress("北京市顺义区"); user.setSex("男"); user.setBirthday(new Date()); System.out.println("保存操作之前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作之后:"+user); } 打开 Mysql 数据库发现并没有添加任何记录,原因是什么? 这一点和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,那么在 mybatis 中如何控制事务 提交呢? 可以使用:session.commit();来实现事务提交。加入事务提交后的代码如下: @After//在测试方法执行完成之后执行 public void destroy() throws Exception{ session.commit(); //7.释放资源 session.close(); in.close(); } 问题扩展:新增用户 id 的返回值 新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相 当于我们要在新增后将自动增长 auto_increment 的值返回。 <insert id="saveUser" parameterType="USER"> <!-- 配置保存时获取插入的 id --> <selectKey keyColumn="id" keyProperty="id" resultType="int"> select last_insert_id(); </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert>
- mybatis对结果封装
-
resultType 配置结果类型
基本类型示例 <select id="findTotal" resultType="int"> select count(*) from user; </select> 实体类类型示例 <select id="findAll" resultType="com.itheima.domain.User"> select * from user </select> 使用别名查询 为什么使用别名查询呢? 比如,在数据库中的名字为name,但是在实体类中的名字为userName,那么如果不用别名的就无法自动封装。 在下面这个例子中,id就是数据库中的,userId就是实体类中的。说实在的,没有必要搞成这样,尽量一致最好。 <select id="findAll" resultType="com.itheima.domain.User"> select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user </select>
-
ResultMap配置结果类型
<!-- 建立 User 实体和数据库表的对应关系 type 属性:指定实体类的全限定类名 id 属性:给定一个唯一标识,是给查询 select 标签引用用的。 --> <resultMap type="com.itheima.domain.User" id="userMap"> <id column="id" property="userId"/> <result column="username" property="userName"/> <result column="sex" property="userSex"/> <result column="address" property="userAddress"/> <result column="birthday" property="userBirthday"/> </resultMap> <!-- id 标签:用于指定主键字段 result 标签:用于指定非主键字段 column 属性:用于指定数据库列名 property 属性:用于指定实体类属性名称 --> 映射配置 <!-- 配置查询所有操作 --> <select id="findAll" resultMap="userMap"> select * from user </select>
-