Mybatis第一天
第一天:
-
mybatis的介绍
-
Mybatis的入门
-
使用jdbc操作数据库存在的问题
-
Mybatis的架构
-
Mybatis的入门程序
-
-
Dao的开发方法
-
原始dao的开发方法
-
动态代理方式
-
-
SqlMapConfig.xml文件说明
-
介绍
-
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

mybatis-3.2.7.jar----mybatis的核心包
lib----mybatis的依赖包
mybatis-3.2.7.pdf----mybatis使用手册
使用jdbc编程问题总结:
JDBC程序:( jdbc的原始方法(未经封装)实现了查询数据库表记录的操作。)
|
publicstaticvoid main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null;
try { //加载数据库驱动 Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root"); //定义sql语句 ?表示占位符 String sql = "select * from user where username = ?"; //获取预处理statement preparedStatement = connection.prepareStatement(sql); //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值 preparedStatement.setString(1, "王五"); //向数据库发出sql执行查询,查询出结果集 resultSet = preparedStatement.executeQuery(); //遍历查询结果集 while(resultSet.next()){ System.out.println(resultSet.getString("id")+""+resultSet.getString("username")); } } catch (Exception e) { e.printStackTrace(); }finally{ //释放资源 if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(preparedStatement!=null){ try { preparedStatement.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(connection!=null){ try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
}
} |
jdbc问题总结如下:
-
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
-
Sql语句在代码中硬编码(sql语句被写死了),造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
-
使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
-
对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便
Mybatis架构

