标签:http 写法 connect 回滚 javascrip java语言 路径 ado build
JDBC是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,也是我们用来访问数据库的核心代码。而Mybatis作为一款优秀的持久层框架,其本质也是对JDBC封装。
下面展示一段非常常见的JDBC代码:
// 加载数据库驱动
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, "tom");
// 向数据库发出sql执?查询,查询出结果集
resultSet = preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
// 封装User
user.setId(id);
user.setUsername(username);
}
可以很清晰的看到JDBC代码的使用步骤非常清晰:
于此同时我们也可以看到原始JDBC开发过程中存在的一些问题:
看完这些问题我们再来看下mybatis这个持久层框架是怎么解决这些问题的。
MyBatis是?款优秀的基于ORM的半?动轻量级持久层框架,它?持定制化SQL、存储过程以及?级映
射。 MyBatis避免了?乎所有的JDBC代码和?动设置参数以及获取结果集。 MyBatis可以使?简单的
XML或注解来配置和映射原?类型、接?和Java的POJO (Plain Old Java Objects,普通?式Java对 象)
为数据库中的记录。
注:ORM全称Object/Relation Mapping:表示对象-关系映射的缩写。简单的来说就是将实体类与表对应起来。
Mybatis是?个半?动化的持久层框架,对开发?员开说,核?sql还是需要??进?优化, sql和java编码进?分离,功能边界清晰,?个专注业务,?个专注数据。
首先我们看下Mybatis的开发步骤:
<!--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>
<scope>runtime</scope>
</dependency>
public class User {
private int id;
private String username;
private String password;
//省略get个set?法
}
<?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="userMapper">
<select id="findAll" resultType="com.lagou.domain.User">
select * from User
</select>
</mapper>
<!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:///test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/lagou/mapper/UserMapper.xml"/>
</mappers>
</configuration>
//加载核?配置?件
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession??对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执?sql语句
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();
以上就是mybatis的一个简单入门案例,接下我们来对入门案例的代码进行分析。
首先,我们看下核心配置文件SqlMapConfig.xml中的数据库环境配置。其中环境配置使用的是< environments >标签进行包裹,里面可以包裹多个< environment >标签,每一个< environment >标签代表一个环境变量的配置。< environments >中的default属性指定默认的环境变量名称。< environment >标签中的id用来指定当前环境的名称。< transactionManager >标签代表事务管理器,其中的type类型用来指定事务的管理类型。< dataSource >用来配置数据源,其中的type类型用来指定当前数据源类型。
接下来,我们来看下< environments >中各个标签的可选属性:
事务管理器(transactionManager)类型有两种:
JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从 数据源得到的连接来管理事务作?域。
MANAGED:这个配置?乎没做什么。它从来不提交或回滚?个连接,?是让容器来管理事务的整个?命周期(?如 JEE 应?服务器的上下?)。 默认情况下它会关闭连接。
数据源类型有三种:
UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED:这种数据源的实现利?“池”的概念将 JDBC 连接对象组织起来。
JNDI:这个数据源的实现是为了能在如 EJB 或应?服务器这类容器中使?,容器可以集中或在外部配置数据源,然后放置?个 JNDI 上下?的引?。
再然后,我们来看下mapper标签:标签的作?是加载映射的,加载?式有4种。
< mapper resource="org/mybatis/builder/UserMapper.xml" />
< mapper url="file:///var/mappers/UserMapper.xml"/>
< mapper class="org.mybatis.builder.UserMapper"/>
< package name="org.mybatis.builder"/>
注意:第四种是我们最常用的一种类型。
最后,我们来看下SqlMapConfig.xml中的一些其他常用标签。
< properties resource="jdbc.properties"></ properties>
< typeAliases>
< typeAliase type="com.xh.domain.User" alias="user"> </ typeAliase>
< /typeAliases>
SqlMapConfig.xml这个核心配置文件的分析,我们目前已经基本分析完成了。接下来,我们来分析一下mybatis的映射配置文件。
就如上图所示,映射配置文件主要有5个重要的标签,它们分别是:
最后我们看下测试类的执行相关代码。
可以看到mybatis的调用相对来说还是比较简单的,首先会将核心配置文件SqlMapConfig.xml读取为输入流。接着将输入流传入build方法中进行解析并创建SqlSessionFactory这个工厂类。再接着由SqlSessionFactory这个工厂类生产SqlSession。然后将要执行的方法所在的mapper.xml文件的命名空间加上具体执行方法的id传入并执行得到结果集。最后关闭SqlSession释放资源。
接下来,我们来看下mybatis的Dao层实现。
首先,我们来看下传统开发方式下的Dao层开发。这里我们依旧使用User这个实体类进行编写。
public interface UserDao {
List<User> findAll() throws IOException;
}
public class UserDaoImpl implements UserDao {
public List<User> findAll() throws IOException {
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("userMapper.findAll");
sqlSession.close();
return userList;
}
}
@Test
public void testTraditionDao() throws IOException {
UserDao userDao = new UserDaoImpl();
List<User> all = userDao.findAll();
System.out.println(all);
}
这里传统开发方式下的Dao层开发其实与入门案例基本一致,只是一个简单的封装。这里就不在多解释了。
接下来,我们来看下代理开发?式,这也是一般开发所使用的开发形式。Mapper 接?开发?法只需要程序员编写Mapper 接?(相当于Dao 接?),由Mybatis 框架根据接?
定义创建接?的动态代理对象,代理对象的?法体同上边Dao接?实现类?法。
Mapper 接?开发需要遵循以下规范:
让我们来看一个简单的代码片段作为例子
@Mapper
public interface userMapper{
List<User> findAll() throws IOException;
}
<mapper namespace="userMapper">
<select id="findAll" resultType="com.lagou.domain.User">
select * from User
</select>
</mapper>
这里可以很明显的看到这两段代码所体现的Mapper 接?开发需要遵循的规范。
最后,让我们看下采用代理方式的测试方法该如何写。
@Test
public void testProxyDao() throws IOException {
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获得MyBatis框架?成的UserMapper接?的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}
这里相比传统模式最大的区别就是获得SqlSession之后。传统方法中直接使用SqlSession调用执行。而使用代理方法是由SqlSession生成UserMapper这个接口的代理类,然后直接调用接口方法。
mybatis的配置文件主要有两类,一类是核心配置文件SqlMapConfig.xml这个在入门案例时已经讲解的较为清楚了,这里就不在叙述了。另一类就是映射配置?件mapper.xml,这里我们将简述一些映射配置?件mapper.xml的常用标签和操作。
首先,我们来了解一下动态sql。在实际工作中我们常常会碰到一些业务逻辑复杂的情况,这个时候我们就不能简单地使用sql语句进行直接查询,而需要根据复杂的业务逻辑对我们的 SQL进行动态地变化。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,方便我们将SQL语句进行灵活的组合。
<select id="findByCondition" parameterType="user" resultType="user">
select * from User
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
</where>
</select>
这里where标签的作用是为sql语句拼接上一个 where 并判断第一个条件是否存在and,若是存在就删去and。if标签进行条件判断,若符合则动态拼接上< if>标签内包裹的语句。
<select id="findByIds" parameterType="list" resultType="user">
select * from User
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
这里< foreach>标签的作用是将传来的数组,集合参数进行循环,并将每个循环出来的值拼接到sql中。接下来,我们看下< foreach>标签的各个属性。
?collection:代表要遍历的集合元素,注意编写时不要写#{}
?open:代表语句的开始部分
?close:代表结束部分
?item:代表遍历集合的每个元素,?成的变量名
?sperator:代表分隔符
<!--抽取sql?段简化编写-->
<sql id="selectUser" select * from User</sql>
<select id="findById" parameterType="int" resultType="user">
<include refid="selectUser"></include> where id=#{id}
</select>
这里的< sql>标签可将重复的 sql 提取出来,使?时?< include>标签引?,最终达到 sql 重用的目的。
在日常的业务过程中,我们经常会遇到使用多表查询的情况,我们需要在一次sql查询中查询出多个实体对象的情况,这时候就需要用到mybatis的复杂映射。我们一般遇到的复杂映射主要有三种情况,一种是一对一,一种是一对多,还有一种就是多对多。
首先,我们先来看下一对一的情况。我们来看这么一种业务场景,我们需要查询一条订单的信息,并且同时查询这个订单所属的用户信息。这就是一个典型的多对多的场景,一个订单对应一个用户。我们这里用代码来看下一对一是如何实现的。
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪?个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
这里需要在Order的实体类中增加一个参数User用于接收该订单所对应的用户。
public interface OrderMapper {
List<Order> findAll();
}
<resultMap id="orderMap" type="com.lagou.domain.Order">
<result property="id" column="id"></result>
<result property="ordertime" column="ordertime"></result>
<result property="total" column="total"></result>
<association property="user" javaType="com.lagou.domain.User">
<result column="uid" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>
这里我们使用association标签来对应Order实体类中的User实体类参数。
接下来我们来看下一对多的情况。这里的业务场景可以借鉴之前订单和用户的关系。之前对于订单来说每个订单都对应以个用户。现在我们反过来,对于一个用户来说是可以拥有多个订单的。我们这里用代码来看下一对多是如何实现的。
public class Order {
private int id;
private Date ordertime;
private double total;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前?户具备哪些订单
private List<Order> orderList;
}
这里和之前相反的是在User实体类中定义一个Order实体类的集合用于接收该用户的订单信息。
public interface UserMapper {
List<User> findAll();
}
<resultMap id="userMap" type="com.lagou.domain.User">
<result column="id" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<collection property="orderList" ofType="com.lagou.domain.Order">
<result column="oid" property="id"></result>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
</collection>
</resultMap>
这里我们使用collection 标签来对应User实体类中的Order集合。
最后,我们来看下多对多的情况。对于多对多我们可以想象一个用户和角色的业务场景。一个用户可能有多个角色,一个角色可能有多个用户拥有。其实对于mybatis而言,多对多的写法其实就是一对多写法,是一对多的应用。与多对多的不同主要在于表关系与sql语句。这里我们简单看下代码实现,其实与一对多写法基本无区别。
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前?户具备哪些??
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}
这里和之前相反的是在User实体类中定义一个Role实体类的集合用于接收该用户的角色信息。
public interface UserMapper {
List<User> findAllUserAndRole();
}
<resultMap id="userRoleMap" type="com.lagou.domain.User">
<result column="id" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<collection property="roleList" ofType="com.lagou.domain.Role">
<result column="rid" property="id"></result>
<result column="rolename" property="rolename"></result>
</collection>
</resultM
这里我们可以很清晰的看到多对多的映射写法与一对一基本一致。
标签:http 写法 connect 回滚 javascrip java语言 路径 ado build
原文地址:https://www.cnblogs.com/xjscf/p/14687871.html