-
mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
-
通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
-
由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
-
mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
-
Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
-
Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
-
Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
-
Mybatis入门程序:
-
需求:
实现以下功能:
根据用户id查询一个用户信息
根据用户名称模糊查询用户信息列表
添加用户
更新用户
删除用户
先新建数据库mybatis再导入sql数据
|
DROP TABLE IF EXISTS `orders`; CREATE TABLE `orders` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '下单用户id', `number` varchar(32) NOT NULL COMMENT '订单号', `createtime` datetime NOT NULL COMMENT '创建订单时间', `note` varchar(100) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`), KEY `FK_orders_1` (`user_id`), CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null); INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null); INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` date DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性别', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', '王五', null, '2', null); INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市'); INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州'); INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州'); INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州'); INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州'); INSERT INTO `user` VALUES ('26', '王五', null, null, null); |
再建立项目,搭建相应项目结构,导入jar包:
User.java:
|
package cn.itheima.pojo;
import java.util.Date;
public class User { private int id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址
…get,set方法…
@Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } } |
SqlMapConfig.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> <properties resource="db.properties"></properties>
<typeAliases> <!-- 定义单个pojo类别名 type:类的全路劲名称 alias:别名 --> <!-- <typeAlias type="cn.itheima.pojo.User" alias="user"/> -->
<!-- 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 --> <package name="cn.itheima.pojo"/> </typeAliases>
<!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
<mappers> <mapper resource="User.xml"/>
<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <!-- <mapper class="cn.itheima.mapper.UserMapper"/> -->
<!-- 使用包扫描的方式批量引入Mapper接口 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <package name="cn.itheima.mapper"/> </mappers> </configuration> |
log4j.properties:
|
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n |
db.properties:
|
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8 jdbc.username=root jdbc.password=root |
User.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:命名空间,做sql隔离 --> <mapper namespace="test"> <!-- id:sql语句唯一标识 parameterType:指定传入参数类型 resultType:返回结果集类型 #{}占位符:起到占位作用,如果传入的是基本类型(string,long,double,int,boolean,float等),那么#{}中的变量名称可以随意写. --> <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itheima.pojo.User"> SELECT * FROM USER WHERE id = #{id} </select>
<!-- 如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所以映射文件中应该配置成集合泛型的类型 ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value 注意:拼接符有sql注入的风险,所以慎重使用.一般等于号后写占位符,like后写拼接符. --> <select id="findUserByUserName" parameterType="java.lang.String" resultType="cn.itheima.pojo.User"> SELECT * FROM USER WHERE username LIKE '%${value}%' </select>
<!-- #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性..... 如果要返回数据库自增主键:可以使用select LAST_INSERT_ID() --> <insert id="insertUser" parameterType="cn.itheima.pojo.User"> <!-- 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键 keyProperty:将返回的主键放入传入参数的Id中保存. order:当前函数相对于insert语句的执行顺序,在insert前执行是before,在insert后执行是AFTER 因为这里User的id是自增的(数据库管理的),所以在只有插入之后,id才有值,没插入之前是默认值0. resultType:id的类型,也就是keyproperties中属性的类型 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID() </selectKey> insert into user (username,birthday,sex,address) values(#{username}, #{birthday}, #{sex}, #{address}) </insert>
<delete id="delUserById" parameterType="java.lang.Integer"> DELETE FROM USER WHERE id=#{id} </delete>
<update id="updateUserById" parameterType="cn.itheima.pojo.User"> UPDATE USER SET username=#{username} WHERE id = #{id} </update>
</mapper> |
UserTest.java:
|
package cn.itheima.test;
import java.io.InputStream; import java.util.Date; import java.util.List;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;
import cn.itheima.pojo.User;
public class UserTest {
@Test public void testFindUserById() throws Exception{ String resource = "SqlMapConfig.xml"; //通过流将核心配置文件读取进来 InputStream inputStream = Resources.getResourceAsStream(resource); //通过核心配置文件输入流来创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //通过工厂创建会话 SqlSession openSession = factory.openSession(); //第一个参数:所调用的sql语句= namespace+.+sql的ID User user = openSession.selectOne("test.findUserById", 1); System.out.println(user); openSession.close(); }
@Test public void testFindUserByUserName() throws Exception{ String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession(); List<User> list = session.selectList("test.findUserByUserName", "王"); System.out.println(list); }
@Test public void testInsertUser() throws Exception{ String config = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(config); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession();
User user = new User(); user.setUsername("王子"); user.setBirthday(new Date()); user.setSex("男"); user.setAddress("广州");
System.out.println("=============="+user.getId()); session.insert("test.insertUser", user); //提交事务(mybatis会自动开启事务,但是它不知道何时提交,所以需要手动提交事务) session.commit(); System.out.println("=============="+user.getId());
}
@Test public void testDelUserById() throws Exception{ String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession();
session.delete("test.delUserById", 22); session.commit(); }
@Test public void testUpdateUserById() throws Exception{ String config = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(config); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession();
User user = new User(); user.setUsername("张大千"); user.setId(25); session.update("test.updateUserById", user); session.commit();
} } |
- Tips:步骤是先在SQLyog中写出正确的sql语句,再把sql语句复制到User.xml中,写好User.xml后再去写UserTest.java.
如果Mysql使用 uuid实现主键
需要增加通过select uuid()得到uuid值
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey resultType="java.lang.String" order="BEFORE"
keyProperty="id">
select uuid()
</selectKey>
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
注意这里使用的order是"BEFORE".因为select uuid()就是数据库中的操作语句,用来给id赋予随机的字符串.在插入数据之前就得先给id赋值,不然会报错.
三.Mybatis原生Dao实现:
先新建Dao和test:
UserDao:
|
package cn.itheima.dao;
import java.util.List;
import cn.itheima.pojo.User;
public interface UserDao {
public User findById(Integer id);
public List<User> findByUserName(String userName);
} |
UserDaoImpl:
|
package cn.itheima.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory;
import cn.itheima.pojo.User;
public class UserDaoImpl implements UserDao{
private SqlSessionFactory sqlSessionFactory; //通过构造方法注入 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; }
@Override public User findById(Integer id) { //sessionFactory是线程不安全的,所以他应该在方法体内注入 SqlSession session = sqlSessionFactory.openSession(); User user = session.selectOne("test.findUserById", id); return user; }
@Override public List<User> findByUserName(String userName) { SqlSession session = sqlSessionFactory.openSession(); List<User> list = session.selectList("test.findUserByUserName", userName); return list; } } |
UserDaoTest:
|
package cn.itheima.test;
import java.io.InputStream; import java.util.List;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test;
import cn.itheima.dao.UserDao; import cn.itheima.dao.UserDaoImpl; import cn.itheima.pojo.User;
public class UserDaoTest {
private SqlSessionFactory factory;
@Before public void setUp() throws Exception{ String config = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(config); factory = new SqlSessionFactoryBuilder().build(inputStream); }
@Test public void findById() throws Exception{ //将初始化好的工厂注入到实现类中 UserDao userDao = new UserDaoImpl(factory);
System.out.println(userDao.findById(25)); }
@Test public void findByUserName() throws Exception{ UserDao userDao = new UserDaoImpl(factory); System.out.println(userDao.findByUserName("子")); } } |
-
Mybatis动态代理Dao实现:
开发规范
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
-
Mapper.xml文件中的namespace与mapper接口的类路径相同。
-
Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
-
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
-
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
先新建mapper包,包下新建UserMapper.java和UserMapper.xml,再来个测试类:
UserMapper.xml:(和之前的User.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接口代理实现编写规则: 1. 映射文件中namespace要等于接口的全路径名称 2. 映射文件中sql语句id要等于接口的方法名称 3. 映射文件中传入参数类型要等于接口方法的传入参数类型 4. 映射文件中返回结果集类型要等于接口方法的返回值类型 --> <mapper namespace="cn.itheima.mapper.UserMapper">
<!-- id:sql语句唯一标识 parameterType:指定传入参数类型 resultType:返回结果集类型 #{}占位符:起到占位作用,如果传入的是基本类型(string,long,double,int,boolean,float等),那么#{}中的变量名称可以随意写. --> <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itheima.pojo.User"> select * from user where id=#{id} </select>
<!-- 如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所以映射文件中应该配置成集合泛型的类型 ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value 注意:拼接符有sql注入的风险,所以慎重使用 --> <select id="findUserByUserName" parameterType="java.lang.String" resultType="user"> select * from user where username like '%${value}%' </select>
<!-- #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性..... 如果要返回数据库自增主键:可以使用select LAST_INSERT_ID() --> <insert id="insertUser" parameterType="cn.itheima.pojo.User" > <!-- 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键 keyProperty:将返回的主键放入传入参数的Id中保存. order:当前函数相对于insert语句的执行顺序,在insert前执行是before,在insert后执行是AFTER resultType:id的类型,也就是keyproperties中属性的类型 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert> </mapper> |
UserMapper.java:
|
package cn.itheima.mapper;
import java.util.List;
import cn.itheima.pojo.User;
public interface UserMapper {
public User findUserById(Integer id);
public List<User> findUserByUserName(String userName);
public void insertUser(User user); } |
接着要在SqlMapConfig.xml中引入UserMapper.xml:
|
<mappers> <mapper resource="User.xml"/>
<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <!--<mapper class="cn.itheima.mapper.UserMapper"/>--> </mappers> |
UserMapperTest.java:
|
package cn.itheima.test; import java.io.InputStream; import java.util.Date; import java.util.List;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test;
import cn.itheima.mapper.UserMapper; import cn.itheima.pojo.User;
public class UserMapperTest { private SqlSessionFactory factory;
//作用:在测试方法前执行这个方法 @Before public void setUp() throws Exception{ String resource = "SqlMapConfig.xml"; //通过流将核心配置文件读取进来 InputStream inputStream = Resources.getResourceAsStream(resource); //通过核心配置文件输入流来创建会话工厂 factory = new SqlSessionFactoryBuilder().build(inputStream); }
@Test public void testFindUserById() throws Exception{ SqlSession openSession = factory.openSession(); //通过getMapper方法来实例化接口 UserMapper mapper = openSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1); System.out.println(user); }
@Test public void testFindUserByUserName() throws Exception{ SqlSession openSession = factory.openSession(); //通过getMapper方法来实例化接口 UserMapper mapper = openSession.getMapper(UserMapper.class);
List<User> list = mapper.findUserByUserName("王");
System.out.println(list); }
@Test public void testInsertUser() throws Exception{ SqlSession openSession = factory.openSession(); //通过getMapper方法来实例化接口 UserMapper mapper = openSession.getMapper(UserMapper.class);
User user = new User(); user.setUsername("老王"); user.setSex("1"); user.setBirthday(new Date()); user.setAddress("北京昌平");
mapper.insertUser(user);
openSession.commit(); } } |
小结:
-
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
-
namespace
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。
五. SqlMapConfig.xml配置文件
配置内容
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
-
1.properties(属性)
SqlMapConfig.xml可以引用java属性文件中的配置信息如下:
|
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8 jdbc.username=root jdbc.password=root |
SqlMapConfig.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> <properties resource="db.properties"></properties>
<typeAliases> <!-- 定义单个pojo类别名 type:类的全路劲名称 alias:别名 --> <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->
<!-- 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 --> <package name="cn.itheima.pojo"/> </typeAliases>
<!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
<mappers> <mapper resource="User.xml"/>
<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->
<!-- 使用包扫描的方式批量引入Mapper接口 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <package name="cn.itheima.mapper"/> </mappers> </configuration> |
注意: MyBatis 将按照下面的顺序来加载属性:
然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
-
2.typeAliases(类型别名)
mybatis支持别名:
|
别名 |
映射的类型 |
|
_byte |
byte |
|
_long |
long |
|
_short |
short |
|
_int |
int |
|
_integer |
int |
|
_double |
double |
|
_float |
float |
|
_boolean |
boolean |
|
string |
String |
|
byte |
Byte |
|
long |
Long |
|
short |
Short |
|
int |
Integer |
|
integer |
Integer |
|
double |
Double |
|
float |
Float |
|
boolean |
Boolean |
|
date |
Date |
|
decimal |
BigDecimal |
|
bigdecimal |
BigDecimal |
|
map |
Map |
自定义别名:
在SqlMapConfig.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> <properties resource="db.properties"></properties>
<typeAliases> <!-- 定义单个pojo类别名 type:类的全路劲名称 alias:别名 --> <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->
<!-- 使用包扫描的方式批量定义别名 以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 --> <package name="cn.itheima.pojo"/> </typeAliases>
<!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
<mappers> <mapper resource="User.xml"/>
<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->
<!-- 使用包扫描的方式批量引入Mapper接口 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <package name="cn.itheima.mapper"/> </mappers> </configuration> |
这样批量定义后,在UserMapper.xml中可直接写类名了,如:
<select id="findUserByUserName" parameterType="java.lang.String" resultType="user">
select * from user where username like '%${value}%'
</select>
-
3.mappers(映射器,将UserMapper.xml或UserMapper.java载入SqlMapConfig.xml中)
Mapper配置的几种方法:
<mapper resource="" />
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
<mapper class="" />
使用mapper接口类路径
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<package name=""/>
注册指定包下的所有mapper接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
SqlMapConfig.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> <properties resource="db.properties"></properties>
<typeAliases> <!-- 定义单个pojo类别名 type:类的全路劲名称 alias:别名 --> <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->
<!-- 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 --> <package name="cn.itheima.pojo"/> </typeAliases>
<!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
<mappers> <mapper resource="User.xml"/>
<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->
<!-- 使用包扫描的方式批量引入Mapper接口 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 --> <package name="cn.itheima.mapper"/> </mappers> </configuration> |
-
总结:
pojo: 不按mvc分层,只是java bean有一些属性,还有get set方法
domain: 不按mvc分层,只是java bean有一些属性,还有get set方法
po: 用在持久层,还可以再增加或者修改的时候,从页面直接传入action中,它里面的java bean 类名等于表名,
属性名等于表的字段名,还有对应的get set方法
vo: view object表现层对象,主要用于在高级查询中从页面接收传过来的各种参数.好处是扩展性强
bo: 用在servie层,现在企业基本不用.
这些po,vo, bo,pojo可以用在各种层面吗?
可以,也就是po用在表现层,vo用在持久层不报错,因为都是普通的java bean没有语法错误.
但是在企业最好不要混着用,因为这些都是设计的原则,混着用比较乱.不利于代码维护.
自学方法论: 理论 -> 实践 -> 理论 -> 实践 反复迭代三遍
1. mybatis是一个持久层框架, 作用是跟数据库交互完成增删改查
2.原生Dao实现(需要接口和实现类)
4.动态代理方式(只需要接口)
mapper接口代理实现编写规则:
1) 映射文件中namespace要等于接口的全路径名称
2) 映射文件中sql语句id要等于接口的方法名称
3) 映射文件中传入参数类型要等于接口方法的传入参数类型
4) 映射文件中返回结果集类型要等于接口方法的返回值类型
5. #{}占位符:占位
如果传入的是基本类型,那么#{}中的变量名称可以随意写
如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性.属性...
6. ${}拼接符:字符串原样拼接
如果传入的是基本类型,那么${}中的变量名必须是value
如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性.属性...
注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格
7. 映射文件:
1)传入参数类型通过parameterType属性指定
2)返回结果集类型通过resultType属性指定
8. hibernate和mybatis区别:
hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.
缺点:sql语句无法优化
应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
总的来说是在用户量不大,并发量小的时候使用.
mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
有点:学习成本低, sql语句可以优化, 执行效率高,速度快
缺点:编码量较大,会拖慢开发周期
应用场景: 互联网项目,比如电商,P2p等
总的来说是在用户量较大,并发高的时候使用.

浙公网安备 33010602011771号